diff options
846 files changed, 17574 insertions, 12737 deletions
@@ -320,7 +320,7 @@ E: bogstad@pobox.com D: wrote /proc/self hack, minor samba & dosemu patches N: Axel Boldt -E: boldt@math.ucsb.edu +E: axel@uni-paderborn.de W: http://math-www.uni-paderborn.de/~axel/ D: Configuration help text support D: Linux CD and Support Giveaway List @@ -795,13 +795,16 @@ S: 26506 Norden S: Germany N: Jeremy Fitzhardinge -E: jeremy@zip.com.au +E: jeremy@goop.org +W: http://www.goop.org/~jeremy +D: author of userfs filesystem D: Improved mmap and munmap handling D: General mm minor tidyups -S: 67 Surrey St. -S: Darlinghurst, Sydney -S: New South Wales 2010 -S: Australia +D: autofs v4 maintainer +S: 987 Alabama St +S: San Francisco +S: CA, 94110 +S: USA N: Ralf Flaxa E: rfflaxa@immd4.informatik.uni-erlangen.de @@ -1703,7 +1706,7 @@ D: cfdisk (curses based disk partitioning program) N: Torben Mathiasen E: torben.mathiasen@compaq.com -E: tmm@image.dk +E: torben@kernel.dk W: http://tlan.kernel.dk D: ThunderLAN maintainer D: ThunderLAN updates and other kernel fixes. @@ -2173,9 +2176,9 @@ S: 79098 Freiburg S: Germany N: Joerg Reuter -E: jreuter@poboxes.com -W: http://poboxes.com/jreuter/ -W: http://qsl.net/dl1bke/ +E: jreuter@yaina.de +W: http://yaina.de/jreuter/ +W: http://www.qsl.net/dl1bke/ D: Generic Z8530 driver, AX.25 DAMA slave implementation D: Several AX.25 hacks diff --git a/Documentation/Changes b/Documentation/Changes index c12ed2e6d..abcb21c64 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -28,7 +28,10 @@ russkim perevodom dannogo documenta. Visite <http://www2.adi.uam.es/~ender/tecnico/> para obtener la traducción al español de este documento en varios formatos. -Last updated: August 28, 2000 +Eine deutsche Version dieser Datei finden Sie unter +<http://www.stefan-winter.de/Changes-2.4.0.txt>. + +Last updated: October 25, 2000 Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu). @@ -45,13 +48,13 @@ necessary on all systems; obviously, if you don't have any PCMCIA (PC Card) hardware, for example, you probably needn't concern yourself with pcmcia-cs. -o Gnu C 2.7.2.3 # gcc --version +o Gnu C 2.91.66 # gcc --version o Gnu make 3.77 # make --version o binutils 2.9.1.0.25 # ld -v o util-linux 2.10o # kbdrate -v -o modutils 2.3.15 # insmod -V -o e2fsprogs 1.18 # tune2fs --version -o pcmcia-cs 3.1.19 # cardmgr -V +o modutils 2.3.18 # insmod -V +o e2fsprogs 1.19 # tune2fs --version +o pcmcia-cs 3.1.21 # cardmgr -V o PPP 2.4.0 # pppd --version o isdn4k-utils 3.1beta7 # isdnctrl 2>&1|grep version @@ -61,13 +64,22 @@ Kernel compilation GCC --- -You will need at least gcc 2.7.2 to compile the kernel. You currently -have several options for gcc-derived compilers: gcc 2.7.2.3, various -versions of egcs, the new gcc 2.95 and upcoming gcc 3.0, and experimental -compilers like pgcc. For absolute stability, it is still recommended -that gcc 2.7.2.3 be used to compile your kernel. egcs 1.1.2 should also -work. gcc 2.95 is known to have problems, and using pgcc for your kernel -is just asking for trouble. +The gcc version requirements may vary depending on the type of CPU in your +computer. The next paragraph applies to users of x86 CPUs, but not +necessarily to users of other CPUs. Users of other CPUs should obtain +information about their gcc version requirements from another source. + +The recommended compiler for the kernel is egcs 1.1.2 (gcc 2.91.66), and it +should be used when you need absolute stability. You may use gcc 2.95.2 +instead if you wish, although it may cause problems. Later versions of gcc +have not received much testing for Linux kernel compilation, and there are +almost certainly bugs (mainly, but not exclusively, in the kernel) that +will need to be fixed in order to use these compilers. In any case, using +pgcc instead of egcs or plain gcc is just asking for trouble. + +Note that gcc 2.7.2.3 is no longer a supported kernel compiler. The kernel +no longer works around bugs in gcc 2.7.2.3 and, in fact, will refuse to +be compiled with it. In addition, please pay attention to compiler optimization. Anything greater than -O2 may not be wise. Similarly, if you choose to use gcc-2.95 @@ -82,7 +94,7 @@ You will need Gnu make 3.77 or later to build the kernel. Binutils -------- -Linux on IA/32 has recently switched from using as86 to using gas for +Linux on IA-32 has recently switched from using as86 to using gas for assembling the 16-bit boot code, removing the need for as86 to compile your kernel. This change does, however, mean that you need a recent release of binutils. @@ -242,12 +254,7 @@ Getting updated software Compilers ********* -gcc 2.7.2.3 ------------ -o <ftp://ftp.gnu.org/gnu/gcc/gcc-2.7.2.3.tar.gz> -o <ftp://metalab.unc.edu/pub/gnu/gcc-2.7.2.3.tar.gz> - -egcs 1.1.2 +egcs 1.1.2 (gcc 2.91.66) --------- o <ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-glibc.x86.tar.bz2> o <ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-libc5.x86.tar.bz2> @@ -277,7 +284,7 @@ o <ftp://ftp.kernel.org/pub/linux/utils/kernel/ksymoops/v2.3> Modutils -------- -o <ftp://ftp.kernel.org/pub/linux/utils/kernel/modutils/v2.3/modutils-2.3.15.tar.gz> +o <ftp://ftp.kernel.org/pub/linux/utils/kernel/modutils/v2.3/modutils-2.3.18.tar.bz2> Mkinitrd -------- @@ -285,8 +292,8 @@ o <ftp://rawhide.redhat.com/pub/rawhide/SRPMS/SRPMS/mkinitrd-2.5-1.src.rpm> E2fsprogs --------- -o <http://web.mit.edu/tytso/www/linux/dist/e2fsprogs-1.18.tar.gz> -o <http://web.mit.edu/tytso/www/linux/dist/e2fsprogs-1.18.src.rpm> +o <ftp://download.sourceforge.net/pub/sourceforge/e2fsprogs/e2fsprogs-1.19.tar.gz> +o <ftp://download.sourceforge.net/pub/sourceforge/e2fsprogs/e2fsprogs-1.19.src.rpm> LVM toolset ----------- @@ -294,7 +301,7 @@ o <http://linux.msede.com/lvm/> Pcmcia-cs --------- -o <ftp://pcmcia-cs.sourceforge.org/pub/pcmcia-cs/pcmcia-cs-3.1.19.tar.gz> +o <ftp://pcmcia-cs.sourceforge.net/pub/pcmcia-cs/pcmcia-cs-3.1.21.tar.gz> Jade ---- diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 73091c87b..390cc0ba0 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -1,4 +1,4 @@ -# Maintained by Axel Boldt (boldt@math.ucsb.edu) +# Maintained by Axel Boldt (axel@uni-paderborn.de) # # This version of the Linux kernel configuration help texts # corresponds to the kernel versions 2.3.x. @@ -868,6 +868,10 @@ CONFIG_BLK_DEV_OPTI621 This is a driver for the OPTi 82C621 EIDE controller. Please read the comments at the top of drivers/ide/opti621.c. +ServerWorks OSB4 chipset support (EXPERIMENTAL) +CONFIG_BLK_DEV_OSB4 + This driver adds PIO/DMA support for the Serverworks OSB4 chipset + Intel PIIXn chipsets support CONFIG_BLK_DEV_PIIX This driver adds PIO mode setting and tuning for all PIIX IDE @@ -938,7 +942,20 @@ CONFIG_BLK_DEV_SIS5513 available" as well. Please read the comments at the top of drivers/ide/sis5513.c - + +SLC90E66 chipset support +CONFIG_BLK_DEV_SLC90E66 + This driver ensures (U)DMA support for Victroy66 SouthBridges for + SMsC with Intel NorthBridges. This is an Ultra66 based chipset. + The nice thing about it is that you can mix Ultra/DMA/PIO devices + and it will handle timing cycles. Since this is an improved look-a-like + to the PIIX4 it should be a nice addition. + + If you say Y here, you need to say Y to "Use DMA by default when + available" as well. + + Please read the comments at the top of drivers/ide/slc90e66.c + Winbond SL82c105 support CONFIG_BLK_DEV_SL82C105 If you have a Winbond SL82c105 IDE controller, say Y here to enable @@ -2157,13 +2174,26 @@ CONFIG_ALPHA_LEGACY_START_ADDRESS If you're using aboot 0.7 or later, the bootloader will examine the ELF headers to determine where to transfer control. Unfortunately, - most older bootloaders -- APB, or MILO -- hardcoded the kernel + most older bootloaders -- APB or MILO -- hardcoded the kernel start address rather than examining the ELF headers, and the result is a hard lockup. Say Y if you have a broken bootloader. Say N if you do not, or if you wish to run on Wildfire. +Large VMALLOC support +CONFIG_ALPHA_LARGE_VMALLOC + Process creation and other aspects of virtual memory management + can be streamlined if we restrict the kernel to one PGD for all + vmalloc allocations. This equates to about 8GB. + + Under normal circumstances, this is so far and above what is needed + as to be laughable. However, there are certain applications (such + as benchmark-grade in-kernel web serving) that can make use of as + much vmalloc space as is available. + + Say N unless you know you need gobs and gobs of vmalloc space. + Non-standard serial port support CONFIG_SERIAL_NONSTANDARD Say Y here if you have any non-standard serial boards -- boards @@ -2387,6 +2417,30 @@ CONFIG_PCI information about which PCI hardware does work under Linux and which doesn't. +PCI support +CONFIG_PCI_INTEGRATOR + Find out whether you have a PCI motherboard. PCI is the name of a + bus system, i.e. the way the CPU talks to the other stuff inside + your box. Other bus systems are ISA, EISA, Microchannel (MCA) or + VESA. If you have PCI, say Y, otherwise N. + + The PCI-HOWTO, available from + http://www.linuxdoc.org/docs.html#howto , contains valuable + information about which PCI hardware does work under Linux and which + doesn't. + +QSpan PCI +CONFIG_PCI_QSPAN + Find out whether you have a PCI motherboard. PCI is the name of a + bus system, i.e. the way the CPU talks to the other stuff inside + your box. Other bus systems are ISA, EISA, Microchannel (MCA) or + VESA. If you have PCI, say Y, otherwise N. + + The PCI-HOWTO, available from + http://www.linuxdoc.org/docs.html#howto , contains valuable + information about which PCI hardware does work under Linux and which + doesn't. + PCI access mode CONFIG_PCI_GOBIOS On PCI systems, the BIOS can be used to detect the PCI devices and @@ -4571,6 +4625,30 @@ CONFIG_LLC This is a Logical Link Layer protocol used for X.25 connections over Ethernet, using ordinary Ethernet cards. + +Frame Diverter (EXPERIMENTAL) +CONFIG_NET_DIVERT + The Frame Diverter allows you to divert packets from the + network, that are not aimed at the interface receiving it (in + promisc. mode). Typically, a Linux box setup as an ethernet bridge + with the Frames Diverter on, can do some *really* transparent www + caching using a Squid proxy for example. + + This is very usefull when you don't want to change your router's + config (or if you simply don't have access to it). + + The other possible usages of diverting Ethernet Frames are numberous: + - reroute smtp traffic to another interface + - traffic-shape certain network streams + - transparently proxy smtp connections + - etc... + + For more informations, please refer to: + http://www.freshmeat.net/projects/etherdivert + http://perso.wanadoo.fr/magpie/EtherDivert.html + + If unsure, say N + 802.1d Ethernet Bridging CONFIG_BRIDGE If you say Y here, then your Linux box will be able to act as an @@ -8124,6 +8202,11 @@ CONFIG_NE2K_PCI say Y and read the Ethernet-HOWTO, available from http://www.linuxdoc.org/docs.html#howto . + This driver also works for the following NE2000 clone cards: + RealTek RTL-8029 Winbond 89C940 Compex RL2000 KTI ET32P2 + NetVin NV5000SC Via 86C926 SureCom NE34 Winbond + Holtek HT80232 Holtek HT80229 + 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 ne2k-pci.o. If you want to compile it as a @@ -8187,6 +8270,8 @@ CONFIG_RTL8129 read the Ethernet-HOWTO, available from http://www.linuxdoc.org/docs.html#howto . + Note: the 8029 is a NE2000 PCI clone, you can use the NE2K-PCI 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 Documentation/modules.txt. This is recommended. @@ -9969,12 +10054,13 @@ CONFIG_USB_OHCI The module will be called usb-ohci.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -USB Human Interface Device (HID) support +USB Human Interface Device (full HID) support CONFIG_USB_HID - Say Y here if you want to connect keyboards, mice, joysticks, - graphic tablets, or any other HID based devices to your - computer via USB. More information is available: - Documentation/usb/input.txt. + Say Y here if you want full HID support to connect keyboards, + mice, joysticks, graphic tablets, or any other HID based devices + to your computer via USB. You can't use this driver and the + HIDBP (Boot Protocol) keyboard and mouse drivers at the same time. + More information is available: Documentation/usb/input.txt. If unsure, say Y. @@ -9983,11 +10069,11 @@ CONFIG_USB_HID The module will be called hid.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -USB HIDBP Keyboard support +USB HIDBP Keyboard (basic) support CONFIG_USB_KBD Say Y here if 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. This driver is much smaller than the HID one. + Protocol mode instead. This driver is much smaller than the HID one. This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -9996,11 +10082,11 @@ CONFIG_USB_KBD If unsure, say N. -USB HIDBP Mouse support +USB HIDBP Mouse (basic) support CONFIG_USB_MOUSE Say Y here if you don't want to use the generic HID driver for your USB mouse and prefer to use the mouse in its limited Boot Protocol - mode. This driver is much smaller than the HID one. + mode instead. This driver is much smaller than the HID one. This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -14259,6 +14345,25 @@ CONFIG_SOUND_TRIDENT for Trident 4Dwave. PCI ID 1039:7018 stands for SiS7018. PCI ID 10B9:5451 stands for ALi5451. + This driver supports S/PDIF in/out (record/playback) for ALi 5451 + embedded in ALi M1535+ and M1535D+. Note that they aren't all + enabled by default; you can enable them by saying Y to "/proc file + system support" and "Sysctl support", and after the /proc file + system has been mounted, executing the command + + command what is enabled + + echo 0>/proc/ALi5451 pcm out is also set to S/PDIF out. (Default). + + echo 1>/proc/ALi5451 use S/PDIF out to output pcm data. + + echo 2>/proc/ALi5451 use S/PDIF out to output non-pcm data.(AC3...). + + echo 3>/proc/ALi5451 record from Ac97 in(MIC, Line in...). (Default). + + echo 4>/proc/ALi5451 no matter Ac97 settings, record from S/PDIF in. + + This driver differs slightly from OSS/Free, so PLEASE READ the comments at the top of driver/sound/trident.c @@ -15094,18 +15199,27 @@ CONFIG_RMW_INSNS really know what you are doing, say N. Try Y only if you're quite adventurous. -Amiga AutoConfig Identification +Zorro support CONFIG_ZORRO - This enables support for automatic identification of Amiga expansion - cards that obey the AutoConfig(tm) specification. - Say Y if you want your expansion cards to be identified on bootup; - it will enlarge your kernel by about 10 KB. The identification - information is then also available through /proc/zorro (say Y to - "/proc file system support"!). Read Documentation/zorro.txt for more - information. + This enables support for the Zorro bus in the Amiga. If you have + expansion cards in your Amiga that conform to the Amiga + AutoConfig(tm) specification, say Y, otherwise N. Note that even + expansion cards that do not fit in the Zorro slots but fit in e.g. + the CPU slot may fall in this category, so you have to say Y to let + Linux use these. + +Zorro device name database +CONFIG_ZORRO_NAMES + By default, the kernel contains a database of all known Zorro device + names to make the information in /proc/iomem comprehensible to the + user. This database increases the size of the kernel image by about + 15KB, but it gets freed after the system boots up, so it doesn't + take up kernel memory. Anyway, if you are building an installation + floppy or kernel for an embedded system where kernel image size + really matters, you can disable this feature and you'll get device + ID numbers instead of names. - Note that even if you say N here, you can still use your expansion - cards. If in doubt, say Y. + When in doubt, say Y. Amiga 1200/600 PCMCIA support (EXPERIMENTAL) CONFIG_AMIGA_PCMCIA @@ -16684,6 +16798,119 @@ CONFIG_DISPLAY7SEG another UltraSPARC-IIi-cEngine boardset with a 7-segment display, you should say N to this option. +IA-64 system type +CONFIG_IA64_GENERIC + This selects the system type of your hardware. A "generic" kernel + 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 http://www.linux-ia64.org/. + 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 (http://software.hp.com/ia64linux/). + SN1-simulator For the SGI SN1 simulator. + DIG-compliant For DIG ("Developer's Interface Guide") compliant system. + + If you don't know what to do, choose "generic". + +Kernel page size +CONFIG_IA64_PAGE_SIZE_4KB + + This lets you select the page size of the kernel. For best IA-64 + performance, a page size of 8KB or 16KB is recommended. For best + IA-32 compatibility, a page size of 4KB should be selected (the vast + majority of IA-32 binaries work perfectly fine with a larger page + size). For Itanium systems, do NOT chose a page size larger than + 16KB. + + 4KB For best IA-32 compatibility + 8KB For best IA-64 performance + 16KB For best IA-64 performance + 64KB Not for Itanium. + + If you don't know what to do, choose 8KB. + +Enable Itanium A-step specific code +CONFIG_ITANIUM_ASTEP_SPECIFIC + Select this option to build a kernel for an Itanium prototype system + with an A-step CPU. You have an A-step CPU if the "revision" field in + /proc/cpuinfo is 0. + +Enable Itanium A1-step specific code +CONFIG_ITANIUM_A1_SPECIFIC + Select this option to build a kernel for an Itanium prototype system + with an A1-step CPU. If you don't know whether you have an A1-step CPU, + you probably don't and you can answer "no" here. + +Enable Itanium B-step specific code +CONFIG_ITANIUM_BSTEP_SPECIFIC + Select this option to build a kernel for an Itanium prototype system + with a B-step CPU. You have a B-step CPU if the "revision" field in + /proc/cpuinfo has a value in the range from 1 to 4. + +Enable Itanium B0-step specific code +CONFIG_ITANIUM_B0_SPECIFIC + Select this option to bild a kernel for an Itanium prototype system + with a B0-step CPU. You have a B0-step CPU if the "revision" field in + /proc/cpuinfo is 1. + +Force interrupt redirection +CONFIG_IA64_HAVE_IRQREDIR + Select this option if you know that your system has the ability to + redirect interrupts to different CPUs. Select N here if you're + unsure. + +Enable use of global TLB purge instruction (ptc.g) +CONFIG_ITANIUM_PTCG + Say Y here if you want the kernel to use the IA-64 "ptc.g" + instruction to flush the TLB on all CPUs. Select N here if + you're unsure. + +Enable SoftSDV hacks +CONFIG_IA64_SOFTSDV_HACKS + Say Y here to enable hacks to make the kernel work on the Intel + SoftSDV simulator. Select N here if you're unsure. + +Enable AzusA hacks +CONFIG_IA64_AZUSA_HACKS + Say Y here to enable hacks to make the kernel work on the NEC + AzusA platform. Select N here if you're unsure. + +Force socket buffers below 4GB? +CONFIG_SKB_BELOW_4GB + Most of today's network interface cards (NICs) support DMA to + the low 32 bits of the address space only. On machines with + more then 4GB of memory, this can cause the system to slow + down if there is no I/O TLB hardware. Turning this option on + avoids the slow-down by forcing socket buffers to be allocated + from memory below 4GB. The downside is that your system could + run out of memory below 4GB before all memory has been used up. + If you're unsure how to answer this question, answer Y. + +Enable IA-64 Machine Check Abort +CONFIG_IA64_MCA + Say Y here to enable machine check support for IA-64. If you're + unsure, answer Y. + +Performance monitor support +CONFIG_PERFMON + Selects whether support for the IA-64 performance monitor hardware + is included in the kernel. This makes some kernel data-structures a + little bigger and slows down execution a bit, but it is still + usually a good idea to turn this on. If you're unsure, say N. + +/proc/pal support +CONFIG_IA64_PALINFO + If you say Y here, you are able to get PAL (Processor Abstraction + Layer) information in /proc/pal. This contains useful information + about the processors in your systems, such as cache and TLB sizes + and the PAL firmware version in use. + + To use this option, you have to check that the "/proc file system + support" (CONFIG_PROC_FS) is enabled, too. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, diff --git a/Documentation/DocBook/via-audio.tmpl b/Documentation/DocBook/via-audio.tmpl index f1fc19a5d..039eff979 100644 --- a/Documentation/DocBook/via-audio.tmpl +++ b/Documentation/DocBook/via-audio.tmpl @@ -56,15 +56,16 @@ <chapter id="intro"> <title>Introduction</title> <para> - The Via VT82C686A and VT82C686A "super southbridge" chips contain - AC97-compatible audio logic which features dual full-duplex 16-bit stereo - PCM sound channels, plus a third PCM channel intended for use + The Via VT82C686A "super southbridge" chips contain + AC97-compatible audio logic which features dual 16-bit stereo + PCM sound channels (full duplex), plus a third PCM channel intended for use in hardware-assisted FM synthesis. </para> <para> The current Linux kernel audio driver for this family of chips - supports audio playback, but recording and hardware-assisted - FM support features are not yet available. + supports audio playback and recording, but hardware-assisted + FM features, and hardware buffer direct-access (mmap) + support are not yet available. </para> <para> This driver supports any Linux kernel version after 2.3.50. @@ -148,13 +149,6 @@ <title>Known Bugs And Assumptions</title> <para> <variablelist> - <varlistentry><term>Recording support</term> - <listitem> - <para> - Recording support is currently missing. - </para> - </listitem></varlistentry> - <varlistentry><term>MMAP support</term> <listitem> <para> @@ -188,17 +182,6 @@ </para> </listitem></varlistentry> - <varlistentry><term>Broken apps</term> - <listitem> - <para> - Applications which attempt to open the sound device in read/write - mode (O_RDWR) will fail. This is incorrect OSS behavior, but since - this driver will eventually support recording as well as playback, - we will be able to (in the future) support even broken programs which - unconditionally use O_RDWR. - </para> - </listitem></varlistentry> - </variablelist> </para> @@ -221,8 +204,8 @@ <title>Random Notes</title> <para> Two /proc pseudo-files provide diagnostic information. This is generally - not useful to most users. Power users can disable VIA_PROC_FS macro in the - driver source code, and remove the /proc support code. In any case, once + not useful to most users. Power users can disable CONFIG_SOUND_VIA82CXXX_PROCFS, + and remove the /proc support code. Once version 2.0.0 is released, the /proc support code will be disabled by default. Available /proc pseudo-files: </para> @@ -236,16 +219,6 @@ and device ids are not examined. </para> <para> - Only supports a single sound chip, as this is a motherboard chipset. - Some architecture remains for multiple cards, feel free to submit - a patch to clean some of that up. - </para> - <para> - No consideration for SMP, this chipset is not known to be found on - any SMP motherboards. However, spin_locks must be used anyway in order - to handle interrupts correctly. - </para> - <para> GNU indent formatting options: -kr -i8 -pcs </para> <para> @@ -265,6 +238,159 @@ <chapter id="changelog"> <title>Driver ChangeLog</title> +<sect1 id="version1114"><title> +Version 1.1.14 +</title> + <itemizedlist spacing=compact> + <listitem> + <para> + Use VM_RESERVE when available, to eliminate unnecessary page faults. + </para> + </listitem> + </itemizedlist> +</sect1> + +<sect1 id="version1112"><title> +Version 1.1.12 +</title> + <itemizedlist spacing=compact> + <listitem> + <para> + mmap bug fixes from Linus. + </para> + </listitem> + </itemizedlist> +</sect1> + +<sect1 id="version1111"><title> +Version 1.1.11 +</title> + <itemizedlist spacing=compact> + <listitem> + <para> + Many more bug fixes. mmap enabled by default, but may still be buggy. + </para> + </listitem> + + <listitem> + <para> + Uses new and spiffy method of mmap'ing the DMA buffer, based + on a suggestion from Linus. + </para> + </listitem> + </itemizedlist> +</sect1> + +<sect1 id="version1110"><title> +Version 1.1.10 +</title> + <itemizedlist spacing=compact> + <listitem> + <para> + Many bug fixes. mmap enabled by default, but may still be buggy. + </para> + </listitem> + </itemizedlist> +</sect1> + +<sect1 id="version119"><title> +Version 1.1.9 +</title> + <itemizedlist spacing=compact> + <listitem> + <para> + Redesign and rewrite audio playback implementation. (faster and smaller, hopefully) + </para> + </listitem> + + <listitem> + <para> + Implement recording and full duplex (DSP_CAP_DUPLEX) support. + </para> + </listitem> + + <listitem> + <para> + Make procfs support optional. + </para> + </listitem> + + <listitem> + <para> + Quick interrupt status check, to lessen overhead in interrupt + sharing situations. + </para> + </listitem> + + <listitem> + <para> + Add mmap(2) support. Disabled for now, it is still buggy and experimental. + </para> + </listitem> + + <listitem> + <para> + Surround all syscalls with a semaphore for cheap and easy SMP protection. + </para> + </listitem> + + <listitem> + <para> + Fix bug in channel shutdown (hardware channel reset) code. + </para> + </listitem> + + <listitem> + <para> + Remove unnecessary spinlocks (better performance). + </para> + </listitem> + + <listitem> + <para> + Eliminate "unknown AFMT" message by using a different method + of selecting the best AFMT_xxx sound sample format for use. + </para> + </listitem> + + <listitem> + <para> + Support for realtime hardware pointer position reporting + (DSP_CAP_REALTIME, SNDCTL_DSP_GETxPTR ioctls) + </para> + </listitem> + + <listitem> + <para> + Support for capture/playback triggering + (DSP_CAP_TRIGGER, SNDCTL_DSP_SETTRIGGER ioctls) + </para> + </listitem> + + <listitem> + <para> + SNDCTL_DSP_SETDUPLEX and SNDCTL_DSP_POST ioctls now handled. + </para> + </listitem> + + <listitem> + <para> + Rewrite open(2) and close(2) logic to allow only one user at + a time. All other open(2) attempts will sleep until they succeed. + FIXME: open(O_RDONLY) and open(O_WRONLY) should be allowed to succeed. + </para> + </listitem> + + <listitem> + <para> + Reviewed code to ensure that SMP and multiple audio devices + are fully supported. + </para> + </listitem> + + </itemizedlist> +</sect1> + <sect1 id="version118"><title> Version 1.1.8 </title> diff --git a/Documentation/IO-mapping.txt b/Documentation/IO-mapping.txt index 78253e5b1..ad7c21c83 100644 --- a/Documentation/IO-mapping.txt +++ b/Documentation/IO-mapping.txt @@ -141,7 +141,7 @@ For such memory, you can do things like * read first 32 bits from ISA memory at 0xC0000, aka * C000:0000 in DOS terms */ - unsigned int signature = readl(0xC0000); + unsigned int signature = isa_readl(0xC0000); - remapping and writing: /* diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt index 3d003463d..952dbc652 100644 --- a/Documentation/cachetlb.txt +++ b/Documentation/cachetlb.txt @@ -284,6 +284,12 @@ Here is the new interface: user space shared/writable mappings of this page potentially exist, this routine is called. + NOTE: This routine need only be called for page cache pages + which can potentially ever be mapped into the address + space of a user process. So for example, VFS layer code + handling vfs symlinks in the page cache need not call + this interface at all. + The phrase "kernel writes to a page cache page" means, specifically, that the kernel executes store instructions that dirty data in that page at the page->virtual mapping diff --git a/Documentation/exception.txt b/Documentation/exception.txt index 6adc97ba1..f1d436993 100644 --- a/Documentation/exception.txt +++ b/Documentation/exception.txt @@ -284,3 +284,9 @@ get_user macro actually returns a value: 0, if the user access was successful, -EFAULT on failure. Our original code did not test this return value, however the inline assembly code in get_user tries to return -EFAULT. GCC selected EAX to return this value. + +NOTE: +Due to the way that the exception table is built and needs to be ordered, +only use exceptions for code in the .text section. Any other section +will cause the exception table to not be sorted correctly, and the +exceptions will fail. diff --git a/Documentation/ia64/README b/Documentation/ia64/README index 738572a80..7163ae745 100644 --- a/Documentation/ia64/README +++ b/Documentation/ia64/README @@ -1,6 +1,6 @@ - Linux kernel release 2.3.xx for the IA-64 Platform + Linux kernel release 2.4.xx for the IA-64 Platform - These are the release notes for Linux version 2.3 for IA-64 + These are the release notes for Linux version 2.4 for IA-64 platform. This document provides information specific to IA-64 ONLY, to get additional information about the Linux kernel also read the original Linux README provided with the kernel. @@ -31,46 +31,13 @@ COMPILING the kernel: IA-64 SPECIFICS - - Security related issues: - - o mmap needs to check whether mapping would overlap with the - address-space hole in a region or whether the mapping would be - across regions. In both cases, mmap should fail. - - o ptrace is a huge security hole right now as it does not reject - writing to security sensitive bits (such as the PSR!). - - General issues: - o Kernel modules aren't supported yet. - - o For non-RT signals, siginfo isn't passed through from the kernel - to the point where the signal is actually delivered. Also, we - should make sure the siginfo data is compliant with the UNIX - ABI. - o Hardly any performance tuning has been done. Obvious targets - include the library routines (memcpy, IP checksum, etc.). Less + include the library routines (IP checksum, etc.). Less obvious targets include making sure we don't flush the TLB - needlessly, etc. Also, the TLB handlers should probably try to - do a speculative load from the virtually mapped linear page - table and only if that fails fall back on walking the page table - tree. + needlessly, etc. - o Discontiguous large memory support; memory above 4GB will be - discontiguous since the 4GB-64MB is reserved for firmware and I/O - space. - - o Correct mapping for PAL runtime code; PAL code needs to be - mapped by a TR. - - o Make current IRQ/IOSAPIC handling closer to IA32 such as, - disable/enable interrupts, use of INPROGRESS flag etc. - - o clone system call implementation; needs to setup proper backing - store - o SMP locks cleanup/optimization - o IA32 support. Currently experimental. It mostly works but - there are problems with some dynamically loaded programs. + o IA32 support. Currently experimental. It mostly works. diff --git a/Documentation/isapnp.txt b/Documentation/isapnp.txt index 4cb7a9b59..3de97b275 100644 --- a/Documentation/isapnp.txt +++ b/Documentation/isapnp.txt @@ -1,5 +1,5 @@ ISA Plug & Play support by Jaroslav Kysela <perex@suse.cz> -========================================================= +========================================================== Interface /proc/isapnp ====================== @@ -13,7 +13,7 @@ Write commands: --------------- With the write interface you can simply activate or modify the configuration -for ISA Plug & Play devices. It is mainly useable for drivers which don't +for ISA Plug & Play devices. It is mainly useable for drivers which has not use the ISA Plug & Play kernel support yet. card <idx> <vendor> - select PnP device by vendor identification @@ -33,8 +33,8 @@ poked <reg> <value> - poke configuration dword to selected register Explanation: - variable <idx> begins with zero - variable <CSN> begins with one - - <vendor> is in form 'PNP0000' - - <logdev> is in form 'PNP0000' + - <vendor> is in format 'PNP0000' + - <logdev> is in format 'PNP0000' Example: @@ -54,6 +54,7 @@ port 0 0x240 activate EOF + Information for developers ========================== @@ -92,7 +93,7 @@ callback with appropriate information. Example for ids parameter initialization: -static struct isapnp_card_id ids[] __devinitdata = { +static struct isapnp_card_id card_ids[] __devinitdata = { { ISAPNP_CARD_ID('A','D','V', 0x550a), devs: { @@ -105,6 +106,25 @@ static struct isapnp_card_id ids[] __devinitdata = { ISAPNP_CARD_END, } }; +ISAPNP_CARD_TABLE(card_ids); + +extern int isapnp_probe_devs(const struct isapnp_device_id *ids, + int (*probe)(struct pci_bus *card, + const struct isapnp_device_id *id)); + + +This function is a helper for drivers which requires to use one +device from an ISA PnP card. For each matched devices is called the probe +callback with appropriate information. + +Example for ids parameter initialization: + +static struct isapnp_device_id device_ids[] __devinitdata = { + { ISAPNP_DEVICE_SINGLE('E','S','S', 0x0968, 'E','S','S', 0x0968), }, + { ISAPNP_DEVICE_SINGLE_END, } +}; +MODULE_DEVICE_TABLE(isapnp, device_ids); + ISA PnP configuration ===================== @@ -157,6 +177,8 @@ Example (game port initialization) NULL); if (!dev) return -ENODEV; + if (dev->active) + return -EBUSY; if (dev->prepare(dev)<0) return -EAGAIN; if (!(dev->resource[0].flags & IORESOURCE_IO)) diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index 206272a47..13a663e3e 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -341,11 +341,6 @@ architecture-specific values. # arch/i386/Makefile - # only work around strength reduction bug(s) on older gcc versions - CFLAGS += $(shell if ! $(CC) -march=i486 -S -o /dev/null \ - -xc /dev/null >/dev/null 2>&1; \ - then echo "-fno-strength-reduce"; fi) - # prevent gcc from keeping the stack 16 byte aligned CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 \ -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ @@ -356,21 +351,15 @@ architecture-specific values. # arch/i386/Makefile ifdef CONFIG_M386 - CFLAGS += $(shell if $(CC) -march=i386 -S -o /dev/null \ - -xc /dev/null >/dev/null 2>&1; \ - then echo "-march=i386"; else echo "-m386"; fi) + CFLAGS += -march=i386 endif ifdef CONFIG_M486 - CFLAGS += $(shell if $(CC) -march=i486 -S -o /dev/null \ - -xc /dev/null >/dev/null 2>&1; \ - then echo "-march=i486"; else echo "-m486"; fi) + CFLAGS += -march=i486 endif ifdef CONFIG_M586 - CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null \ - -xc /dev/null >/dev/null 2>&1; \ - then echo "-march=i586"; fi) + CFLAGS += -march=i586 endif Some arch Makefiles redefine the compilation commands in order diff --git a/Documentation/networking/8139too.txt b/Documentation/networking/8139too.txt index 1c5c8afc9..4a045bc48 100644 --- a/Documentation/networking/8139too.txt +++ b/Documentation/networking/8139too.txt @@ -180,6 +180,20 @@ suggestions welcome) (WIP) Change History -------------- +Version 0.9.11 - October 28, 2000 + +* Do not fail when PIO and MMIO region lengths do not match. + (They don't on some CardBus models, at least) +* Sanity check Rx packet status and size (Tobias) +* When handling a Tx timeout, disable Tx ASAP if not already. +* Do not inline Tx interrupt handler (better register usage) +* Handle dirty_tx signed integer wrap +* Do not abort Rx processing on lack of memory, keep going + until the current Rx ring is completely handling. (Tobias) +* Clean up rtl8139_close +* Whitespace correction for dev_kfree_skb_irq call + + Version 0.9.10 - September 12, 2000 * Never wrap an Rx packet (faster Rx interrupt handling) diff --git a/Documentation/networking/z8530drv.txt b/Documentation/networking/z8530drv.txt index c74fb4253..60f453d18 100644 --- a/Documentation/networking/z8530drv.txt +++ b/Documentation/networking/z8530drv.txt @@ -4,17 +4,14 @@ full package from: Internet: ========= -1. ftp://ftp.ccac.rwth-aachen.de/pub/jr/z8530drv-utils-3.0-1.tar.gz +1. ftp://ftp.ccac.rwth-aachen.de/pub/jr/z8530drv-utils_3.0-3.tar.gz -2. ftp://ftp.pspt.fi/pub/ham/linux/ax25/z8530drv-utils-3.0-1.tar.gz - -3. ftp://ftp.ucsd.edu/hamradio/packet/tcpip/incoming/z8530drv-utils-3.0.tar.gz - If you can't find it there, try .../tcpip/linux/z8530drv-utils-3.0.tar.gz +2. ftp://ftp.pspt.fi/pub/ham/linux/ax25/z8530drv-utils_3.0-3.tar.gz Please note that the information in this document may be hopelessly outdated. A new version of the documentation, along with links to other important Linux Kernel AX.25 documentation and programs, is available on -http://www.rat.de/jr +http://yaina.de/jreuter ----------------------------------------------------------------------------- @@ -23,7 +20,7 @@ http://www.rat.de/jr ******************************************************************** - (c) 1993,1998 by Joerg Reuter DL1BKE <jreuter@poboxes.com> + (c) 1993,2000 by Joerg Reuter DL1BKE <jreuter@yaina.de> portions (c) 1993 Guido ten Dolle PE1NNZ @@ -655,6 +652,6 @@ Many thanks to Linus Torvalds and Alan Cox for including the driver in the Linux standard distribution and their support. Joerg Reuter ampr-net: dl1bke@db0pra.ampr.org - AX-25 : DL1BKE @ DB0ACH.#NRW.DEU.EU - Internet: jreuter@poboxes.com - WWW : http://www.rat.de/jr/ + AX-25 : DL1BKE @ DB0ABH.#BAY.DEU.EU + Internet: jreuter@yaina.de + WWW : http://yaina.de/jreuter diff --git a/Documentation/pm.txt b/Documentation/pm.txt index 1e78926cd..205f9666f 100644 --- a/Documentation/pm.txt +++ b/Documentation/pm.txt @@ -261,7 +261,6 @@ Q: Who do I contact for additional information about enabling power management for my specific driver/device? ACPI4Linux mailing list: acpi@phobos.fs.tum.de -Linux ACPI maintainer: andy_henroid@yahoo.com System Interface ---------------- diff --git a/Documentation/s390/cds.txt b/Documentation/s390/cds.txt index 99d514d4c..1de558718 100644 --- a/Documentation/s390/cds.txt +++ b/Documentation/s390/cds.txt @@ -419,7 +419,7 @@ 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 -aquired device. +acquired device. void free_irq( unsigned int irq, void *dev_id); diff --git a/Documentation/usb/bluetooth.txt b/Documentation/usb/bluetooth.txt new file mode 100644 index 000000000..774f5d383 --- /dev/null +++ b/Documentation/usb/bluetooth.txt @@ -0,0 +1,44 @@ +INTRODUCTION + + The USB Bluetooth driver supports any USB Bluetooth device. + It currently works well with the Linux USB Bluetooth stack from Axis + (available at http://developer.axis.com/software/bluetooth/ ) and + has been rumored to work with other Linux USB Bluetooth stacks. + + +CONFIGURATION + + Currently the driver can handle up to 256 different USB Bluetooth + devices at once. + + If you are not using devfs: + The major number that the driver uses is 216 so to use the driver, + create the following nodes: + mknod /dev/ttyUB0 c 216 0 + mknod /dev/ttyUB1 c 216 1 + mknod /dev/ttyUB2 c 216 2 + mknod /dev/ttyUB3 c 216 3 + . + . + . + mknod /dev/ttyUB254 c 216 254 + mknod /dev/ttyUB255 c 216 255 + + If you are using devfs: + The devices supported by this driver will show up as + /dev/usb/ttub/{0,1,...} + + When the device is connected and recognized by the driver, the driver + will print to the system log, which node the device has been bound to. + + +CONTACT: + + If anyone has any problems using this driver, please contact me, or + join the Linux-USB mailing list (information on joining the mailing + list, as well as a link to its searchable archive is at + http://www.linux-usb.org/ ) + + +Greg Kroah-Hartman +greg@kroah.com diff --git a/Documentation/vm/locking b/Documentation/vm/locking index 125cde7cd..f2e8e6c75 100644 --- a/Documentation/vm/locking +++ b/Documentation/vm/locking @@ -4,7 +4,7 @@ The intent of this file is to have an uptodate, running commentary from different people about how locking and synchronization is done in the Linux vm code. -vmlist_access_lock/vmlist_modify_lock +page_table_lock -------------------------------------- Page stealers pick processes out of the process pool and scan for @@ -12,10 +12,10 @@ the best process to steal pages from. To guarantee the existence of the victim mm, a mm_count inc and a mmdrop are done in swap_out(). Page stealers hold kernel_lock to protect against a bunch of races. The vma list of the victim mm is also scanned by the stealer, -and the vmlist_lock is used to preserve list sanity against the +and the page_table_lock is used to preserve list sanity against the process adding/deleting to the list. This also guarantees existence of the vma. Vma existence is not guaranteed once try_to_swap_out() -drops the vmlist lock. To guarantee the existence of the underlying +drops the page_table_lock. To guarantee the existence of the underlying file structure, a get_file is done before the swapout() method is invoked. The page passed into swapout() is guaranteed not to be reused for a different purpose because the page reference count due to being @@ -32,19 +32,19 @@ you must hold mmap_sem to guard against clones doing mmap/munmap/faults, (ie all vm system calls and faults), and from ptrace, swapin due to swap deletion etc. 2. To modify the vmlist (add/delete or change fields in an element), -you must also hold vmlist_modify_lock, to guard against page stealers +you must also hold page_table_lock, to guard against page stealers scanning the list. 3. To scan the vmlist (find_vma()), you must either a. grab mmap_sem, which should be done by all cases except page stealer. or - b. grab vmlist_access_lock, only done by page stealer. -4. While holding the vmlist_modify_lock, you must be able to guarantee + b. grab page_table_lock, only done by page stealer. +4. While holding the page_table_lock, you must be able to guarantee that no code path will lead to page stealing. A better guarantee is to claim non sleepability, which ensures that you are not sleeping for a lock, whose holder might in turn be doing page stealing. -5. You must be able to guarantee that while holding vmlist_modify_lock -or vmlist_access_lock of mm A, you will not try to get either lock +5. You must be able to guarantee that while holding page_table_lock +or page_table_lock of mm A, you will not try to get either lock for mm B. The caveats are: @@ -52,7 +52,7 @@ The caveats are: The update of mmap_cache is racy (page stealer can race with other code that invokes find_vma with mmap_sem held), but that is okay, since it is a hint. This can be fixed, if desired, by having find_vma grab the -vmlist lock. +page_table_lock. Code that add/delete elements from the vmlist chain are @@ -72,23 +72,16 @@ in some cases it is not really needed. Eg, vm_start is modified by expand_stack(), it is hard to come up with a destructive scenario without having the vmlist protection in this case. -The vmlist lock nests with the inode i_shared_lock and the kmem cache +The page_table_lock nests with the inode i_shared_lock and the kmem cache c_spinlock spinlocks. This is okay, since code that holds i_shared_lock never asks for memory, and the kmem code asks for pages after dropping -c_spinlock. The vmlist lock also nests with pagecache_lock and +c_spinlock. The page_table_lock also nests with pagecache_lock and pagemap_lru_lock spinlocks, and no code asks for memory with these locks held. -The vmlist lock is grabbed while holding the kernel_lock spinning monitor. +The page_table_lock is grabbed while holding the kernel_lock spinning monitor. -The vmlist lock can be a sleeping or spin lock. In either case, care -must be taken that it is not held on entry to the driver methods, since -those methods might sleep or ask for memory, causing deadlocks. - -The current implementation of the vmlist lock uses the page_table_lock, -which is also the spinlock that page stealers use to protect changes to -the victim process' ptes. Thus we have a reduction in the total number -of locks. +The page_table_lock is a spin lock. swap_list_lock/swap_device_lock ------------------------------- diff --git a/Documentation/zorro.txt b/Documentation/zorro.txt index ed77a047c..a56e2c485 100644 --- a/Documentation/zorro.txt +++ b/Documentation/zorro.txt @@ -9,7 +9,7 @@ Last revised: February 27, 2000 --------------- The Zorro bus is the bus used in the Amiga family of computers. Thanks to -AutoConfig(tm), it's is 100% Plug-and-Play. +AutoConfig(tm), it's 100% Plug-and-Play. There are two types of Zorro busses, Zorro II and Zorro III: @@ -32,7 +32,6 @@ for the board with Zorro ID `ZORRO_PROD_xxx' looks like: while ((z = zorro_find_device(ZORRO_PROD_xxx, z))) { if (!zorro_request_region(z->resource.start+MY_START, MY_SIZE, "My explanation")) - strcpy(z->name, "My board name"); ... } @@ -94,16 +93,7 @@ The treatment of these regions depends on the type of Zorro space: iounmap(virt_addr); -5. Zorro Device Naming ----------------------- - -Since we think generic device naming is something for userspace (zorroutils), -we don't keep a Zorro device name database in the kernel. -However, device drivers are allowed to store the expansion board name in struct -zorro_dev. - - -6. References +5. References ------------- linux/include/linux/zorro.h @@ -111,6 +101,6 @@ linux/include/linux/ioport.h linux/include/asm-m68k/io.h linux/include/asm-m68k/amigahw.h linux/include/asm-ppc/io.h -linux/driver/zorro +linux/drivers/zorro /proc/bus/zorro diff --git a/MAINTAINERS b/MAINTAINERS index 3be1a37d0..4682b40e2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -87,6 +87,12 @@ M: ajk@iehk.rwth-aachen.de L: linux-hams@vger.kernel.org S: Maintained +8139TOO ETHERNET DRIVER +P: Jeff Garzik +M: jgarzik@mandrakesoft.com +W: http://sourceforge.net/projects/gkernel/ +S: Maintained + 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER P: Theodore Ts'o M: tytso@mit.edu @@ -101,8 +107,8 @@ L: linux-net@vger.kernel.org S: Maintained ACPI -P: Andrew Henroid -M: andy_henroid@yahoo.com +P: Andy Grover +M: andrew.grover@intel.com L: acpi@phobos.fs.tum.de W: http://phobos.fs.tum.de/acpi/index.html S: Maintained @@ -208,7 +214,7 @@ CIRRUS LOGIC GENERIC FBDEV DRIVER P: Jeff Garzik M: jgarzik@mandrakesoft.com L: linux-fbdev@vuser.vu.union.edu -S: Maintained +S: Odd Fixes COMPAQ FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA P: Amy Vanzant-Hodge @@ -255,7 +261,7 @@ S: Maintained CONFIGURE.HELP P: Axel Boldt -M: boldt@math.ucsb.edu +M: axel@uni-paderborn.de S: Maintained COSA/SRP SYNC SERIAL DRIVER @@ -295,9 +301,9 @@ S: Supported DAMA SLAVE for AX.25 P: Joerg Reuter -M: jreuter@poboxes.com -W: http://poboxes.com/jreuter/ -W: http://qsl.net/dl1bke/ +M: jreuter@yaina.de +W: http://yaina.de/jreuter/ +W: http://www.qsl.net/dl1bke/ L: linux-hams@vger.kernel.org S: Maintained @@ -423,8 +429,8 @@ S: Maintained FILE LOCKING (flock() and fcntl()/lockf()) P: Matthew Wilcox -M: willy@thepuffingroup.com -L: linux-kernel@vger.kernel.org +M: matthew@wil.cx +L: linux-fsdevel@vger.kernel.org S: Maintained FPU EMULATOR @@ -609,6 +615,12 @@ P: Ingo Molnar M: mingo@redhat.com S: Maintained +INTEL I8XX RANDOM NUMBER GENERATOR SUPPORT +P: Jeff Garzik +M: jgarzik@mandrakesoft.com +W: http://sourceforge.net/projects/gkernel/ +S: Maintained + INTEL P6 MICROCODE UPDATE SUPPORT P: Tigran Aivazian M: tigran@veritas.com @@ -678,6 +690,12 @@ M: hpa@zytor.com L: autofs@linux.kernel.org S: Maintained +KERNEL AUTOMOUNTER v4 (AUTOFS4) +P: Jeremy Fitzhardinge +M: jeremy@goop.org +L: autofs@linux.kernel.org +S: Maintained + KERNEL NFSD P: Neil Brown M: neilb@cse.unsw.edu.au @@ -1151,7 +1169,7 @@ S: Maintained TLAN NETWORK DRIVER P: Torben Mathiasen M: torben.mathiasen@compaq.com -M: tmm@image.dk +M: torben@kernel.dk L: tlan@vuser.vu.union.edu L: linux-net@vger.kernel.org W: http://tlan.kernel.dk @@ -1180,7 +1198,8 @@ S: Maintained TULIP NETWORK DRIVER P: Jeff Garzik M: jgarzik@mandrakesoft.com -L: linux-tulip@cesdis.gsfc.nasa.gov +L: tulip-users@lists.sourceforge.net +W: http://sourceforge.net/projects/tulip/ S: Maintained TUN/TAP driver @@ -1338,6 +1357,7 @@ VIA 82Cxxx AUDIO DRIVER P: Jeff Garzik M: jgarzik@mandrakesoft.com L: linux-via@gtf.org +W: http://sourceforge.net/projects/gkernel/ S: Maintained USB DIAMOND RIO500 DRIVER @@ -1386,9 +1406,9 @@ S: Maintained for 2.2 only Z8530 DRIVER FOR AX.25 P: Joerg Reuter -M: jreuter@poboxes.com -W: http://poboxes.com/jreuter/ -W: http://qsl.net/dl1bke/ +M: jreuter@yaina.de +W: http://yaina.de/jreuter/ +W: http://www.qsl.net/dl1bke/ L: linux-hams@vger.kernel.org S: Maintained @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -test9 +EXTRAVERSION = -test10 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -87,7 +87,7 @@ export MODLIB CPPFLAGS := -D__KERNEL__ -I$(HPATH) -CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer +CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS) # @@ -158,7 +158,7 @@ DRIVERS-$(CONFIG_PCMCIA) += drivers/pcmcia/pcmcia.o DRIVERS-$(CONFIG_PCMCIA_NETCARD) += drivers/net/pcmcia/pcmcia_net.o DRIVERS-$(CONFIG_PCMCIA_CHRDEV) += drivers/char/pcmcia/pcmcia_char.o DRIVERS-$(CONFIG_DIO) += drivers/dio/dio.a -DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus.a +DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/zorro.a DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a DRIVERS-$(CONFIG_ALL_PPC) += drivers/macintosh/macintosh.o @@ -182,9 +182,6 @@ DRIVERS += $(DRIVERS-y) include arch/$(ARCH)/Makefile -# use '-fno-strict-aliasing', but only if the compiler can take it -CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi) - export CPPFLAGS CFLAGS AFLAGS export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS @@ -291,7 +288,7 @@ TAGS: dummy # Exuberant ctags works better with -I tags: dummy - CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__initlocaldata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \ + CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \ ctags $$CTAGSF `find include/asm-$(ARCH) -name '*.h'` && \ find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs ctags $$CTAGSF -a && \ find $(SUBDIRS) init -name '*.c' | xargs ctags $$CTAGSF -a @@ -367,6 +364,7 @@ clean: archclean rm -f drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c rm -f drivers/char/conmakehash rm -f drivers/pci/devlist.h drivers/pci/classlist.h drivers/pci/gen-devlist + rm -f drivers/zorro/devlist.h drivers/zorro/gen-devlist rm -f drivers/sound/bin2hex drivers/sound/hex2hex rm -f drivers/atm/fore200e_mkfirm drivers/atm/{pca,sba}*{.bin,.bin1,.bin2} rm -f net/khttpd/make_times_h @@ -161,12 +161,10 @@ CONFIGURING the kernel: COMPILING the kernel: - - Make sure you have gcc-2.7.2 or newer available. It seems older gcc - versions can have problems compiling newer versions of Linux. This - is mainly because the older compilers can only generate "a.out"-format - executables. As of Linux 2.1.0, the kernel must be compiled as an - "ELF" binary. If you upgrade your compiler, remember to get the new - binutils package too (for as/ld/nm and company). + - Make sure you have gcc-2.91.66 (egcs-1.1.2) available. gcc 2.95.2 may + also work but is not as safe, and *gcc 2.7.2.3 is no longer supported*. + Also remember to upgrade your binutils package (for as/ld/nm and company) + if necessary. For more information, refer to ./Documentation/Changes. Please note that you can still run a.out user programs with this kernel. diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 3b0126e7d..18fdcde8a 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -63,6 +63,7 @@ unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS CONFIG_ALPHA_POLARIS unset CONFIG_ALPHA_TSUNAMI CONFIG_ALPHA_MCPCIA unset CONFIG_ALPHA_IRONGATE unset CONFIG_ALPHA_BROKEN_IRQ_MASK +unset CONFIG_ALPHA_LARGE_VMALLOC # Most of these machines have ISA slots; not exactly sure which don't, # and this doesn't activate hordes of code, so do it always. @@ -207,6 +208,14 @@ then bool 'Symmetric multi-processing support' CONFIG_SMP fi +# The machine must be able to support more than 8GB physical memory +# before large vmalloc might even pretend to be an issue. +if [ "$CONFIG_ALPHA_GENERIC" = "y" -o "$CONFIG_ALPHA_DP264" = "y" \ + -o "$CONFIG_ALPHA_WILDFIRE" = "y" -o "$CONFIG_ALPHA_TITAN" = "y" ] +then + bool 'Large VMALLOC support' CONFIG_ALPHA_LARGE_VMALLOC +fi + source drivers/pci/Config.in bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index f7bf7b2a0..702778091 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -6,14 +6,14 @@ # # Code maturity level options # -# CONFIG_EXPERIMENTAL is not set +CONFIG_EXPERIMENTAL=y # # Loadable module support # CONFIG_MODULES=y # CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set +CONFIG_KMOD=y # # General setup @@ -52,6 +52,7 @@ CONFIG_ISA=y CONFIG_PCI=y CONFIG_ALPHA_BROKEN_IRQ_MASK=y # CONFIG_SMP is not set +# CONFIG_ALPHA_LARGE_VMALLOC is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -61,10 +62,10 @@ CONFIG_SYSVIPC=y CONFIG_SYSCTL=y CONFIG_KCORE_ELF=y # CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -CONFIG_BINFMT_EM86=y +# CONFIG_BINFMT_EM86 is not set # # Parallel port support @@ -72,10 +73,15 @@ CONFIG_BINFMT_EM86=y # 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_PNP=y +CONFIG_ISAPNP=y # # Block devices @@ -84,11 +90,24 @@ CONFIG_BLK_DEV_FD=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -96,23 +115,48 @@ CONFIG_BLK_DEV_FD=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set +CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set +# CONFIG_IP_MROUTE is not set +CONFIG_INET_ECN=y # CONFIG_SYN_COOKIES is not set # -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_LIMIT is not set +# CONFIG_IP_NF_MATCH_MAC is not set +# CONFIG_IP_NF_MATCH_MARK is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_STATE 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 is not set +# 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 is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=y +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set # # @@ -120,13 +164,92 @@ CONFIG_SKB_LARGE=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set # # 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_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# 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_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_IDEDMA_PCI_AUTO=y +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD7409 is not set +# CONFIG_AMD7409_OVERRIDE is not set +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_CY82C693=y +# 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_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y # # SCSI support @@ -140,7 +263,7 @@ CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 # CONFIG_CHR_DEV_ST is not set CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 # CONFIG_CHR_DEV_SG is not set @@ -149,7 +272,7 @@ CONFIG_SR_EXTRA_DEVS=2 # # CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # @@ -161,13 +284,18 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA152X is not set # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_IPS is not set +CONFIG_SCSI_AIC7XXX=y +CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT=y +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_PROC_STATS=y +CONFIG_AIC7XXX_RESET_DELAY=5 # 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 @@ -178,24 +306,30 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set +CONFIG_SCSI_NCR53C8XX=y +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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=y +# 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_DEBUG is not set # # Network device support @@ -209,40 +343,62 @@ CONFIG_NETDEVICES=y CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +CONFIG_VORTEX=y # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set # CONFIG_DEPCA is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set -CONFIG_DE4X5=y -# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +CONFIG_TULIP=y # CONFIG_DGRS is not set +# CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +CONFIG_YELLOWFIN=y # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -256,6 +412,8 @@ CONFIG_DE4X5=y # # CONFIG_TR is not set # CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set # # Wan interfaces @@ -307,19 +465,19 @@ CONFIG_PSMOUSE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set -# CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set +CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -328,34 +486,38 @@ CONFIG_PSMOUSE=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set +# CONFIG_AGP is not set # CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # -# USB support +# Multimedia devices # -# CONFIG_USB is not set +# CONFIG_VIDEO_DEV is not set # # File systems # # CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS_FS=m # CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_MINIX_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 @@ -363,23 +525,40 @@ CONFIG_PROC_FS=y # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE 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_NFS_FS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y # CONFIG_ROOT_NFS is not set -# CONFIG_NFSD is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_SUNRPC=m +CONFIG_LOCKD=m +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_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set # # Partition Types @@ -387,7 +566,45 @@ CONFIG_LOCKD=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_OSF_PARTITION=y CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# 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_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 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_8 is not set +# CONFIG_NLS_ISO8859_9 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_UTF8 is not set # # Console drivers @@ -405,7 +622,18 @@ CONFIG_VGA_CONSOLE=y # CONFIG_SOUND is not set # +# USB support +# +# CONFIG_USB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# # Kernel hacking # CONFIG_MATHEMU=y -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_ALPHA_LEGACY_START_ADDRESS=y diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c index c686fd29d..1b1f46867 100644 --- a/arch/alpha/kernel/core_cia.c +++ b/arch/alpha/kernel/core_cia.c @@ -399,7 +399,7 @@ verify_tb_operation(void) { static int page[PAGE_SIZE/4] __attribute__((aligned(PAGE_SIZE))) - __initlocaldata = { 0 }; + __initdata = { 0 }; struct pci_iommu_arena *arena = pci_isa_hose->sg_isa; int ctrl, addr0, tag0, pte0, data0; diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 4aded0d6a..8a5c12e08 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -449,17 +449,13 @@ static int __init srm_console_setup(struct console *co, char *options) } static struct console srmcons = { - "srm0", - srm_console_write, - NULL, - srm_console_device, - srm_console_wait_key, - NULL, - srm_console_setup, - CON_PRINTBUFFER | CON_ENABLED, /* fake it out */ - -1, - 0, - NULL + name: "srm0", + write: srm_console_write, + device: srm_console_device, + wait_key: srm_console_wait_key, + setup: srm_console_setup, + flags: CON_PRINTBUFFER | CON_ENABLED, /* fake it out */ + index: -1, }; #else @@ -683,7 +679,7 @@ static int tsunami_indices[] = {0,1,2,3,4,5,6,7,8}; static struct alpha_machine_vector * __init get_sysvec(long type, long variation, long cpu) { - static struct alpha_machine_vector *systype_vecs[] __initlocaldata = + static struct alpha_machine_vector *systype_vecs[] __initdata = { NULL, /* 0 */ NULL, /* ADU */ @@ -726,48 +722,48 @@ get_sysvec(long type, long variation, long cpu) NULL, /* Titan */ }; - static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata = + static struct alpha_machine_vector *unofficial_vecs[] __initdata = { NULL, /* 100 */ &ruffian_mv, }; - static struct alpha_machine_vector *api_vecs[] __initlocaldata = + static struct alpha_machine_vector *api_vecs[] __initdata = { NULL, /* 200 */ &nautilus_mv, }; - static struct alpha_machine_vector *alcor_vecs[] __initlocaldata = + static struct alpha_machine_vector *alcor_vecs[] __initdata = { &alcor_mv, &xlt_mv, &xlt_mv }; - static struct alpha_machine_vector *eb164_vecs[] __initlocaldata = + static struct alpha_machine_vector *eb164_vecs[] __initdata = { &eb164_mv, &pc164_mv, &lx164_mv, &sx164_mv, &rx164_mv }; - static struct alpha_machine_vector *eb64p_vecs[] __initlocaldata = + static struct alpha_machine_vector *eb64p_vecs[] __initdata = { &eb64p_mv, &cabriolet_mv, &cabriolet_mv /* AlphaPCI64 */ }; - static struct alpha_machine_vector *eb66_vecs[] __initlocaldata = + static struct alpha_machine_vector *eb66_vecs[] __initdata = { &eb66_mv, &eb66p_mv }; - static struct alpha_machine_vector *titan_vecs[] __initlocaldata = + static struct alpha_machine_vector *titan_vecs[] __initdata = { NULL, &privateer_mv, /* privateer */ }; - static struct alpha_machine_vector *tsunami_vecs[] __initlocaldata = + static struct alpha_machine_vector *tsunami_vecs[] __initdata = { NULL, &dp264_mv, /* dp264 */ @@ -860,7 +856,7 @@ get_sysvec(long type, long variation, long cpu) static struct alpha_machine_vector * __init get_sysvec_byname(const char *name) { - static struct alpha_machine_vector *all_vecs[] __initlocaldata = + static struct alpha_machine_vector *all_vecs[] __initdata = { &alcor_mv, &alphabook1_mv, diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index 656a0a8df..5b764298a 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c @@ -201,7 +201,7 @@ alcor_init_irq(void) static int __init alcor_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[7][5] __initlocaldata = { + static char irq_tab[7][5] __initdata = { /*INT INTA INTB INTC INTD */ /* note: IDSEL 17 is XLT only */ {16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */ diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index 8f456ca54..624c6732c 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c @@ -173,7 +173,7 @@ pc164_device_interrupt(unsigned long v, struct pt_regs *r) static inline int __init eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initlocaldata = { + static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ {16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J25 */ {16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J26 */ @@ -203,7 +203,7 @@ eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static inline int __init cabriolet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initlocaldata = { + static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ { 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5, slot 2, J21 */ { 16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J19 */ @@ -274,7 +274,7 @@ cia_cab_init_pci(void) static inline int __init alphapc164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[7][5] __initlocaldata = { + static char irq_tab[7][5] __initdata = { /*INT INTA INTB INTC INTD */ { 16+2, 16+2, 16+9, 16+13, 16+17}, /* IdSel 5, slot 2, J20 */ { 16+0, 16+0, 16+7, 16+11, 16+15}, /* IdSel 6, slot 0, J29 */ diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 9f9993b6a..6197a6a14 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -393,7 +393,7 @@ clipper_init_irq(void) static int __init dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[6][5] __initlocaldata = { + static char irq_tab[6][5] __initdata = { /*INT INTA INTB INTC INTD */ { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */ { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/ @@ -427,7 +427,7 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static int __init monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[13][5] __initlocaldata = { + static char irq_tab[13][5] __initdata = { /*INT INTA INTB INTC INTD */ { 45, 45, 45, 45, 45}, /* IdSel 3 21143 PCI1 */ { -1, -1, -1, -1, -1}, /* IdSel 4 unused */ @@ -488,7 +488,7 @@ monet_swizzle(struct pci_dev *dev, u8 *pinp) static int __init webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[13][5] __initlocaldata = { + static char irq_tab[13][5] __initdata = { /*INT INTA INTB INTC INTD */ { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ { -1, -1, -1, -1, -1}, /* IdSel 8 unused */ @@ -509,7 +509,7 @@ webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static int __init clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[7][5] __initlocaldata = { + static char irq_tab[7][5] __initdata = { /*INT INTA INTB INTC INTD */ { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */ { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */ diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index 6acbef05c..8a98a959c 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c @@ -188,7 +188,7 @@ eb64p_init_irq(void) static int __init eb64p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initlocaldata = { + static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ {16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */ {16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */ diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c index f54de2c87..01ff6334e 100644 --- a/arch/alpha/kernel/sys_miata.c +++ b/arch/alpha/kernel/sys_miata.c @@ -151,7 +151,7 @@ miata_init_irq(void) static int __init miata_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[18][5] __initlocaldata = { + static char irq_tab[18][5] __initdata = { /*INT INTA INTB INTC INTD */ {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8}, /* IdSel 14, DC21142 */ { -1, -1, -1, -1, -1}, /* IdSel 15, EIDE */ diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index d939b2c21..298fac1b2 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c @@ -164,7 +164,7 @@ mikasa_init_irq(void) static int __init mikasa_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[8][5] __initlocaldata = { + static char irq_tab[8][5] __initdata = { /*INT INTA INTB INTC INTD */ {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17, SCSI */ { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */ diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index 6e777c3ab..950fffcf1 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -205,7 +205,7 @@ noritake_init_irq(void) static int __init noritake_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[15][5] __initlocaldata = { + static char irq_tab[15][5] __initdata = { /*INT INTA INTB INTC INTD */ /* note: IDSELs 16, 17, and 25 are CORELLE only */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */ diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index 3ccce8640..b18c148d1 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c @@ -194,7 +194,7 @@ rawhide_init_irq(void) static int __init rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initlocaldata = { + static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ { 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */ { 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */ diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c index 23069e06d..54fc93387 100644 --- a/arch/alpha/kernel/sys_ruffian.c +++ b/arch/alpha/kernel/sys_ruffian.c @@ -119,7 +119,7 @@ ruffian_get_bank_size(unsigned long offset) /* Check BANK_ENABLE */ if (bank & 0x01) { - static unsigned long size[] __initlocaldata = { + static unsigned long size[] __initdata = { 0x40000000UL, /* 0x00, 1G */ 0x20000000UL, /* 0x02, 512M */ 0x10000000UL, /* 0x04, 256M */ diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index 2d5927c84..fa237282c 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c @@ -164,7 +164,7 @@ static int __init rx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { #if 0 - static char irq_tab_pass1[6][5] __initlocaldata = { + static char irq_tab_pass1[6][5] __initdata = { /*INT INTA INTB INTC INTD */ { 16+3, 16+3, 16+8, 16+13, 16+18}, /* IdSel 5, slot 2 */ { 16+5, 16+5, 16+10, 16+15, 16+20}, /* IdSel 6, slot 0 */ @@ -174,7 +174,7 @@ rx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { 16+1, 16+1, 16+6, 16+11, 16+16}, /* IdSel 10, slot 4 */ }; #else - static char irq_tab[6][5] __initlocaldata = { + static char irq_tab[6][5] __initdata = { /*INT INTA INTB INTC INTD */ { 16+0, 16+0, 16+6, 16+11, 16+16}, /* IdSel 5, slot 0 */ { 16+1, 16+1, 16+7, 16+12, 16+17}, /* IdSel 6, slot 1 */ diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index b27d757b2..c2513d3b8 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c @@ -255,7 +255,7 @@ sable_init_irq(void) static int __init sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[9][5] __initlocaldata = { + 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 */ diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index e378408f2..7853ad012 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -143,7 +143,7 @@ noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin) * that they use the default INTA line, if they are interrupt * driven at all). */ - static char irq_tab[][5] __initlocaldata = { + static char irq_tab[][5] __initdata = { /*INT A B C D */ { 3, 3, 3, 3, 3}, /* idsel 6 (53c810) */ {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */ @@ -164,7 +164,7 @@ noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static inline int __init p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[][5] __initlocaldata = { + static char irq_tab[][5] __initdata = { /*INT A B C D */ { 0, 0, -1, -1, -1}, /* idsel 6 (53c810) */ {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */ diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c index 19abbb6c3..2d31435e4 100644 --- a/arch/alpha/kernel/sys_sx164.c +++ b/arch/alpha/kernel/sys_sx164.c @@ -96,7 +96,7 @@ sx164_init_irq(void) static int __init sx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initlocaldata = { + static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ { 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */ { 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */ diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index 9ebba3955..c6d858f91 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -172,7 +172,7 @@ takara_init_irq(void) static int __init takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[15][5] __initlocaldata = { + static char irq_tab[15][5] __initdata = { { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */ @@ -203,7 +203,7 @@ takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin) static int __init takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[15][5] __initlocaldata = { + static char irq_tab[15][5] __initdata = { { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */ diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index 276195040..8a7ad55c4 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c @@ -302,7 +302,7 @@ wildfire_device_interrupt(unsigned long vector, struct pt_regs * regs) static int __init wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[8][5] __initlocaldata = { + static char irq_tab[8][5] __initdata = { /*INT INTA INTB INTC INTD */ { -1, -1, -1, -1, -1}, /* IdSel 0 ISA Bridge */ { 36, 36, 36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */ @@ -326,11 +326,6 @@ wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin) return irq; } -static void __init -wildfire_init_pci(void) -{ - common_init_pci(); -} /* * The System Vectors @@ -353,7 +348,7 @@ struct alpha_machine_vector wildfire_mv __initmv = { init_arch: wildfire_init_arch, init_irq: wildfire_init_irq, init_rtc: common_init_rtc, - init_pci: wildfire_init_pci, + init_pci: common_init_pci, kill_arch: wildfire_kill_arch, pci_map_irq: wildfire_map_irq, pci_swizzle: common_swizzle, diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index b6cf88e3d..d22a6f522 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile @@ -13,7 +13,7 @@ OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \ strchr.o strrchr.o memchr.o \ copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \ csum_ipv6_magic.o strcasecmp.o semaphore.o fpreg.o \ - callback_srm.o callback_init.o srm_puts.o srm_printk.o + callback_srm.o srm_puts.o srm_printk.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) diff --git a/arch/alpha/lib/callback_init.c b/arch/alpha/lib/callback_init.c deleted file mode 100644 index fe643ccfc..000000000 --- a/arch/alpha/lib/callback_init.c +++ /dev/null @@ -1,79 +0,0 @@ -#include <linux/init.h> -#include <linux/sched.h> - -#include <asm/page.h> -#include <asm/hwrpb.h> -#include <asm/console.h> -#include <asm/pgtable.h> - -#include "../kernel/proto.h" - -extern struct hwrpb_struct *hwrpb; - -/* This is the SRM version. Maybe there will be a DBM version. */ - -int callback_init_done = 0; - -void * __init callback_init(void * kernel_end) -{ - int i, j; - unsigned long vaddr = CONSOLE_REMAP_START; - struct crb_struct * crb; - pgd_t * pgd = pgd_offset_k(vaddr); - pmd_t * pmd; - unsigned long two_pte_pages; - - if (!alpha_using_srm) { - switch_to_system_map(); - return kernel_end; - } - - /* Allocate some memory for the pages. */ - two_pte_pages = ((unsigned long)kernel_end + ~PAGE_MASK) & PAGE_MASK; - kernel_end = (void *)(two_pte_pages + 2*PAGE_SIZE); - memset((void *)two_pte_pages, 0, 2*PAGE_SIZE); - - /* Starting at the HWRPB, locate the CRB. */ - crb = (struct crb_struct *)((char *)hwrpb + hwrpb->crb_offset); - - /* Tell the console whither the console is to be remapped. */ - if (srm_fixup(vaddr, (unsigned long)hwrpb)) - __halt(); /* "We're boned." --Bender */ - - /* Edit the procedure descriptors for DISPATCH and FIXUP. */ - crb->dispatch_va = (struct procdesc_struct *) - (vaddr + (unsigned long)crb->dispatch_va - crb->map[0].va); - crb->fixup_va = (struct procdesc_struct *) - (vaddr + (unsigned long)crb->fixup_va - crb->map[0].va); - - switch_to_system_map(); - - /* - * Set up the first and second level PTEs for console callbacks. - * 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. - */ - pgd_set(pgd, (pmd_t *)two_pte_pages); - pmd = pmd_offset(pgd, vaddr); - pmd_set(pmd, (pte_t *)(two_pte_pages + PAGE_SIZE)); - - /* - * Set up the third level PTEs and update the virtual addresses - * of the CRB entries. - */ - for (i = 0; i < crb->map_entries; ++i) { - unsigned long paddr = crb->map[i].pa; - crb->map[i].va = vaddr; - for (j = 0; j < crb->map[i].count; ++j) { - set_pte(pte_offset(pmd, vaddr), - mk_pte_phys(paddr, PAGE_KERNEL)); - paddr += PAGE_SIZE; - vaddr += PAGE_SIZE; - } - } - - callback_init_done = 1; - return kernel_end; -} - diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index c81a12d18..a5140ce1c 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -108,6 +108,11 @@ do_page_fault(unsigned long address, unsigned long mmcsr, if (!mm || in_interrupt()) goto no_context; +#ifdef CONFIG_ALPHA_LARGE_VMALLOC + if (address >= TASK_SIZE) + goto vmalloc_fault; +#endif + down(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -204,4 +209,25 @@ do_sigbus: if (!user_mode(regs)) goto no_context; return; + +#ifdef CONFIG_ALPHA_LARGE_VMALLOC +vmalloc_fault: + if (user_mode(regs)) { + force_sig(SIGSEGV, current); + return; + } else { + /* Synchronize this task's top level page-table + with the "reference" page table from init. */ + long offset = __pgd_offset(address); + pgd_t *pgd, *pgd_k; + + pgd = current->active_mm->pgd + offset; + pgd_k = swapper_pg_dir + offset; + if (!pgd_present(*pgd) && pgd_present(*pgd_k)) { + pgd_val(*pgd) = pgd_val(*pgd_k); + return; + } + goto no_context; + } +#endif } diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 2ab7941b2..52e2b36f7 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -19,6 +19,7 @@ #include <linux/swap.h> #include <linux/init.h> #include <linux/bootmem.h> /* max_low_pfn */ +#include <linux/vmalloc.h> #ifdef CONFIG_BLK_DEV_INITRD #include <linux/blk.h> #endif @@ -30,6 +31,7 @@ #include <asm/hwrpb.h> #include <asm/dma.h> #include <asm/mmu_context.h> +#include <asm/console.h> static unsigned long totalram_pages; @@ -55,6 +57,29 @@ __bad_pte(pmd_t *pmd) pmd_set(pmd, (pte_t *) BAD_PAGETABLE); } +pgd_t * +get_pgd_slow(void) +{ + pgd_t *ret, *init; + + ret = (pgd_t *)__get_free_page(GFP_KERNEL); + init = pgd_offset(&init_mm, 0UL); + if (ret) { + clear_page(ret); +#ifdef CONFIG_ALPHA_LARGE_VMALLOC + memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD - 1)*sizeof(pgd_t)); +#else + pgd_val(ret[PTRS_PER_PGD-2]) = pgd_val(init[PTRS_PER_PGD-2]); +#endif + + /* The last PGD entry is the VPTB self-map. */ + pgd_val(ret[PTRS_PER_PGD-1]) + = pte_val(mk_pte(virt_to_page(ret), PAGE_KERNEL)); + } + return ret; +} + pmd_t * get_pmd_slow(pgd_t *pgd, unsigned long offset) { @@ -182,8 +207,9 @@ load_PCB(struct thread_struct * pcb) return __reload_thread(pcb); } -/* switch_to_system_map() sets up some necessary page tables. */ -void +/* Set up initial PCB, VPTB, and other such nicities. */ + +static inline void switch_to_system_map(void) { unsigned long newptbr; @@ -225,6 +251,84 @@ switch_to_system_map(void) original_pcb = *(struct thread_struct *) original_pcb_ptr; } +int callback_init_done; + +void * __init +callback_init(void * kernel_end) +{ + struct crb_struct * crb; + pgd_t *pgd; + pmd_t *pmd; + void *two_pages; + + /* Starting at the HWRPB, locate the CRB. */ + crb = (struct crb_struct *)((char *)hwrpb + hwrpb->crb_offset); + + if (alpha_using_srm) { + /* Tell the console whither it is to be remapped. */ + if (srm_fixup(VMALLOC_START, (unsigned long)hwrpb)) + __halt(); /* "We're boned." --Bender */ + + /* Edit the procedure descriptors for DISPATCH and FIXUP. */ + crb->dispatch_va = (struct procdesc_struct *) + (VMALLOC_START + (unsigned long)crb->dispatch_va + - crb->map[0].va); + crb->fixup_va = (struct procdesc_struct *) + (VMALLOC_START + (unsigned long)crb->fixup_va + - crb->map[0].va); + } + + switch_to_system_map(); + + /* 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. + + 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 + forking other tasks. */ + + two_pages = (void *) + (((unsigned long)kernel_end + ~PAGE_MASK) & PAGE_MASK); + kernel_end = two_pages + 2*PAGE_SIZE; + memset(two_pages, 0, 2*PAGE_SIZE); + + pgd = pgd_offset_k(VMALLOC_START); + pgd_set(pgd, (pmd_t *)two_pages); + pmd = pmd_offset(pgd, VMALLOC_START); + pmd_set(pmd, (pte_t *)(two_pages + PAGE_SIZE)); + + if (alpha_using_srm) { + static struct vm_struct console_remap_vm; + unsigned long vaddr = VMALLOC_START; + long i, j; + + /* Set up the third level PTEs and update the virtual + addresses of the CRB entries. */ + for (i = 0; i < crb->map_entries; ++i) { + unsigned long paddr = crb->map[i].pa; + crb->map[i].va = vaddr; + for (j = 0; j < crb->map[i].count; ++j) { + set_pte(pte_offset(pmd, vaddr), + mk_pte_phys(paddr, PAGE_KERNEL)); + paddr += PAGE_SIZE; + vaddr += PAGE_SIZE; + } + } + + /* Let vmalloc know that we've allocated some space. */ + console_remap_vm.flags = VM_ALLOC; + console_remap_vm.addr = VMALLOC_START; + console_remap_vm.size = vaddr - VMALLOC_START; + vmlist = &console_remap_vm; + } + + callback_init_done = 1; + return kernel_end; +} + + /* * paging_init() sets up the memory map. */ diff --git a/arch/arm/config.in b/arch/arm/config.in index 1a79b55b9..fff056940 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -213,7 +213,8 @@ if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \ define_bool CONFIG_PCI y else if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then - bool 'PCI support' CONFIG_PCI + bool 'PCI support' CONFIG_PCI_INTEGRATOR + define_bool CONFIG_PCI $CONFIG_PCI_INTEGRATOR else define_bool CONFIG_PCI n fi diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c index e01a6417e..f89852641 100644 --- a/arch/arm/kernel/semaphore.c +++ b/arch/arm/kernel/semaphore.c @@ -19,8 +19,8 @@ /* * Semaphores are implemented using a two-way counter: * The "count" variable is decremented for each process - * that tries to aquire the semaphore, while the "sleeping" - * variable is a count of such aquires. + * that tries to acquire the semaphore, while the "sleeping" + * variable is a count of such acquires. * * Notably, the inline "up()" and "down()" functions can * efficiently test if they need to do any extra work (up @@ -257,7 +257,7 @@ struct rw_semaphore *down_write_failed(struct rw_semaphore *sem) while (atomic_read(&sem->count) < 0) { set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (atomic_read(&sem->count) >= 0) - break; /* we must attempt to aquire or bias the lock */ + break; /* we must attempt to acquire or bias the lock */ schedule(); } diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index a235232d9..ea833c58d 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -56,7 +56,7 @@ extern char _stext, _text, _etext, _end, __init_begin, __init_end; * The sole use of this is to pass memory configuration * data from paging_init to mem_init. */ -static struct meminfo __initdata meminfo; +static struct meminfo meminfo __initdata = { 0, }; /* * empty_bad_page is the page that is used for page faults when @@ -383,27 +383,27 @@ static inline void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot * Register the kernel text and data with bootmem. * Note that this can only be in node 0. */ - reserve_bootmem_node(0, __pa(&_stext), &_end - &_stext); + reserve_bootmem_node(NODE_DATA(0), __pa(&_stext), &_end - &_stext); #ifdef CONFIG_CPU_32 /* * Reserve the page tables. These are already in use, * and can only be in node 0. */ - reserve_bootmem_node(0, __pa(swapper_pg_dir), + reserve_bootmem_node(NODE_DATA(0), __pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *)); #else /* * Stop this memory from being grabbed - its special DMA * memory that is required for the screen. */ - reserve_bootmem_node(0, 0x02000000, 0x00080000); + reserve_bootmem_node(NODE_DATA(0), 0x02000000, 0x00080000); #endif /* * And don't forget to reserve the allocator bitmap, * which will be freed later. */ - reserve_bootmem_node(0, bootmap_pfn << PAGE_SHIFT, + reserve_bootmem_node(NODE_DATA(0), bootmap_pfn << PAGE_SHIFT, bootmap_pages << PAGE_SHIFT); } @@ -416,7 +416,7 @@ static inline void free_bootmem_node_bank(int node, struct meminfo *mi) for (bank = 0; bank < mi->nr_banks; bank++) if (mi->bank[bank].node == node) - free_bootmem_node(node, mi->bank[bank].start, + free_bootmem_node(NODE_DATA(node), mi->bank[bank].start, mi->bank[bank].size); } @@ -450,7 +450,7 @@ void __init bootmem_init(struct meminfo *mi) /* * Initialise the bootmem allocator. */ - init_bootmem_node(node, map_pg, np->start, np->end); + init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end); free_bootmem_node_bank(node, mi); map_pg += np->bootmap_pages; @@ -465,7 +465,7 @@ void __init bootmem_init(struct meminfo *mi) #ifdef CONFIG_BLK_DEV_INITRD if (initrd_node >= 0) - reserve_bootmem_node(initrd_node, __pa(initrd_start), + reserve_bootmem_node(NODE_DATA(initrd_node), __pa(initrd_start), initrd_end - initrd_start); #endif @@ -583,7 +583,7 @@ void __init mem_init(void) /* this will put all unused low memory onto the freelists */ for (node = 0; node < numnodes; node++) - totalram_pages += free_all_bootmem_node(node); + totalram_pages += free_all_bootmem_node(NODE_DATA(node)); /* * Since our memory may not be contiguous, calculate the diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 9ddcc84bc..2ace55d47 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -438,7 +438,7 @@ static inline void free_memmap(int node, unsigned long start, unsigned long end) start = __virt_to_phys(pg); end = __virt_to_phys(pgend); - free_bootmem_node(node, start, end - start); + free_bootmem_node(NODE_DATA(node), start, end - start); } static inline void free_unused_memmap_node(int node, struct meminfo *mi) diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 7735399cb..96da8d33b 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -23,62 +23,59 @@ LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS) CFLAGS += -pipe -# only work around strength reduction bug(s) on older gcc versions -CFLAGS += $(shell if ! $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strength-reduce"; fi) - # prevent gcc from keeping the stack 16 byte aligned CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi) ifdef CONFIG_M386 -CFLAGS += $(shell if $(CC) -march=i386 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i386"; else echo "-m386"; fi) +CFLAGS += -march=i386 endif ifdef CONFIG_M486 -CFLAGS += $(shell if $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i486"; else echo "-m486"; fi) +CFLAGS += -march=i486 endif ifdef CONFIG_M586 -CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi) +CFLAGS += -march=i586 endif ifdef CONFIG_M586TSC -CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi) +CFLAGS += -march=i586 endif ifdef CONFIG_M586MMX -CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi) +CFLAGS += -march=i586 endif ifdef CONFIG_M686 -CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) +CFLAGS += -march=i686 endif ifdef CONFIG_M686FXSR -CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) +CFLAGS += -march=i686 endif ifdef CONFIG_MK6 -CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; fi) +CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; else echo "-march=i586"; fi) endif ifdef CONFIG_MK7 -CFLAGS += $(shell if $(CC) -march=athlon -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=athlon"; else if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686 -malign-functions=4"; fi fi) +CFLAGS += $(shell if $(CC) -march=athlon -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=athlon"; else echo "-march=i686 -malign-functions=4"; fi) endif ifdef CONFIG_MCRUSOE -CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi) +CFLAGS += -march=i586 endif ifdef CONFIG_MWINCHIPC6 -CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) +CFLAGS += -march=i586 endif ifdef CONFIG_MWINCHIP2 -CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) +CFLAGS += -march=i586 endif ifdef CONFIG_MWINCHIP3D -CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) +CFLAGS += -march=i586 endif HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index c91d8ff00..0da4e866e 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S @@ -641,6 +641,15 @@ end_move_self: # now we are at the right place outb %al, $0x60 call empty_8042 +# +# You must preserve the other bits here. Otherwise embarrasing things +# like laptops powering off on boot happen. Corrected version by Kira +# Brown from Linux 2.2 +# + inb $0x92, %al # + orb $02, %al # "fast A20" version + outb %al, $0x92 # some chips have only this + # wait until a20 really *is* enabled; it can take a fair amount of # time on certain systems; Toshiba Tecras are known to have this # problem. The memory location used here (0x200) is the int 0x80 diff --git a/arch/i386/config.in b/arch/i386/config.in index 6d1279ed7..327aa736d 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -45,7 +45,7 @@ choice 'Processor family' \ # if [ "$CONFIG_M386" = "y" ]; then define_bool CONFIG_X86_CMPXCHG n - define_int CONFIG_X86_L1_CACHE_BYTES 16 + define_int CONFIG_X86_L1_CACHE_SHIFT 4 else define_bool CONFIG_X86_WP_WORKS_OK y define_bool CONFIG_X86_INVLPG y @@ -54,37 +54,37 @@ else define_bool CONFIG_X86_POPAD_OK y fi if [ "$CONFIG_M486" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 16 + define_int CONFIG_X86_L1_CACHE_SHIFT 4 define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_ALIGNMENT_16 y fi if [ "$CONFIG_M586" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_ALIGNMENT_16 y fi if [ "$CONFIG_M586TSC" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_TSC y fi if [ "$CONFIG_M586MMX" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y fi if [ "$CONFIG_M686" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi if [ "$CONFIG_M686FXSR" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y @@ -93,13 +93,13 @@ if [ "$CONFIG_M686FXSR" = "y" ]; then define_bool CONFIG_X86_XMM y fi if [ "$CONFIG_MK6" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi if [ "$CONFIG_MK7" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 64 + define_int CONFIG_X86_L1_CACHE_SHIFT 6 define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_USE_3DNOW y @@ -107,22 +107,22 @@ if [ "$CONFIG_MK7" = "y" ]; then define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi if [ "$CONFIG_MCRUSOE" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_TSC y fi if [ "$CONFIG_MWINCHIPC6" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi if [ "$CONFIG_MWINCHIP2" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi if [ "$CONFIG_MWINCHIP3D" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 7dddf3057..b22c770db 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -39,7 +39,7 @@ CONFIG_X86_INVLPG=y CONFIG_X86_CMPXCHG=y CONFIG_X86_BSWAP=y CONFIG_X86_POPAD_OK=y -CONFIG_X86_L1_CACHE_BYTES=32 +CONFIG_X86_L1_CACHE_SHIFT=5 CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_PGE=y @@ -230,7 +230,9 @@ CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set # CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_OSB4 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 @@ -352,6 +354,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c index 211a6ce50..f9424d105 100644 --- a/arch/i386/kernel/acpi.c +++ b/arch/i386/kernel/acpi.c @@ -27,6 +27,8 @@ * - check copy*user return * - get rid of check_region * - get rid of verify_area + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/09/28 + * - do proper release on failure in acpi_claim_ioports and acpi_init */ #include <linux/config.h> @@ -81,6 +83,7 @@ static int acpi_do_sleep(ctl_table *ctl, struct file *file, void *buffer, size_t *len); +static void acpi_release(unsigned long start, unsigned long size); static struct ctl_table_header *acpi_sysctl = NULL; @@ -1300,15 +1303,28 @@ static int acpi_claim(unsigned long start, unsigned long size) static int acpi_claim_ioports(struct acpi_facp *facp) { // we don't get a guarantee of contiguity for any of the ACPI registers - if (acpi_claim(facp->pm1a_evt, facp->pm1_evt_len) - || acpi_claim(facp->pm1b_evt, facp->pm1_evt_len) - || acpi_claim(facp->pm1a_cnt, facp->pm1_cnt_len) - || acpi_claim(facp->pm1b_cnt, facp->pm1_cnt_len) - || acpi_claim(facp->pm_tmr, facp->pm_tm_len) - || acpi_claim(facp->gpe0, facp->gpe0_len) - || acpi_claim(facp->gpe1, facp->gpe1_len)) - return -EBUSY; + if (acpi_claim(facp->pm1a_evt, facp->pm1_evt_len)) + goto return_ebusy; + if (acpi_claim(facp->pm1b_evt, facp->pm1_evt_len)) + goto release_pm1a_evt; + if (acpi_claim(facp->pm1a_cnt, facp->pm1_cnt_len)) + goto release_pm1b_evt; + if (acpi_claim(facp->pm1b_cnt, facp->pm1_cnt_len)) + goto release_pm1a_cnt; + if (acpi_claim(facp->pm_tmr, facp->pm_tm_len)) + goto release_pm1b_cnt; + if (acpi_claim(facp->gpe0, facp->gpe0_len)) + goto release_pm_tmr; + if (acpi_claim(facp->gpe1, facp->gpe1_len)) + goto release_gpe0; return 0; +release_gpe0: acpi_release(facp->gpe0, facp->gpe0_len); +release_pm_tmr: acpi_release(facp->pm_tmr, facp->pm_tm_len); +release_pm1b_cnt: acpi_release(facp->pm1b_cnt, facp->pm1_cnt_len); +release_pm1a_cnt: acpi_release(facp->pm1a_cnt, facp->pm1_cnt_len); +release_pm1b_evt: acpi_release(facp->pm1b_evt, facp->pm1_evt_len); +release_pm1a_evt: acpi_release(facp->pm1a_evt, facp->pm1_evt_len); +return_ebusy: return -EBUSY; } /* @@ -1523,8 +1539,10 @@ static int acpi_do_table(ctl_table *ctl, error = -ENOMEM; } if (data) - if (copy_from_user(data, buffer, size)) + if (copy_from_user(data, buffer, size)) { + acpi_destroy_table(info); error = -EFAULT; + } write_unlock(&acpi_do_table_lock); } @@ -1838,7 +1856,7 @@ int __init acpi_init(void) &acpi_facp)) { printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", facp->sci_int); - goto err_out; + goto cleanup_ioports; } #ifndef CONFIG_ACPI_S1_SLEEP @@ -1846,6 +1864,8 @@ int __init acpi_init(void) #endif acpi_sysctl = register_sysctl_table(acpi_dir_table, 1); + if (!acpi_sysctl) + goto cleanup_irq; pm_power_off = acpi_power_off; @@ -1863,7 +1883,10 @@ int __init acpi_init(void) pm_idle = acpi_idle; return 0; - +cleanup_irq: + free_irq(facp->sci_int, &acpi_facp); +cleanup_ioports: + acpi_release_ioports(facp); err_out: if (pci_driver_registered) pci_unregister_driver(&acpi_driver); diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 9a4084292..b0aa2a7c3 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -1427,7 +1427,7 @@ static int apm(void *unused) atomic_inc(¤t->files->count); daemonize(); - strcpy(current->comm, "kapmd"); + strcpy(current->comm, "kapm-idled"); sigfillset(¤t->blocked); current->tty = NULL; /* get rid of controlling tty */ diff --git a/arch/i386/kernel/bluesmoke.c b/arch/i386/kernel/bluesmoke.c index 0fecf5851..ee6966d5f 100644 --- a/arch/i386/kernel/bluesmoke.c +++ b/arch/i386/kernel/bluesmoke.c @@ -8,7 +8,7 @@ #include <asm/processor.h> #include <asm/msr.h> -static int banks = 0; +static int banks; void mcheck_fault(void) { @@ -71,7 +71,7 @@ void mcheck_init(void) u32 l, h; int i; struct cpuinfo_x86 *c; - static int done=0; + static int done; c=cpu_data+smp_processor_id(); diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 57aada831..4ae0ed2ee 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -205,7 +205,7 @@ ENTRY(system_call) ENTRY(ret_from_sys_call) #ifdef CONFIG_SMP movl processor(%ebx),%eax - shll $5,%eax + shll $CONFIG_X86_L1_CACHE_SHIFT,%eax movl SYMBOL_NAME(irq_stat)(,%eax),%ecx # softirq_active testl SYMBOL_NAME(irq_stat)+4(,%eax),%ecx # softirq_mask #else @@ -261,7 +261,7 @@ ret_from_exception: #ifdef CONFIG_SMP GET_CURRENT(%ebx) movl processor(%ebx),%eax - shll $5,%eax + shll $CONFIG_X86_L1_CACHE_SHIFT,%eax movl SYMBOL_NAME(irq_stat)(,%eax),%ecx # softirq_active testl SYMBOL_NAME(irq_stat)+4(,%eax),%ecx # softirq_mask #else @@ -305,16 +305,18 @@ error_code: pushl %ebx cld movl %es,%ecx - xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. ) + movl ORIG_EAX(%esp), %esi # get the error code + movl ES(%esp), %edi # get the function address + movl %eax, ORIG_EAX(%esp) + movl %ecx, ES(%esp) movl %esp,%edx - xchgl %ecx, ES(%esp) # get the address and save es. - pushl %eax # push the error code - pushl %edx + pushl %esi # push the error code + pushl %edx # push the pt_regs pointer movl $(__KERNEL_DS),%edx movl %edx,%ds movl %edx,%es GET_CURRENT(%ebx) - call *%ecx + call *%edi addl $8,%esp jmp ret_from_exception diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index b264c54a3..c3d052e8a 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -33,22 +33,24 @@ #endif /* - * FPU lazy state save handling. + * The _current_ task is using the FPU for the first time + * so initialize it and set the mxcsr to its default + * value at reset if we support FXSR and then + * remeber the current task has used the FPU. */ - -void save_fpu( struct task_struct *tsk ) +void init_fpu(void) { - if ( HAVE_FXSR ) { - asm volatile( "fxsave %0 ; fwait" - : "=m" (tsk->thread.i387.fxsave) ); - } else { - asm volatile( "fnsave %0 ; fwait" - : "=m" (tsk->thread.i387.fsave) ); - } - tsk->flags &= ~PF_USEDFPU; - stts(); + __asm__("fninit"); + if ( HAVE_FXSR ) + load_mxcsr(0x1f80); + + current->used_math = 1; } +/* + * FPU lazy state save handling. + */ + void save_init_fpu( struct task_struct *tsk ) { if ( HAVE_FXSR ) { @@ -79,16 +81,16 @@ void restore_fpu( struct task_struct *tsk ) static inline unsigned short twd_i387_to_fxsr( unsigned short twd ) { - unsigned short ret = 0; - int i; - - for ( i = 0 ; i < 8 ; i++ ) { - if ( (twd & 0x3) != 0x3 ) { - ret |= (1 << i); - } - twd = twd >> 2; - } - return ret; + unsigned int tmp; /* to avoid 16 bit prefixes in the code */ + + /* Transform each pair of bits into 01 (valid) or 00 (empty) */ + tmp = ~twd; + tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ + /* and move the valid bits to the lower byte. */ + tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ + tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ + tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ + return tmp; } static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) @@ -105,8 +107,8 @@ static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave if ( twd & 0x1 ) { st = (struct _fpxreg *) FPREG_ADDR( fxsave, i ); - switch ( st->exponent ) { - case 0xffff: + switch ( st->exponent & 0x7fff ) { + case 0x7fff: tag = 2; /* Special */ break; case 0x0000: diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 46e270774..df377c5b4 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -178,7 +178,7 @@ static unsigned int cached_irq_mask = 0xffff; * this 'mixed mode' IRQ handling costs nothing because it's only used * at IRQ setup time. */ -unsigned long io_apic_irqs = 0; +unsigned long io_apic_irqs; void disable_8259A_irq(unsigned int irq) { @@ -312,7 +312,7 @@ spurious_8259A_irq: goto handle_real_irq; { - static int spurious_irq_mask = 0; + static int spurious_irq_mask; /* * At this point we can be sure the IRQ is spurious, * lets ACK and report it. [once per IRQ] diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 80536a1c4..5f9925495 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -177,7 +177,7 @@ static void do_update_one(void *unused) req->err = 1; /* assume the worst */ - if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6){ + if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 != 6){ printk(KERN_ERR "microcode: CPU%d not an Intel P6\n", cpu_num); return; } @@ -198,11 +198,15 @@ static void do_update_one(void *unused) wrmsr(0x8B, 0, 0); __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); rdmsr(0x8B, val[0], rev); - if (microcode[i].rev <= rev) { + if (microcode[i].rev < rev) { printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier revision" " %d (current=%d)\n", cpu_num, microcode[i].rev, rev); - } else { + } else if (microcode[i].rev == rev) { + printk(KERN_ERR + "microcode: CPU%d already up-to-date (revision %d)\n", + cpu_num, rev); + } else { int sum = 0; struct microcode *m = µcode[i]; unsigned int *sump = (unsigned int *)(m+1); diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c index abe198315..045374d50 100644 --- a/arch/i386/kernel/mtrr.c +++ b/arch/i386/kernel/mtrr.c @@ -1581,7 +1581,7 @@ static struct proc_dir_entry *proc_root_mtrr; # endif /* CONFIG_PROC_FS */ -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static void compute_ascii (void) { diff --git a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c index b98bf4748..9a5fe8958 100644 --- a/arch/i386/kernel/pci-irq.c +++ b/arch/i386/kernel/pci-irq.c @@ -125,81 +125,143 @@ static void eisa_set_level_irq(unsigned int irq) } } +/* + * Common IRQ routing practice: nybbles in config space, + * offset by some magic constant. + */ +static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr) +{ + u8 x; + unsigned reg = offset + (nr >> 1); + + pci_read_config_byte(router, reg, &x); + return (nr & 1) ? (x >> 4) : (x & 0xf); +} + +static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val) +{ + u8 x; + unsigned reg = offset + (nr >> 1); + + pci_read_config_byte(router, reg, &x); + x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val); + pci_write_config_byte(router, reg, x); +} + +/* + * ALI pirq entries are damn ugly, and completely undocumented. + * This has been figured out from pirq tables, and it's not a pretty + * picture. + */ static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; + + switch (pirq) { + case 0x00: + return 0; + default: + return irqmap[read_config_nybble(router, 0x48, pirq-1)]; + case 0xfe: + return irqmap[read_config_nybble(router, 0x44, 0)]; + case 0xff: + return irqmap[read_config_nybble(router, 0x75, 0)]; + } +} + +static void pirq_ali_ide_interrupt(struct pci_dev *router, unsigned reg, unsigned val, unsigned irq) +{ u8 x; - unsigned reg; - pirq--; - reg = 0x48 + (pirq >> 1); pci_read_config_byte(router, reg, &x); - return irqmap[(pirq & 1) ? (x >> 4) : (x & 0x0f)]; + x = (x & 0xe0) | val; /* clear the level->edge transform */ + pci_write_config_byte(router, reg, x); + eisa_set_level_irq(irq); } static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; unsigned int val = irqmap[irq]; - pirq--; + if (val) { - u8 x; - unsigned reg = 0x48 + (pirq >> 1); - pci_read_config_byte(router, reg, &x); - x = (pirq & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val); - pci_write_config_byte(router, reg, x); + switch (pirq) { + default: + write_config_nybble(router, 0x48, pirq-1, val); + break; + case 0xfe: + pirq_ali_ide_interrupt(router, 0x44, val, irq); + break; + case 0xff: + pirq_ali_ide_interrupt(router, 0x75, val, irq); + break; + } eisa_set_level_irq(irq); return 1; } return 0; } +/* + * The Intel PIIX4 pirq rules are fairly simple: "pirq" is + * just a pointer to the config space. However, something + * funny is going on with 0xfe/0xff, and apparently they + * should handle IDE irq routing. Ignore them for now. + */ static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { u8 x; - pci_read_config_byte(router, pirq, &x); - return (x < 16) ? x : 0; + + switch (pirq) { + case 0xfe: + case 0xff: + return 0; + default: + pci_read_config_byte(router, pirq, &x); + return (x < 16) ? x : 0; + } } static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - pci_write_config_byte(router, pirq, irq); - return 1; + switch (pirq) { + case 0xfe: + case 0xff: + return 0; + default: + pci_write_config_byte(router, pirq, irq); + return 1; + } } +/* + * The VIA pirq rules are nibble-based, like ALI, + * but without the ugly irq number munging or the + * strange special cases.. + */ static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - u8 x; - int reg = 0x55 + (pirq >> 1); - pci_read_config_byte(router, reg, &x); - return (pirq & 1) ? (x >> 4) : (x & 0x0f); + return read_config_nybble(router, 0x55, pirq); } static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - u8 x; - int reg = 0x55 + (pirq >> 1); - pci_read_config_byte(router, reg, &x); - x = (pirq & 1) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | irq); - pci_write_config_byte(router, reg, x); + write_config_nybble(router, 0x55, pirq, irq); return 1; } +/* + * OPTI: high four bits are nibble pointer.. + * I wonder what the low bits do? + */ static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - u8 x; - int reg = 0xb8 + (pirq >> 5); - pci_read_config_byte(router, reg, &x); - return (pirq & 0x10) ? (x >> 4) : (x & 0x0f); + return read_config_nybble(router, 0xb8, pirq >> 4); } static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - u8 x; - int reg = 0xb8 + (pirq >> 5); - pci_read_config_byte(router, reg, &x); - x = (pirq & 0x10) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | irq); - pci_write_config_byte(router, reg, x); + write_config_nybble(router, 0xb8, pirq >> 4, irq); return 1; } diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index a9b11561d..b374f8e99 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -351,7 +351,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); + child->ptrace = 0; child->exit_code = data; write_lock_irq(&tasklist_lock); REMOVE_LINKS(child); @@ -451,6 +451,15 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) break; } + case PTRACE_SETOPTIONS: { + if (data & PTRACE_O_TRACESYSGOOD) + child->ptrace |= PT_TRACESYSGOOD; + else + child->ptrace &= ~PT_TRACESYSGOOD; + ret = 0; + break; + } + default: ret = -EIO; break; @@ -467,7 +476,10 @@ asmlinkage void syscall_trace(void) if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) != (PT_PTRACED|PT_TRACESYS)) return; - current->exit_code = SIGTRAP; + /* the 0x80 provides a way for the tracing parent to distinguish + between a syscall stop and SIGTRAP delivery */ + current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0); current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule(); diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c index febc592ae..d70e9e569 100644 --- a/arch/i386/kernel/semaphore.c +++ b/arch/i386/kernel/semaphore.c @@ -20,8 +20,8 @@ /* * Semaphores are implemented using a two-way counter: * The "count" variable is decremented for each process - * that tries to aquire the semaphore, while the "sleeping" - * variable is a count of such aquires. + * that tries to acquire the semaphore, while the "sleeping" + * variable is a count of such acquires. * * Notably, the inline "up()" and "down()" functions can * efficiently test if they need to do any extra work (up @@ -373,7 +373,7 @@ struct rw_semaphore *down_write_failed(struct rw_semaphore *sem) while (atomic_read(&sem->count) < 0) { set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (atomic_read(&sem->count) >= 0) - break; /* we must attempt to aquire or bias the lock */ + break; /* we must attempt to acquire or bias the lock */ schedule(); } diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index e765a0e94..7ac7fdb36 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -51,6 +51,10 @@ * Forward port AMD Duron errata T13 from 2.2.17pre * Dave Jones <davej@suse.de>, August 2000 * + * Forward port lots of fixes/improvements from 2.2.18pre + * Cyrix III, Pentium IV support. + * Dave Jones <davej@suse.de>, October 2000 + * */ /* @@ -137,6 +141,8 @@ extern int root_mountflags; extern char _text, _etext, _edata, _end; extern unsigned long cpu_khz; +static int disable_x86_serial_nr __initdata = 1; + /* * This is set up by the setup-routine at boot-time */ @@ -844,12 +850,6 @@ static int __init get_model_name(struct cpuinfo_x86 *c) { unsigned int n, dummy, *v; - /* - * Actually we must have cpuid or we could never have - * figured out that this was AMD/Cyrix/Transmeta - * from the vendor info :-). - */ - cpuid(0x80000000, &n, &dummy, &dummy, &dummy); if (n < 0x80000004) return 0; @@ -862,29 +862,45 @@ static int __init get_model_name(struct cpuinfo_x86 *c) return 1; } + +static void __init display_cacheinfo(struct cpuinfo_x86 *c) +{ + unsigned int n, dummy, ecx, edx; + + cpuid(0x80000000, &n, &dummy, &dummy, &dummy); + + if (n >= 0x80000005) { + cpuid(0x80000005, &dummy, &dummy, &ecx, &edx); + printk("CPU: L1 I Cache: %dK L1 D Cache: %dK (%d bytes/line)\n", + edx>>24, ecx>>24, edx&0xFF); + c->x86_cache_size=(ecx>>24)+(edx>>24); + } + + if (n < 0x80000006) /* Cyrix just has large L1. */ + return; + + cpuid(0x80000006, &dummy, &dummy, &ecx, &edx); + c->x86_cache_size = ecx >>16; + + /* AMD errata T13 (order #21922) */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 3 && + boot_cpu_data.x86_mask == 0) + { + c->x86_cache_size = 64; + } + printk("CPU: L2 Cache: %dK\n", ecx>>16); +} + + static int __init amd_model(struct cpuinfo_x86 *c) { u32 l, h; unsigned long flags; - unsigned int n, dummy, ecx, edx; int mbytes = max_mapnr >> (20-PAGE_SHIFT); int r=get_model_name(c); - /* - * Set MTRR capability flag if appropriate - */ - if(boot_cpu_data.x86 == 5) { - if((boot_cpu_data.x86_model == 13) || - (boot_cpu_data.x86_model == 9) || - ((boot_cpu_data.x86_model == 8) && - (boot_cpu_data.x86_mask >= 8))) - c->x86_capability |= X86_FEATURE_MTRR; - } - - /* - * Now do the cache operations. - */ switch(c->x86) { case 5: @@ -923,6 +939,7 @@ static int __init amd_model(struct cpuinfo_x86 *c) if(mbytes>4092) mbytes=4092; + rdmsr(0xC0000082, l, h); if((l&0xFFFF0000)==0) { @@ -935,35 +952,23 @@ static int __init amd_model(struct cpuinfo_x86 *c) printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n", mbytes); } + + /* Set MTRR capability flag if appropriate */ + if((boot_cpu_data.x86_model == 13) || + (boot_cpu_data.x86_model == 9) || + ((boot_cpu_data.x86_model == 8) && + (boot_cpu_data.x86_mask >= 8))) + c->x86_capability |= X86_FEATURE_MTRR; break; } + break; + case 6: /* An Athlon/Duron. We can trust the BIOS probably */ break; } - cpuid(0x80000000, &n, &dummy, &dummy, &dummy); - if (n >= 0x80000005) { - cpuid(0x80000005, &dummy, &dummy, &ecx, &edx); - printk("CPU: L1 I Cache: %dK L1 D Cache: %dK (%d bytes/line)\n", - edx>>24, ecx>>24, edx&0xFF); - c->x86_cache_size=(ecx>>24)+(edx>>24); - } - - /* AMD errata T13 (order #21922) */ - if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 3 && - boot_cpu_data.x86_mask == 0) - { - c->x86_cache_size = 64; - printk("CPU: L2 Cache: 64K\n"); - } else { - if (n >= 0x80000006) { - cpuid(0x80000006, &dummy, &dummy, &ecx, &edx); - printk("CPU: L2 Cache: %dK\n", ecx>>16); - c->x86_cache_size=(ecx>>16); - } - } - + display_cacheinfo(c); return r; } @@ -1097,9 +1102,8 @@ static void __init cyrix_model(struct cpuinfo_x86 *c) bug to do with 'hlt'. I've not seen any boards using VSA2 and X doesn't seem to support it either so who cares 8). VSA1 we work around however. - */ - + printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n"); isa_dma_bridge_buggy = 2; #endif @@ -1183,79 +1187,104 @@ static void __init centaur_model(struct cpuinfo_x86 *c) u32 lo,hi,newlo; u32 aa,bb,cc,dd; - switch(c->x86_model) { - case 4: - name="C6"; - fcr_set=ECX8|DSMC|EDCTLB|EMMX|ERETSTK; - fcr_clr=DPDC; - printk("Disabling bugged TSC.\n"); - c->x86_capability &= ~X86_FEATURE_TSC; - break; - case 8: - switch(c->x86_mask) { - default: - name="2"; - break; - case 7 ... 9: - name="2A"; - break; - case 10 ... 15: - name="2B"; + switch (c->x86) { + + case 5: + switch(c->x86_model) { + case 4: + name="C6"; + fcr_set=ECX8|DSMC|EDCTLB|EMMX|ERETSTK; + fcr_clr=DPDC; + printk("Disabling bugged TSC.\n"); + c->x86_capability &= ~X86_FEATURE_TSC; + break; + case 8: + switch(c->x86_mask) { + default: + name="2"; + break; + case 7 ... 9: + name="2A"; + break; + case 10 ... 15: + name="2B"; + break; + } + fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; + fcr_clr=DPDC; + break; + case 9: + name="3"; + fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; + fcr_clr=DPDC; + break; + case 10: + name="4"; + /* no info on the WC4 yet */ + break; + default: + name="??"; + } + + /* get FCR */ + rdmsr(0x107, lo, hi); + + newlo=(lo|fcr_set) & (~fcr_clr); + + if (newlo!=lo) { + printk("Centaur FCR was 0x%X now 0x%X\n", lo, newlo ); + wrmsr(0x107, newlo, hi ); + } else { + printk("Centaur FCR is 0x%X\n",lo); + } + /* Emulate MTRRs using Centaur's MCR. */ + c->x86_capability |= X86_FEATURE_MTRR; + /* Report CX8 */ + c->x86_capability |= X86_FEATURE_CX8; + /* Set 3DNow! on Winchip 2 and above. */ + if (c->x86_model >=8) + c->x86_capability |= X86_FEATURE_AMD3D; + /* See if we can find out some more. */ + cpuid(0x80000000,&aa,&bb,&cc,&dd); + if (aa>=0x80000005) { /* Yes, we can. */ + cpuid(0x80000005,&aa,&bb,&cc,&dd); + /* Add L1 data and code cache sizes. */ + c->x86_cache_size = (cc>>24)+(dd>>24); + } + sprintf( c->x86_model_id, "WinChip %s", name ); break; - } - fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; - fcr_clr=DPDC; - break; - case 9: - name="3"; - fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; - fcr_clr=DPDC; - break; - case 10: - name="4"; - /* no info on the WC4 yet */ - break; - default: - name="??"; - } - /* get FCR */ - rdmsr(0x107, lo, hi); + case 6: + switch (c->x86_model) { + case 6: /* Cyrix III */ + rdmsr (0x1107, lo, hi); + lo |= (1<<1 | 1<<7); /* Report CX8 & enable PGE */ + wrmsr (0x1107, lo, hi); - newlo=(lo|fcr_set) & (~fcr_clr); + c->x86_capability |= X86_FEATURE_CX8; + rdmsr (0x80000001, lo, hi); + if (hi & (1<<31)) + c->x86_capability |= X86_FEATURE_AMD3D; - if (newlo!=lo) { - printk("Centaur FCR was 0x%X now 0x%X\n", lo, newlo ); - wrmsr(0x107, newlo, hi ); - } else { - printk("Centaur FCR is 0x%X\n",lo); + get_model_name(c); + display_cacheinfo(c); + break; + } + break; } - /* Emulate MTRRs using Centaur's MCR. */ - c->x86_capability |= X86_FEATURE_MTRR; - /* Report CX8 */ - c->x86_capability |= X86_FEATURE_CX8; - /* Set 3DNow! on Winchip 2 and above. */ - if (c->x86_model >=8) - c->x86_capability |= X86_FEATURE_AMD3D; - /* See if we can find out some more. */ - cpuid(0x80000000,&aa,&bb,&cc,&dd); - if (aa>=0x80000005) { /* Yes, we can. */ - cpuid(0x80000005,&aa,&bb,&cc,&dd); - /* Add L1 data and code cache sizes. */ - c->x86_cache_size = (cc>>24)+(dd>>24); - } - sprintf( c->x86_model_id, "WinChip %s", name ); } + static void __init transmeta_model(struct cpuinfo_x86 *c) { - unsigned int cap_mask, uk, max, dummy, n, ecx, edx; + unsigned int cap_mask, uk, max, dummy; unsigned int cms_rev1, cms_rev2; unsigned int cpu_rev, cpu_freq, cpu_flags; char cpu_info[65]; get_model_name(c); /* Same as AMD/Cyrix */ + display_cacheinfo(c); /* Print CMS and CPU revision */ cpuid(0x80860000, &max, &dummy, &dummy, &dummy); @@ -1309,22 +1338,6 @@ static void __init transmeta_model(struct cpuinfo_x86 *c) wrmsr(0x80860004, ~0, uk); cpuid(0x00000001, &dummy, &dummy, &dummy, &c->x86_capability); wrmsr(0x80860004, cap_mask, uk); - - - /* L1/L2 cache */ - cpuid(0x80000000, &n, &dummy, &dummy, &dummy); - - if (n >= 0x80000005) { - cpuid(0x80000005, &dummy, &dummy, &ecx, &edx); - printk("CPU: L1 I Cache: %dK L1 D Cache: %dK\n", - ecx>>24, edx>>24); - c->x86_cache_size=(ecx>>24)+(edx>>24); - } - if (n >= 0x80000006) { - cpuid(0x80000006, &dummy, &dummy, &ecx, &edx); - printk("CPU: L2 Cache: %dK\n", ecx>>16); - c->x86_cache_size=(ecx>>16); - } } @@ -1407,7 +1420,7 @@ static struct cpu_model_info cpu_models[] __initdata = { * to have CPUID. (Thanks to Herbert Oppmann) */ -static int deep_magic_nexgen_probe(void) +static int __init deep_magic_nexgen_probe(void) { int ret; @@ -1424,9 +1437,9 @@ static int deep_magic_nexgen_probe(void) return ret; } -static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) +static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c) { - if(c->x86_capability&(1<<18)) { + if(c->x86_capability&(X86_FEATURE_PN) && disable_x86_serial_nr) { /* Disable processor serial number */ unsigned long lo,hi; rdmsr(0x119,lo,hi); @@ -1436,10 +1449,20 @@ static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) } } + +int __init x86_serial_nr_setup(char *s) +{ + disable_x86_serial_nr = 0; + return 1; +} +__setup("serialnumber", x86_serial_nr_setup); + + void __init identify_cpu(struct cpuinfo_x86 *c) { int i=0; char *p = NULL; + extern void mcheck_init(void); c->loops_per_sec = loops_per_sec; c->x86_cache_size = -1; @@ -1476,9 +1499,10 @@ void __init identify_cpu(struct cpuinfo_x86 *c) return; case X86_VENDOR_INTEL: - + squash_the_stupid_serial_number(c); - + mcheck_init(); + if (c->cpuid_level > 1) { /* supports eax=2 call */ int edx, dummy; @@ -1522,6 +1546,12 @@ void __init identify_cpu(struct cpuinfo_x86 *c) } } + /* Pentium IV. */ + if (c->x86 == 15) { + get_model_name(c); + return; + } + /* Names for the Pentium II/Celeron processors detectable only by also checking the cache size. Dixon is NOT a Celeron. */ @@ -1555,7 +1585,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) squash_the_stupid_serial_number(c); return; } - + /* may be changed in the switch so needs to be after */ if(c->x86_vendor == X86_VENDOR_NEXGEN) @@ -1658,12 +1688,12 @@ int get_cpuinfo(char * buffer) #endif p += sprintf(p,"processor\t: %d\n" "vendor_id\t: %s\n" - "cpu family\t: %c\n" + "cpu family\t: %d\n" "model\t\t: %d\n" "model name\t: %s\n", n, c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown", - c->x86 + '0', + c->x86, c->x86_model, c->x86_model_id[0] ? c->x86_model_id : "unknown"); diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 6ce9eb61e..f39e42522 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -422,7 +422,7 @@ struct call_data_struct { int wait; }; -static struct call_data_struct * call_data = NULL; +static struct call_data_struct * call_data; /* * this function sends a 'generic call function' IPI to all other CPUs diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 3a9df08e7..12ba21b92 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -76,7 +76,7 @@ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ * Equal to 2^32 * (1 / (clocks per usec) ). * Initialized in time_init. */ -unsigned long fast_gettimeoffset_quotient=0; +unsigned long fast_gettimeoffset_quotient; extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; @@ -373,9 +373,9 @@ static int set_rtc_mmss(unsigned long nowtime) } /* last time the cmos clock got updated */ -static long last_rtc_update = 0; +static long last_rtc_update; -int timer_ack = 0; +int timer_ack; /* * timer_interrupt() needs to keep up the real-time clock, @@ -449,7 +449,7 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg #endif } -static int use_tsc = 0; +static int use_tsc; /* * This is the same as the above, except we _also_ save the current diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 953c23d55..ae87ded92 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -741,11 +741,7 @@ asmlinkage void math_state_restore(struct pt_regs regs) if (current->used_math) { restore_fpu(current); } else { - /* - * Our first FPU usage, clean the chip. - */ - __asm__("fninit"); - current->used_math = 1; + init_fpu(); } current->flags |= PF_USEDFPU; /* So we fnsave on switch_to() */ } diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index b88c4a422..946d1f40a 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -77,31 +77,6 @@ bad_area: return 0; } -static void __init handle_wp_test (void) -{ - const unsigned long vaddr = PAGE_OFFSET; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - /* - * make it read/writable temporarily, so that the fault - * can be handled. - */ - pgd = swapper_pg_dir + __pgd_offset(vaddr); - pmd = pmd_offset(pgd, vaddr); - pte = pte_offset(pmd, vaddr); - *pte = mk_pte_phys(0, PAGE_KERNEL); - __flush_tlb_all(); - - boot_cpu_data.wp_works_ok = 1; - /* - * Beware: Black magic here. The printk is needed here to flush - * CPU state on certain buggy processors. - */ - printk("Ok"); -} - asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); extern unsigned long idt; @@ -130,6 +105,19 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) __asm__("movl %%cr2,%0":"=r" (address)); tsk = current; + + /* + * We fault-in kernel-space virtual memory on-demand. The + * 'reference' page table is init_mm.pgd. + * + * NOTE! We MUST NOT take any locks for this case. We may + * be in an interrupt or a critical region, and should + * only copy the information from the master page table, + * nothing more. + */ + if (address >= TASK_SIZE) + goto vmalloc_fault; + mm = tsk->mm; info.si_code = SEGV_MAPERR; @@ -223,6 +211,7 @@ good_area: bad_area: up(&mm->mmap_sem); +bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (error_code & 4) { tsk->thread.cr2 = address; @@ -260,14 +249,7 @@ no_context: /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. - * - * First we check if it was the bootup rw-test, though.. */ - if (boot_cpu_data.wp_works_ok < 0 && - address == PAGE_OFFSET && (error_code & 1)) { - handle_wp_test(); - return; - } if (address < PAGE_SIZE) printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); @@ -318,4 +300,34 @@ do_sigbus: /* Kernel mode? Handle exceptions or die */ if (!(error_code & 4)) goto no_context; + return; + +vmalloc_fault: + { + /* + * Synchronize this task's top level page-table + * with the 'reference' page table. + */ + int offset = __pgd_offset(address); + pgd_t *pgd, *pgd_k; + pmd_t *pmd, *pmd_k; + + pgd = tsk->active_mm->pgd + 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; + } + + pmd = pmd_offset(pgd, address); + pmd_k = pmd_offset(pgd_k, address); + + if (pmd_present(*pmd) || !pmd_present(*pmd_k)) + goto bad_area_nosemaphore; + set_pmd(pmd, *pmd_k); + return; + } } diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 9ba2baa31..39a6ce0f8 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -37,8 +37,8 @@ #include <asm/apic.h> unsigned long highstart_pfn, highend_pfn; -static unsigned long totalram_pages = 0; -static unsigned long totalhigh_pages = 0; +static unsigned long totalram_pages; +static unsigned long totalhigh_pages; /* * BAD_PAGE is the page that is used for page faults when linux @@ -491,16 +491,21 @@ void __init paging_init(void) * before and after the test are here to work-around some nasty CPU bugs. */ +/* + * This function cannot be __init, since exceptions don't work in that + * section. + */ +static int do_test_wp_bit(unsigned long vaddr); + void __init test_wp_bit(void) { /* - * Ok, all PAE-capable CPUs are definitely handling the WP bit right. + * Ok, all PSE-capable CPUs are definitely handling the WP bit right. */ const unsigned long vaddr = PAGE_OFFSET; pgd_t *pgd; pmd_t *pmd; pte_t *pte, old_pte; - char tmp_reg; printk("Checking if this processor honours the WP bit even in supervisor mode... "); @@ -511,27 +516,19 @@ void __init test_wp_bit(void) *pte = mk_pte_phys(0, PAGE_READONLY); local_flush_tlb(); - __asm__ __volatile__( - "jmp 1f; 1:\n" - "movb %0,%1\n" - "movb %1,%0\n" - "jmp 1f; 1:\n" - :"=m" (*(char *) vaddr), - "=q" (tmp_reg) - :/* no inputs */ - :"memory"); + boot_cpu_data.wp_works_ok = do_test_wp_bit(vaddr); *pte = old_pte; local_flush_tlb(); - if (boot_cpu_data.wp_works_ok < 0) { - boot_cpu_data.wp_works_ok = 0; + if (!boot_cpu_data.wp_works_ok) { printk("No.\n"); #ifdef CONFIG_X86_WP_WORKS_OK panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!"); #endif - } else - printk(".\n"); + } else { + printk("Ok.\n"); + } } static inline int page_is_ram (unsigned long pagenr) @@ -634,6 +631,30 @@ void __init mem_init(void) } +/* Put this after the callers, so that it cannot be inlined */ +static int do_test_wp_bit(unsigned long vaddr) +{ + char tmp_reg; + int flag; + + __asm__ __volatile__( + " movb %0,%1 \n" + "1: movb %1,%0 \n" + " xorl %2,%2 \n" + "2: \n" + ".section __ex_table,\"a\"\n" + " .align 4 \n" + " .long 1b,2b \n" + ".previous \n" + :"=m" (*(char *) vaddr), + "=q" (tmp_reg), + "=r" (flag) + :"2" (1) + :"memory"); + + return flag; +} + void free_initmem(void) { unsigned long addr; diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index 66f846925..bb72da8c8 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -78,7 +78,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, if (remap_area_pmd(pmd, address, end - address, phys_addr + address, flags)) return -ENOMEM; - set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index d542d1487..0a1714c35 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -14,13 +14,18 @@ AWK := awk export AWK LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds -AFLAGS += -Wa,-x +AFLAGS += -Wa,-x +AFLAGS_KERNEL := -mconstant-gp EXTRA = CFLAGS := $(CFLAGS) -pipe $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-range=f10-f15,f32-f127 \ -funwind-tables CFLAGS_KERNEL := -mconstant-gp +ifeq ($(CONFIG_ITANIUM_ASTEP_SPECIFIC),y) + CFLAGS += -ma-step +endif + ifdef CONFIG_IA64_GENERIC CORE_FILES := arch/$(ARCH)/hp/hp.a \ arch/$(ARCH)/sn/sn.a \ @@ -41,11 +46,18 @@ ifdef CONFIG_IA64_HP_SIM $(CORE_FILES) endif -ifdef CONFIG_IA64_SGI_SN1_SIM +ifdef CONFIG_IA64_SGI_SN1 +CFLAGS := $(CFLAGS) -DSN -I. -DBRINGUP -DDIRECT_L1_CONSOLE \ + -DNUMA_BASE -DSIMULATED_KLGRAPH -DNUMA_MIGR_CONTROL \ + -DLITTLE_ENDIAN -DREAL_HARDWARE -DLANGUAGE_C=1 \ + -D_LANGUAGE_C=1 SUBDIRS := arch/$(ARCH)/sn/sn1 \ arch/$(ARCH)/sn \ + arch/$(ARCH)/sn/io \ + arch/$(ARCH)/sn/fprom \ $(SUBDIRS) CORE_FILES := arch/$(ARCH)/sn/sn.a \ + arch/$(ARCH)/sn/io/sgiio.o\ $(CORE_FILES) endif diff --git a/arch/ia64/boot/bootloader.c b/arch/ia64/boot/bootloader.c index b73f396dc..5d1778ee3 100644 --- a/arch/ia64/boot/bootloader.c +++ b/arch/ia64/boot/bootloader.c @@ -68,15 +68,16 @@ cons_write (const char *buf) void enter_virtual_mode (unsigned long new_psr) { + long tmp; + + asm volatile ("movl %0=1f" : "=r"(tmp)); asm volatile ("mov cr.ipsr=%0" :: "r"(new_psr)); - asm volatile ("mov cr.iip=%0" :: "r"(&&target)); + asm volatile ("mov cr.iip=%0" :: "r"(tmp)); asm volatile ("mov cr.ifs=r0"); - asm volatile ("rfi;;"); /* must be last insn in an insn group */ - - target: + asm volatile ("rfi;;"); + asm volatile ("1:"); } - #define MAX_ARGS 32 void @@ -96,7 +97,7 @@ _start (void) char *kpath, *args; long arglen = 0; - asm volatile ("movl gp=__gp" ::: "memory"); + asm volatile ("movl gp=__gp;;" ::: "memory"); asm volatile ("mov sp=%0" :: "r"(stack) : "memory"); asm volatile ("bsw.1;;"); #ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC diff --git a/arch/ia64/config.in b/arch/ia64/config.in index 97d622276..33bf47a44 100644 --- a/arch/ia64/config.in +++ b/arch/ia64/config.in @@ -27,7 +27,7 @@ choice 'IA-64 system type' \ "generic CONFIG_IA64_GENERIC \ DIG-compliant CONFIG_IA64_DIG \ HP-simulator CONFIG_IA64_HP_SIM \ - SN1-simulator CONFIG_IA64_SGI_SN1_SIM" generic + SGI-SN1 CONFIG_IA64_SGI_SN1" generic choice 'Kernel page size' \ "4KB CONFIG_IA64_PAGE_SIZE_4KB \ @@ -51,11 +51,30 @@ if [ "$CONFIG_IA64_DIG" = "y" ]; then bool ' Enable SoftSDV hacks' CONFIG_IA64_SOFTSDV_HACKS bool ' Enable AzusA hacks' CONFIG_IA64_AZUSA_HACKS bool ' Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA + bool ' Force socket buffers below 4GB?' CONFIG_SKB_BELOW_4GB + + bool ' ACPI kernel configuration manager (EXPERIMENTAL)' CONFIG_ACPI_KERNEL_CONFIG + if [ "$CONFIG_ACPI_KERNEL_CONFIG" = "y" ]; then + define_bool CONFIG_PM y + define_bool CONFIG_ACPI y + define_bool CONFIG_ACPI_INTERPRETER y + fi fi -if [ "$CONFIG_IA64_SGI_SN1_SIM" = "y" ]; then - define_bool CONFIG_NUMA y - define_bool CONFIG_IA64_SOFTSDV_HACKS y +if [ "$CONFIG_IA64_SGI_SN1" = "y" ]; then + bool ' Enable use of global TLB purge instruction (ptc.g)' CONFIG_ITANIUM_PTCG + bool ' Enable Itanium B-step specific code' CONFIG_ITANIUM_BSTEP_SPECIFIC + if [ "$CONFIG_ITANIUM_BSTEP_SPECIFIC" = "y" ]; then + bool ' Enable Itanium B0-step specific code' CONFIG_ITANIUM_B0_SPECIFIC + fi + bool ' Enable SGI Medusa Simulator Support' CONFIG_IA64_SGI_SN1_SIM n + bool ' Enable SGI hack for version 1.0 syngery bugs' CONFIG_IA64_SGI_SYNERGY_1_0_HACKS n + define_bool CONFIG_DEVFS_DEBUG y + define_bool CONFIG_DEVFS_FS y + define_bool CONFIG_IA64_BRL_EMU y + define_bool CONFIG_IA64_MCA y + define_bool CONFIG_IA64_SGI_IO y + define_bool CONFIG_ITANIUM y fi define_bool CONFIG_KCORE_ELF y # On IA-64, we always want an ELF /proc/kcore. @@ -161,6 +180,10 @@ endmenu fi # !HP_SIM +# +# input before char - char/joystick depends on it. As does USB. +# +source drivers/input/Config.in source drivers/char/Config.in #source drivers/misc/Config.in @@ -192,7 +215,6 @@ fi endmenu source drivers/usb/Config.in -source drivers/input/Config.in fi # !HP_SIM @@ -226,5 +248,6 @@ bool 'Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXC bool 'Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ bool 'Print possible IA64 hazards to console' CONFIG_IA64_PRINT_HAZARDS bool 'Enable new unwind support' CONFIG_IA64_NEW_UNWIND +bool 'Disable VHPT' CONFIG_DISABLE_VHPT endmenu diff --git a/arch/ia64/dig/iosapic.c b/arch/ia64/dig/iosapic.c index 7d9a084fd..18c7713bd 100644 --- a/arch/ia64/dig/iosapic.c +++ b/arch/ia64/dig/iosapic.c @@ -31,6 +31,10 @@ #include <asm/ptrace.h> #include <asm/system.h> +#ifdef CONFIG_ACPI_KERNEL_CONFIG +# include <asm/acpikcfg.h> +#endif + #undef DEBUG_IRQ_ROUTING static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; @@ -228,7 +232,7 @@ iosapic_init (unsigned long address, int irqbase) { struct hw_interrupt_type *irq_type; struct pci_vector_struct *vectors; - int i, irq; + int i, irq, num_pci_vectors; if (irqbase == 0) /* @@ -255,9 +259,14 @@ iosapic_init (unsigned long address, int irqbase) * Map the PCI Interrupt data into the ACPI IOSAPIC data using * the info that the bootstrap loader passed to us. */ +# ifdef CONFIG_ACPI_KERNEL_CONFIG + acpi_cf_get_pci_vectors(&vectors, &num_pci_vectors); +# else ia64_boot_param.pci_vectors = (__u64) __va(ia64_boot_param.pci_vectors); vectors = (struct pci_vector_struct *) ia64_boot_param.pci_vectors; - for (i = 0; i < ia64_boot_param.num_pci_vectors; i++) { + num_pci_vectors = ia64_boot_param.num_pci_vectors; +# endif + for (i = 0; i < num_pci_vectors; i++) { irq = vectors[i].irq; if (irq < 16) irq = isa_irq_to_vector(irq); @@ -277,11 +286,11 @@ iosapic_init (unsigned long address, int irqbase) iosapic_trigger(irq) = IO_SAPIC_LEVEL; iosapic_polarity(irq) = IO_SAPIC_POL_LOW; -#ifdef DEBUG_IRQ_ROUTING +# ifdef DEBUG_IRQ_ROUTING printk("PCI: BUS %d Slot %x Pin %x IRQ %02x --> Vector %02x IOSAPIC Pin %d\n", vectors[i].bus, vectors[i].pci_id>>16, vectors[i].pin, vectors[i].irq, irq, iosapic_pin(irq)); -#endif +# endif } #endif /* CONFIG_IA64_SOFTSDV_HACKS */ @@ -377,7 +386,7 @@ dig_register_iosapic (acpi_entry_iosapic_t *iosapic) unsigned int ver, v; int l, max_pin; - ver = iosapic_version(iosapic->address); + ver = iosapic_version((unsigned long) ioremap(iosapic->address, 0)); max_pin = (ver >> 16) & 0xff; printk("IOSAPIC Version %x.%x: address 0x%lx IRQs 0x%x - 0x%x\n", diff --git a/arch/ia64/hp/hpsim_console.c b/arch/ia64/hp/hpsim_console.c index b97116cee..4f56dc829 100644 --- a/arch/ia64/hp/hpsim_console.c +++ b/arch/ia64/hp/hpsim_console.c @@ -28,17 +28,13 @@ static int simcons_wait_key (struct console *); static kdev_t simcons_console_device (struct console *); struct console hpsim_cons = { - "simcons", - simcons_write, /* write */ - NULL, /* read */ - simcons_console_device, /* device */ - simcons_wait_key, /* wait_key */ - NULL, /* unblank */ - simcons_init, /* setup */ - CON_PRINTBUFFER, /* flags */ - -1, /* index */ - 0, /* cflag */ - NULL /* next */ + name: "simcons", + write: simcons_write, + device: simcons_console_device, + wait_key: simcons_wait_key, + setup: simcons_init, + flags: CON_PRINTBUFFER, + index: -1, }; static int diff --git a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile index 4f3312c01..23ffbd0d9 100644 --- a/arch/ia64/ia32/Makefile +++ b/arch/ia64/ia32/Makefile @@ -3,9 +3,9 @@ # .S.s: - $(CPP) $(AFLAGS) -o $*.s $< + $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $< .S.o: - $(CC) $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< all: ia32.o diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c index 770ef6363..384747f8b 100644 --- a/arch/ia64/ia32/binfmt_elf32.c +++ b/arch/ia64/ia32/binfmt_elf32.c @@ -52,7 +52,7 @@ put_shared_page(struct task_struct * tsk, struct page *page, unsigned long addre pte_t * pte; if (page_count(page) != 1) - printk("mem_map disagrees with %p at %08lx\n", page, address); + printk("mem_map disagrees with %p at %08lx\n", (void *) page, address); pgd = pgd_offset(tsk->mm, address); pmd = pmd_alloc(pgd, address); if (!pmd) { @@ -120,6 +120,8 @@ void ia64_elf32_init(struct pt_regs *regs) : "r" ((ulong)IA32_FCR_DEFAULT)); __asm__("mov ar.fir = r0"); __asm__("mov ar.fdr = r0"); + __asm__("mov %0=ar.k0 ;;" : "=r" (current->thread.old_iob)); + __asm__("mov ar.k0=%0 ;;" :: "r"(IA32_IOBASE)); /* TSS */ __asm__("mov ar.k1 = %0" : /* no outputs */ diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c index 574c1937f..7b2a9f3ec 100644 --- a/arch/ia64/ia32/ia32_signal.c +++ b/arch/ia64/ia32/ia32_signal.c @@ -278,7 +278,7 @@ setup_frame_ia32(int sig, struct k_sigaction *ka, sigset_t *set, err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]); - if (_NSIG_WORDS > 1) { + if (_IA32_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask)); } @@ -310,7 +310,7 @@ setup_frame_ia32(int sig, struct k_sigaction *ka, sigset_t *set, #if 0 printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n", - current->comm, current->pid, sig, frame, regs->cr_iip, frame->pretcode); + current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode); #endif return 1; @@ -380,7 +380,7 @@ setup_rt_frame_ia32(int sig, struct k_sigaction *ka, siginfo_t *info, #if 0 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n", - current->comm, current->pid, frame, regs->cr_iip, frame->pretcode); + current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode); #endif return 1; diff --git a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c index ab5bebfe1..bc02579ae 100644 --- a/arch/ia64/ia32/ia32_support.c +++ b/arch/ia64/ia32/ia32_support.c @@ -42,6 +42,7 @@ ia32_save_state (struct thread_struct *thread) thread->csd = csd; thread->ssd = ssd; thread->tssd = tssd; + asm ("mov ar.k0=%0 ;;" :: "r"(thread->old_iob)); } void @@ -68,6 +69,8 @@ ia32_load_state (struct thread_struct *thread) "mov ar.k1=%7" :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr), "r"(csd), "r"(ssd), "r"(tssd)); + asm ("mov %0=ar.k0 ;;" : "=r"(thread->old_iob)); + asm ("mov ar.k0=%0 ;;" :: "r"(IA32_IOBASE)); } /* diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index a6bf4a8d8..0383741a0 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -75,11 +75,11 @@ nargs(unsigned int arg, char **ap) n = 0; do { err = get_user(addr, (int *)A(arg)); - if (IS_ERR(err)) + if (err) return err; if (ap) { /* no access_ok needed, we allocated */ err = __put_user((char *)A(addr), ap++); - if (IS_ERR(err)) + if (err) return err; } arg += sizeof(unsigned int); @@ -102,13 +102,14 @@ int stack) { struct pt_regs *regs = (struct pt_regs *)&stack; char **av, **ae; - int na, ne, r, len; + int na, ne, len; + long r; na = nargs(argv, NULL); - if (IS_ERR(na)) + if (na < 0) return(na); ne = nargs(envp, NULL); - if (IS_ERR(ne)) + if (ne < 0) return(ne); len = (na + ne + 2) * sizeof(*av); /* @@ -130,19 +131,19 @@ int stack) return (long)av; ae = av + na + 1; r = __put_user(0, (av + na)); - if (IS_ERR(r)) + if (r) goto out; r = __put_user(0, (ae + ne)); - if (IS_ERR(r)) + if (r) goto out; r = nargs(argv, av); - if (IS_ERR(r)) + if (r < 0) goto out; r = nargs(envp, ae); - if (IS_ERR(r)) + if (r < 0) goto out; r = sys_execve(filename, av, ae, regs); - if (IS_ERR(r)) + if (r < 0) out: sys_munmap((unsigned long) av, len); return(r); @@ -297,7 +298,7 @@ ia32_do_mmap (struct file *file, unsigned int addr, unsigned int len, unsigned i error = do_mmap(file, addr, len, prot, flags, poff); up(¤t->mm->mmap_sem); - if (!IS_ERR(error)) + if (!IS_ERR((void *) error)) error += offset - poff; } else { down(¤t->mm->mmap_sem); @@ -788,7 +789,8 @@ out: } static int -fillonedir32 (void * __buf, const char * name, int namlen, off_t offset, ino_t ino) +fillonedir32 (void * __buf, const char * name, int namlen, off_t offset, ino_t ino, + unsigned int d_type) { struct readdir32_callback * buf = (struct readdir32_callback *) __buf; struct old_linux32_dirent * dirent; @@ -2545,6 +2547,78 @@ sys32_ni_syscall(int dummy0, int dummy1, int dummy2, int dummy3, return(sys_ni_syscall()); } +/* + * The IA64 maps 4 I/O ports for each 4K page + */ +#define IOLEN ((65536 / 4) * 4096) + +asmlinkage long +sys_iopl (int level, long arg1, long arg2, long arg3) +{ + extern unsigned long ia64_iobase; + int fd; + struct file * file; + unsigned int old; + unsigned long addr; + mm_segment_t old_fs = get_fs (); + + if (level != 3) + return(-EINVAL); + /* Trying to gain more privileges? */ + __asm__ __volatile__("mov %0=ar.eflag ;;" : "=r"(old)); + if (level > ((old >> 12) & 3)) { + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + } + set_fs(KERNEL_DS); + fd = sys_open("/dev/mem", O_SYNC | O_RDWR, 0); + set_fs(old_fs); + if (fd < 0) + return fd; + file = fget(fd); + if (file == NULL) { + sys_close(fd); + return(-EFAULT); + } + + down(¤t->mm->mmap_sem); + lock_kernel(); + + addr = do_mmap_pgoff(file, IA32_IOBASE, + IOLEN, PROT_READ|PROT_WRITE, MAP_SHARED, + (ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT); + + unlock_kernel(); + up(¤t->mm->mmap_sem); + + if (addr >= 0) { + __asm__ __volatile__("mov ar.k0=%0 ;;" :: "r"(addr)); + old = (old & ~0x3000) | (level << 12); + __asm__ __volatile__("mov ar.eflag=%0 ;;" :: "r"(old)); + } + + fput(file); + sys_close(fd); + return 0; +} + +asmlinkage long +sys_ioperm (unsigned long from, unsigned long num, int on) +{ + + /* + * Since IA64 doesn't have permission bits we'd have to go to + * a lot of trouble to simulate them in software. There's + * no point, only trusted programs can make this call so we'll + * just turn it into an iopl call and let the process have + * access to all I/O ports. + * + * XXX proper ioperm() support should be emulated by + * manipulating the page protections... + */ + return(sys_iopl(3, 0, 0, 0)); +} + #ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */ /* In order to reduce some races, while at the same time doing additional diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 563c308ea..7a49511d3 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -3,9 +3,9 @@ # .S.s: - $(CPP) $(AFLAGS) -o $*.s $< + $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $< .S.o: - $(CC) $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< all: kernel.o head.o init_task.o @@ -16,7 +16,7 @@ obj-y := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt obj-$(CONFIG_IA64_GENERIC) += machvec.o obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SMP) += smp.o smpboot.o obj-$(CONFIG_IA64_MCA) += mca.o mca_asm.o obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 4bba56e1d..a8c1ead1f 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -24,18 +24,17 @@ #include <asm/iosapic.h> #include <asm/machvec.h> #include <asm/page.h> +#ifdef CONFIG_ACPI_KERNEL_CONFIG +# include <asm/acpikcfg.h> +#endif #undef ACPI_DEBUG /* Guess what this does? */ -#ifdef CONFIG_SMP -extern struct smp_boot_data smp; -#endif - /* These are ugly but will be reclaimed by the kernel */ -int __initdata available_cpus = 0; -int __initdata total_cpus = 0; +int __initdata available_cpus; +int __initdata total_cpus; -void (*pm_idle) (void); +void (*pm_idle)(void); /* * Identify usable CPU's and remember them for SMP bringup later. @@ -60,18 +59,16 @@ acpi_lsapic(char *p) add = 0; } +#ifdef CONFIG_SMP + smp_boot_data.cpu_phys_id[total_cpus] = -1; +#endif if (add) { printk("Available.\n"); available_cpus++; #ifdef CONFIG_SMP -# if LARGE_CPU_ID_OK - smp.cpu_map[total_cpus] = (lsapic->id << 8) | lsapic->eid; -# else - smp.cpu_map[total_cpus] = lsapic->id; -# endif -#endif + smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid; +#endif /* CONFIG_SMP */ } - total_cpus++; } @@ -139,13 +136,12 @@ acpi_legacy_irq(char *p) break; } -#if 1/*def ACPI_DEBUG*/ +# ifdef ACPI_DEBUG printk("Legacy ISA IRQ %x -> IA64 Vector %x IOSAPIC Pin %x Active %s %s Trigger\n", legacy->isa_irq, vector, iosapic_pin(vector), ((iosapic_polarity(vector) == IO_SAPIC_POL_LOW) ? "Low" : "High"), ((iosapic_trigger(vector) == IO_SAPIC_LEVEL) ? "Level" : "Edge")); -#endif /* ACPI_DEBUG */ - +# endif /* ACPI_DEBUG */ #endif /* CONFIG_IA64_IRQ_ACPI */ } @@ -172,10 +168,6 @@ acpi_parse_msapic(acpi_sapic_t *msapic) /* Base address of IPI Message Block */ ipi_base_addr = (unsigned long) ioremap(msapic->interrupt_block, 0); -#ifdef CONFIG_SMP - memset(&smp, -1, sizeof(smp)); -#endif - p = (char *) (msapic + 1); end = p + (msapic->header.length - sizeof(acpi_sapic_t)); @@ -248,6 +240,10 @@ acpi_parse(acpi_rsdp_t *rsdp) printk("ACPI: %.6s %.8s %d.%d\n", rsdt->header.oem_id, rsdt->header.oem_table_id, rsdt->header.oem_revision >> 16, rsdt->header.oem_revision & 0xffff); +#ifdef CONFIG_ACPI_KERNEL_CONFIG + acpi_cf_init(rsdp); +#endif + tables = (rsdt->header.length - sizeof(acpi_desc_table_hdr_t)) / 8; for (i = 0; i < tables; i++) { hdrp = (acpi_desc_table_hdr_t *) __va(rsdt->entry_ptrs[i]); @@ -259,12 +255,16 @@ acpi_parse(acpi_rsdp_t *rsdp) acpi_parse_msapic((acpi_sapic_t *) hdrp); } +#ifdef CONFIG_ACPI_KERNEL_CONFIG + acpi_cf_terminate(); +#endif + #ifdef CONFIG_SMP if (available_cpus == 0) { printk("ACPI: Found 0 CPUS; assuming 1\n"); available_cpus = 1; /* We've got at least one of these, no? */ } - smp.cpu_count = available_cpus; + smp_boot_data.cpu_count = available_cpus; #endif return 1; } @@ -278,7 +278,7 @@ acpi_get_sysname (void) #else # if defined (CONFIG_IA64_HP_SIM) return "hpsim"; -# elif defined (CONFIG_IA64_SGI_SN1_SIM) +# elif defined (CONFIG_IA64_SGI_SN1) return "sn1"; # elif defined (CONFIG_IA64_DIG) return "dig"; @@ -286,4 +286,4 @@ acpi_get_sysname (void) # error Unknown platform. Fix acpi.c. # endif #endif -} +} diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 32d83ae75..759db7f52 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -18,6 +18,7 @@ * Goutham Rao: <goutham.rao@intel.com> * Skip non-WB memory and ignore empty memory ranges. */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/types.h> @@ -216,12 +217,41 @@ efi_map_pal_code (void) md->phys_addr); continue; } - mask = ~((1 << _PAGE_SIZE_4M)-1); /* XXX should be dynamic? */ + /* + * We must use the same page size as the one used + * for the kernel region when we map the PAL code. + * This way, we avoid overlapping TRs if code is + * executed nearby. The Alt I-TLB installs 256MB + * page sizes as defined for region 7. + * + * XXX Fixme: should be dynamic here (for page size) + */ + mask = ~((1 << _PAGE_SIZE_256M)-1); vaddr = PAGE_OFFSET + md->phys_addr; - printk(__FUNCTION__": mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", - md->phys_addr, md->phys_addr + (md->num_pages << 12), - vaddr & mask, (vaddr & mask) + 4*1024*1024); + /* + * We must check that the PAL mapping won't overlap + * with the kernel mapping on ITR1. + * + * PAL code is guaranteed to be aligned on a power of 2 + * between 4k and 256KB. + * Also from the documentation, it seems like there is an + * implicit guarantee that you will need only ONE ITR to + * map it. This implies that the PAL code is always aligned + * on its size, i.e., the closest matching page size supported + * by the TLB. Therefore PAL code is guaranteed never to cross + * a 256MB unless it is bigger than 256MB (very unlikely!). + * So for now the following test is enough to determine whether + * or not we need a dedicated ITR for the PAL code. + */ + if ((vaddr & mask) == (PAGE_OFFSET & mask)) { + printk(__FUNCTION__ " : no need to install ITR for PAL Code\n"); + continue; + } + + printk("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 << 12), + vaddr & mask, (vaddr & mask) + 256*1024*1024); /* * Cannot write to CRx with PSR.ic=1 @@ -232,12 +262,11 @@ efi_map_pal_code (void) * ITR0/DTR0: used for kernel code/data * ITR1/DTR1: used by HP simulator * ITR2/DTR2: map PAL code - * ITR3/DTR3: used to map PAL calls buffer */ ia64_itr(0x1, 2, vaddr & mask, pte_val(mk_pte_phys(md->phys_addr, __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RX))), - _PAGE_SIZE_4M); + _PAGE_SIZE_256M); local_irq_restore(flags); ia64_srlz_i (); } @@ -348,6 +377,16 @@ efi_init (void) #endif efi_map_pal_code(); + +#ifndef CONFIG_IA64_SOFTSDV_HACKS + /* + * (Some) SoftSDVs seem to have a problem with this call. + * Since it's mostly a performance optimization, just don't do + * it for now... --davidm 99/12/6 + */ + efi_enter_virtual_mode(); +#endif + } void diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index eba75378e..ffb1760ea 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -120,6 +120,9 @@ GLOBAL_ENTRY(ia64_switch_to) mov r13=in0 // set "current" pointer ;; DO_LOAD_SWITCH_STACK( ) +#ifdef CONFIG_SMP + sync.i // ensure "fc"s done by this CPU are visible on other CPUs +#endif br.ret.sptk.few rp END(ia64_switch_to) @@ -1088,7 +1091,7 @@ sys_call_table: data8 sys_setpriority data8 sys_statfs data8 sys_fstatfs - data8 sys_ioperm // 1105 + data8 ia64_ni_syscall data8 sys_semget data8 sys_semop data8 sys_semctl diff --git a/arch/ia64/kernel/fw-emu.c b/arch/ia64/kernel/fw-emu.c index c34bbaeee..34316fe58 100644 --- a/arch/ia64/kernel/fw-emu.c +++ b/arch/ia64/kernel/fw-emu.c @@ -20,7 +20,7 @@ #define MB (1024*1024UL) -#define NUM_MEM_DESCS 3 +#define NUM_MEM_DESCS 2 static char fw_mem[( sizeof(efi_system_table_t) + sizeof(efi_runtime_services_t) @@ -453,6 +453,12 @@ sys_fw_init (const char *args, int arglen) md->num_pages = (1*MB) >> 12; /* 1MB (in 4KB pages) */ md->attribute = EFI_MEMORY_WB; +#if 0 + /* + * XXX bootmem is broken for now... (remember to NUM_MEM_DESCS + * if you re-enable this!) + */ + /* descriptor for high memory (>4GB): */ md = &efi_memmap[2]; md->type = EFI_CONVENTIONAL_MEMORY; @@ -461,6 +467,7 @@ sys_fw_init (const char *args, int arglen) md->virt_addr = 0; md->num_pages = (32*MB) >> 12; /* 32MB (in 4KB pages) */ md->attribute = EFI_MEMORY_WB; +#endif bp = id(ZERO_PAGE_ADDR); bp->efi_systab = __pa(&fw_mem); diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index bea14236d..e6298b297 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -111,7 +111,7 @@ GLOBAL_ENTRY(_start) * be implemented more efficiently (for example, __switch_to() * always sets the psr.dfh bit of the task it is switching to). */ - addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 + addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2 addl r2=IA64_RBS_OFFSET,r2 // initialize the RSE mov ar.rsc=r0 // place RSE in enforced lazy mode ;; diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 62e792612..d3d2416cf 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -10,6 +10,7 @@ EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(strcat); EXPORT_SYMBOL(strchr); EXPORT_SYMBOL(strcmp); @@ -18,6 +19,8 @@ EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strncat); EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strtok); @@ -27,24 +30,58 @@ EXPORT_SYMBOL(pci_free_consistent); #include <linux/in6.h> #include <asm/checksum.h> +/* not coded yet?? EXPORT_SYMBOL(csum_ipv6_magic); */ EXPORT_SYMBOL(csum_partial_copy_nocheck); +EXPORT_SYMBOL(csum_tcpudp_magic); +EXPORT_SYMBOL(ip_compute_csum); +EXPORT_SYMBOL(ip_fast_csum); + +#include <asm/io.h> +EXPORT_SYMBOL(__ia64_memcpy_fromio); +EXPORT_SYMBOL(__ia64_memcpy_toio); +EXPORT_SYMBOL(__ia64_memset_c_io); #include <asm/irq.h> EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(disable_irq_nosync); + +#include <asm/page.h> +EXPORT_SYMBOL(clear_page); + +#include <asm/pci.h> +EXPORT_SYMBOL(pci_dma_sync_sg); +EXPORT_SYMBOL(pci_dma_sync_single); +EXPORT_SYMBOL(pci_map_sg); +EXPORT_SYMBOL(pci_map_single); +EXPORT_SYMBOL(pci_unmap_sg); +EXPORT_SYMBOL(pci_unmap_single); #include <asm/processor.h> EXPORT_SYMBOL(cpu_data); EXPORT_SYMBOL(kernel_thread); +#include <asm/system.h> +#ifdef CONFIG_IA64_DEBUG_IRQ +EXPORT_SYMBOL(last_cli_ip); +#endif + #ifdef CONFIG_SMP + +#include <asm/current.h> #include <asm/hardirq.h> EXPORT_SYMBOL(synchronize_irq); +#include <asm/smp.h> +EXPORT_SYMBOL(smp_call_function); + +#include <linux/smp.h> +EXPORT_SYMBOL(smp_num_cpus); + #include <asm/smplock.h> EXPORT_SYMBOL(kernel_flag); -#include <asm/system.h> +/* #include <asm/system.h> */ EXPORT_SYMBOL(__global_sti); EXPORT_SYMBOL(__global_cli); EXPORT_SYMBOL(__global_save_flags); @@ -54,17 +91,29 @@ EXPORT_SYMBOL(__global_restore_flags); #include <asm/uaccess.h> EXPORT_SYMBOL(__copy_user); +EXPORT_SYMBOL(__do_clear_user); #include <asm/unistd.h> EXPORT_SYMBOL(__ia64_syscall); /* from arch/ia64/lib */ +extern void __divsi3(void); +extern void __udivsi3(void); +extern void __modsi3(void); +extern void __umodsi3(void); extern void __divdi3(void); extern void __udivdi3(void); extern void __moddi3(void); extern void __umoddi3(void); +EXPORT_SYMBOL_NOVERS(__divsi3); +EXPORT_SYMBOL_NOVERS(__udivsi3); +EXPORT_SYMBOL_NOVERS(__modsi3); +EXPORT_SYMBOL_NOVERS(__umodsi3); EXPORT_SYMBOL_NOVERS(__divdi3); EXPORT_SYMBOL_NOVERS(__udivdi3); EXPORT_SYMBOL_NOVERS(__moddi3); EXPORT_SYMBOL_NOVERS(__umoddi3); + +extern unsigned long ia64_iobase; +EXPORT_SYMBOL(ia64_iobase); diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index c913fdc3d..30d4def40 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -536,8 +536,7 @@ void enable_irq(unsigned int irq) desc->depth--; break; case 0: - printk("enable_irq() unbalanced from %p\n", - __builtin_return_address(0)); + printk("enable_irq() unbalanced from %p\n", (void *) __builtin_return_address(0)); } spin_unlock_irqrestore(&desc->lock, flags); } diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index fe686db0e..2166e205f 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -39,7 +39,8 @@ spinlock_t ivr_read_lock; #endif -unsigned long ipi_base_addr = IPI_DEFAULT_BASE_ADDR; /* default base addr of IPI table */ +/* default base addr of IPI table */ +unsigned long ipi_base_addr = (__IA64_UNCACHED_OFFSET | IPI_DEFAULT_BASE_ADDR); /* * Legacy IRQ to IA-64 vector translation table. Any vector not in @@ -220,13 +221,23 @@ ipi_send (int cpu, int vector, int delivery_mode, int redirect) { unsigned long ipi_addr; unsigned long ipi_data; + unsigned long phys_cpu_id; #ifdef CONFIG_ITANIUM_A1_SPECIFIC unsigned long flags; #endif -# define EID 0 + +#ifdef CONFIG_SMP + phys_cpu_id = cpu_physical_id(cpu); +#else + phys_cpu_id = (ia64_get_lid() >> 16) & 0xffff; +#endif + + /* + * cpu number is in 8bit ID and 8bit EID + */ ipi_data = (delivery_mode << 8) | (vector & 0xff); - ipi_addr = ipi_base_addr | ((cpu << 8 | EID) << 4) | ((redirect & 1) << 3); + ipi_addr = ipi_base_addr | (phys_cpu_id << 4) | ((redirect & 1) << 3); #ifdef CONFIG_ITANIUM_A1_SPECIFIC spin_lock_irqsave(&ivr_read_lock, flags); diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index d1b599f77..fa0ad0993 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -4,6 +4,8 @@ * Copyright (C) 1998-2000 Hewlett-Packard Co * Copyright (C) 1998, 1999 Stephane Eranian <eranian@hpl.hp.com> * Copyright (C) 1998-2000 David Mosberger <davidm@hpl.hp.com> + * + * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP */ /* * This file defines the interrupt vector table used by the CPU. @@ -134,32 +136,51 @@ ia64_ivt: (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry ;; -(p7) ld8 r17=[r17] // fetch the L2 entry (may be 0) +(p7) ld8 r20=[r17] // fetch the L2 entry (may be 0) shr.u r19=r16,PAGE_SHIFT // shift L3 index into position ;; -(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL? - dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry +(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 ;; -(p7) ld8 r18=[r17] // read the L3 PTE +(p7) ld8 r18=[r21] // read the L3 PTE mov r19=cr.isr // cr.isr bit 0 tells us if this is an insn miss ;; (p7) tbit.z p6,p7=r18,0 // page present bit cleared? - mov r21=cr.iha // get the VHPT address that caused the TLB miss + mov r22=cr.iha // get the VHPT address that caused the TLB miss ;; // avoid RAW on p7 (p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss? - dep r17=0,r17,0,PAGE_SHIFT // clear low bits to get page address + dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address ;; (p10) itc.i r18 // insert the instruction TLB entry (p11) itc.d r18 // insert the data TLB entry (p6) br.spnt.few page_fault // handle bad address/page not present (page fault) - mov cr.ifa=r21 + mov cr.ifa=r22 // 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 bit. - adds r16=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r17 + adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23 + ;; +(p7) itc.d r24 + ;; +#ifdef CONFIG_SMP + // + // Re-check L2 and L3 pagetable. If they changed, we may have received + // a ptc.g between reading the pagetable and the "itc". If so, + // flush the entry we inserted and retry. + // + ld8 r25=[r21] // read L3 PTE again + ld8 r26=[r17] // read L2 entry again + ;; + cmp.ne p6,p7=r26,r20 // did L2 entry change + mov r27=PAGE_SHIFT<<2 + ;; +(p6) ptc.l r22,r27 // purge PTE page translation +(p7) cmp.ne.or.andcm p6,p7=r25,r18 // did L3 PTE change ;; -(p7) itc.d r16 +(p6) ptc.l r16,r27 // purge translation +#endif + mov pr=r31,-1 // restore predicate registers rfi @@ -175,22 +196,32 @@ ia64_ivt: * The speculative access will fail if there is no TLB entry * for the L3 page table page we're trying to access. */ - mov r16=cr.iha // get virtual address of L3 PTE + mov r16=cr.ifa // get virtual address + mov r19=cr.iha // get virtual address of L3 PTE ;; - ld8.s r16=[r16] // try to read L3 PTE + ld8.s r17=[r19] // try to read L3 PTE mov r31=pr // save predicates ;; - tnat.nz p6,p0=r16 // did read succeed? + tnat.nz p6,p0=r17 // did read succeed? (p6) br.cond.spnt.many 1f ;; - itc.i r16 + itc.i r17 + ;; +#ifdef CONFIG_SMP + ld8.s r18=[r19] // try to read L3 PTE again and see if same + mov r20=PAGE_SHIFT<<2 // setup page size for purge ;; + cmp.eq p6,p7=r17,r18 + ;; +(p7) ptc.l r16,r20 +#endif mov pr=r31,-1 rfi -1: mov r16=cr.ifa // get address that caused the TLB miss - ;; - rsm psr.dt // use physical addressing for data +#ifdef CONFIG_DISABLE_VHPT +itlb_fault: +#endif +1: rsm psr.dt // use physical addressing for data mov r19=ar.k7 // get page table base address shl r21=r16,3 // shift bit 60 into sign bit shr.u r17=r16,61 // get the region number into r17 @@ -228,6 +259,15 @@ ia64_ivt: (p7) itc.i r18 // insert the instruction TLB entry (p6) br.spnt.few page_fault // handle bad address/page not present (page fault) ;; +#ifdef CONFIG_SMP + ld8 r19=[r17] // re-read the PTE and check if same + ;; + cmp.eq p6,p7=r18,r19 + mov r20=PAGE_SHIFT<<2 + ;; +(p7) ptc.l r16,r20 // PTE changed purge translation +#endif + mov pr=r31,-1 // restore predicate registers rfi @@ -243,22 +283,32 @@ ia64_ivt: * The speculative access will fail if there is no TLB entry * for the L3 page table page we're trying to access. */ - mov r16=cr.iha // get virtual address of L3 PTE + mov r16=cr.ifa // get virtual address + mov r19=cr.iha // get virtual address of L3 PTE ;; - ld8.s r16=[r16] // try to read L3 PTE + ld8.s r17=[r19] // try to read L3 PTE mov r31=pr // save predicates ;; - tnat.nz p6,p0=r16 // did read succeed? + tnat.nz p6,p0=r17 // did read succeed? (p6) br.cond.spnt.many 1f ;; - itc.d r16 + itc.d r17 + ;; +#ifdef CONFIG_SMP + ld8.s r18=[r19] // try to read L3 PTE again and see if same + mov r20=PAGE_SHIFT<<2 // setup page size for purge ;; + cmp.eq p6,p7=r17,r18 + ;; +(p7) ptc.l r16,r20 +#endif mov pr=r31,-1 rfi -1: mov r16=cr.ifa // get address that caused the TLB miss - ;; - rsm psr.dt // use physical addressing for data +#ifdef CONFIG_DISABLE_VHPT +dtlb_fault: +#endif +1: rsm psr.dt // use physical addressing for data mov r19=ar.k7 // get page table base address shl r21=r16,3 // shift bit 60 into sign bit shr.u r17=r16,61 // get the region number into r17 @@ -296,6 +346,14 @@ ia64_ivt: (p7) itc.d r18 // insert the instruction TLB entry (p6) br.spnt.few page_fault // handle bad address/page not present (page fault) ;; +#ifdef CONFIG_SMP + ld8 r19=[r17] // re-read the PTE and check if same + ;; + cmp.eq p6,p7=r18,r19 + mov r20=PAGE_SHIFT<<2 + ;; +(p7) ptc.l r16,r20 // PTE changed purge translation +#endif mov pr=r31,-1 // restore predicate registers rfi @@ -303,6 +361,16 @@ ia64_ivt: ///////////////////////////////////////////////////////////////////////////////////////// // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) mov r16=cr.ifa // get address that caused the TLB miss +#ifdef CONFIG_DISABLE_VHPT + mov r31=pr + ;; + shr.u r21=r16,61 // get the region number into r21 + ;; + cmp.gt p6,p0=6,r21 // user mode +(p6) br.cond.dptk.many itlb_fault + ;; + mov pr=r31,-1 +#endif movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RX ;; shr.u r18=r16,57 // move address bit 61 to bit 4 @@ -323,8 +391,14 @@ ia64_ivt: movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RW mov r20=cr.isr mov r21=cr.ipsr - mov r19=pr + mov r31=pr + ;; +#ifdef CONFIG_DISABLE_VHPT + shr.u r22=r16,61 // get the region number into r21 ;; + cmp.gt p8,p0=6,r22 // user mode +(p8) br.cond.dptk.many dtlb_fault +#endif tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on? shr.u r18=r16,57 // move address bit 61 to bit 4 dep r16=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS) // clear ed & reserved bits @@ -337,7 +411,7 @@ ia64_ivt: (p6) mov cr.ipsr=r21 ;; (p7) itc.d r16 // insert the TLB entry - mov pr=r19,-1 + mov pr=r31,-1 rfi ;; @@ -452,6 +526,7 @@ page_fault: // a nested TLB miss hit where we look up the physical address of the L3 PTE // and then continue at label 1 below. // +#ifndef CONFIG_SMP mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault ;; @@ -465,6 +540,36 @@ page_fault: ;; st8 [r17]=r18 // store back updated PTE itc.d r18 // install updated PTE +#else + mov r16=cr.ifa // get the address that caused the fault + movl r30=1f // load continuation point in case of nested fault + ;; + thash r17=r16 // compute virtual address of L3 PTE + mov r28=ar.ccv // save ar.ccv + mov r29=b0 // save b0 in case of nested fault + mov r27=pr + ;; +1: ld8 r18=[r17] + ;; // avoid RAW on r18 + mov ar.ccv=r18 // set compare value for cmpxchg + or r25=_PAGE_D,r18 // set the dirty bit + ;; + cmpxchg8.acq r26=[r17],r25,ar.ccv + mov r24=PAGE_SHIFT<<2 + ;; + cmp.eq p6,p7=r26,r18 + ;; +(p6) itc.d r25 // install updated PTE + ;; + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov b0=r29 // restore b0 + mov ar.ccv=r28 + mov pr=r27,-1 +#endif rfi .align 1024 @@ -486,6 +591,8 @@ page_fault: (p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa mov pr=r31,-1 #endif /* CONFIG_ITANIUM */ + +#ifndef CONFIG_SMP movl r30=1f // load continuation point in case of nested fault ;; thash r17=r16 // compute virtual address of L3 PTE @@ -515,12 +622,58 @@ page_fault: ;; st8 [r17]=r18 // store back updated PTE itc.i r18 // install updated PTE +#else + movl r30=1f // load continuation point in case of nested fault + ;; + thash r17=r16 // compute virtual address of L3 PTE + mov r28=ar.ccv // save ar.ccv + mov r29=b0 // save b0 in case of nested fault) + mov r27=pr + ;; +1: ld8 r18=[r17] +#if defined(CONFIG_IA32_SUPPORT) && \ + (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_B0_SPECIFIC)) + // + // Erratum 85 (Access bit fault could be reported before page not present fault) + // If the PTE is indicates the page is not present, then just turn this into a + // page fault. + // + ;; + tbit.nz p6,p0=r18,0 // page present bit set? +(p6) br.cond.sptk 1f + ;; // avoid WAW on p6 + mov pr=r27,-1 + br.cond.sptk page_fault // page wasn't present +1: +#else + ;; // avoid RAW on r18 +#endif + mov ar.ccv=r18 // set compare value for cmpxchg + or r25=_PAGE_A,r18 // set the accessed bit + ;; + cmpxchg8.acq r26=[r17],r25,ar.ccv + mov r24=PAGE_SHIFT<<2 + ;; + cmp.eq p6,p7=r26,r18 + ;; +(p6) itc.i r25 // install updated PTE + ;; + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov b0=r29 // restore b0 + mov ar.ccv=r28 + mov pr=r27,-1 +#endif rfi .align 1024 ///////////////////////////////////////////////////////////////////////////////////////// // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) // Like Entry 8, except for data access +#ifndef CONFIG_SMP mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault ;; @@ -534,6 +687,36 @@ page_fault: ;; st8 [r17]=r18 // store back updated PTE itc.d r18 // install updated PTE +#else + mov r16=cr.ifa // get the address that caused the fault + movl r30=1f // load continuation point in case of nested fault + ;; + thash r17=r16 // compute virtual address of L3 PTE + mov r28=ar.ccv // save ar.ccv + mov r29=b0 // save b0 in case of nested fault + mov r27=pr + ;; +1: ld8 r18=[r17] + ;; // avoid RAW on r18 + mov ar.ccv=r18 // set compare value for cmpxchg + or r25=_PAGE_A,r18 // set the dirty bit + ;; + cmpxchg8.acq r26=[r17],r25,ar.ccv + mov r24=PAGE_SHIFT<<2 + ;; + cmp.eq p6,p7=r26,r18 + ;; +(p6) itc.d r25 // install updated PTE + ;; + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov b0=r29 // restore b0 + mov ar.ccv=r28 + mov pr=r27,-1 +#endif rfi .align 1024 diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index b57d4702d..333258d35 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -43,10 +43,6 @@ u64 ia64_mca_stackframe[32]; u64 ia64_mca_bspstore[1024]; u64 ia64_init_stack[INIT_TASK_SIZE] __attribute__((aligned(16))); -#if defined(SAL_MPINIT_WORKAROUND) && !defined(CONFIG_SMP) -int bootstrap_processor = -1; -#endif - static void ia64_mca_cmc_vector_setup(int enable, int_vector_t cmc_vector); static void ia64_mca_wakeup_ipi_wait(void); @@ -223,12 +219,6 @@ ia64_mca_init(void) IA64_MCA_DEBUG("ia64_mca_init : begin\n"); -#if defined(SAL_MPINIT_WORKAROUND) && !defined(CONFIG_SMP) - /* XXX -- workaround for SAL bug for running on MP system, but UP kernel */ - - bootstrap_processor = hard_smp_processor_id(); -#endif - /* Clear the Rendez checkin flag for all cpus */ for(i = 0 ; i < IA64_MAXCPUS; i++) ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; @@ -265,8 +255,11 @@ ia64_mca_init(void) IA64_MCA_DEBUG("ia64_mca_init : correctable mca vector setup done\n"); ia64_mc_info.imi_mca_handler = __pa(ia64_os_mca_dispatch); - ia64_mc_info.imi_mca_handler_size = - __pa(ia64_os_mca_dispatch_end) - __pa(ia64_os_mca_dispatch); + /* + * 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 (ia64_sal_set_vectors(SAL_VECTOR_OS_MCA, ia64_mc_info.imi_mca_handler, @@ -278,10 +271,14 @@ ia64_mca_init(void) IA64_MCA_DEBUG("ia64_mca_init : registered os mca handler with SAL\n"); + /* + * 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 = IA64_INIT_HANDLER_SIZE; + 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 = IA64_INIT_HANDLER_SIZE; + 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); @@ -386,7 +383,7 @@ ia64_mca_wakeup_all(void) int cpu; /* Clear the Rendez checkin flag for all cpus */ - for(cpu = 0 ; cpu < IA64_MAXCPUS; cpu++) + for(cpu = 0 ; cpu < smp_num_cpus; cpu++) if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE) ia64_mca_wakeup(cpu); @@ -404,11 +401,14 @@ ia64_mca_wakeup_all(void) void ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) { - int flags; + int flags, cpu = 0; /* Mask all interrupts */ save_and_cli(flags); - ia64_mc_info.imi_rendez_checkin[ia64_get_cpuid(0)] = IA64_MCA_RENDEZ_CHECKIN_DONE; +#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 */ diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 6b714108e..15993525d 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S @@ -6,6 +6,8 @@ // 00/03/29 cfleck Added code to save INIT handoff state in pt_regs format, switch to temp kstack, // switch modes, jump to C INIT handler // +#include <linux/config.h> + #include <asm/pgtable.h> #include <asm/processor.h> #include <asm/mca_asm.h> @@ -680,32 +682,22 @@ end_os_mca_restore: .proc ia64_monarch_init_handler ia64_monarch_init_handler: -#if defined(SAL_MPINIT_WORKAROUND) +#if defined(CONFIG_SMP) && defined(SAL_MPINIT_WORKAROUND) // // work around SAL bug that sends all processors to monarch entry // - .global bootstrap_processor - - movl r21=24 - movl r20=16 mov r17=cr.lid - movl r18=bootstrap_processor + movl r18=__cpu_physical_id ;; - dep r18=0,r18,61,3 // convert bsp to physical address + dep r18=0,r18,61,3 // convert to physical address ;; - shr r19=r17,r20 - shr r22=r17,r21 + shr.u r17=r17,16 ld4 r18=[r18] // get the BSP ID ;; - and r19=0xf, r19 - and r22=0xf, r22 - ;; - shl r19=r19,8 // get them in the right order - ;; - or r22=r22,r19 // combine EID and LID + dep r17=0,r17,16,48 ;; - cmp.eq p6,p7=r22,r18 // Am I the BSP ? -(p7) br.cond.spnt slave_init_spin_me + cmp4.ne p6,p0=r17,r18 // Am I the BSP ? +(p6) br.cond.spnt slave_init_spin_me ;; #endif diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h index 24be2f53d..8790d49c3 100644 --- a/arch/ia64/kernel/minstate.h +++ b/arch/ia64/kernel/minstate.h @@ -192,13 +192,3 @@ #define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs,) STOPS #define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs, mov r15=r19) STOPS #define SAVE_MIN DO_SAVE_MIN(mov rCRIFS=r0,) STOPS - -#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC -# define STOPS nop.i 0x0;; nop.i 0x0;; nop.i 0x0;; -#else -# define STOPS -#endif - -#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs,) STOPS -#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs, mov r15=r19) STOPS -#define SAVE_MIN DO_SAVE_MIN(mov rCRIFS=r0,) STOPS diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S index 0b07163dc..2e56a428e 100644 --- a/arch/ia64/kernel/pal.S +++ b/arch/ia64/kernel/pal.S @@ -54,7 +54,8 @@ END(ia64_pal_default_handler) * * in0 Pointer to struct ia64_pal_retval * in1 Index of PAL service - * in2 - in4 Remaning PAL arguments + * in2 - in4 Remaining PAL arguments + * in5 1 ==> clear psr.ic, 0 ==> don't clear psr.ic * */ GLOBAL_ENTRY(ia64_pal_call_static) @@ -68,18 +69,22 @@ GLOBAL_ENTRY(ia64_pal_call_static) } ;; ld8 loc2 = [loc2] // loc2 <- entry point - mov r30 = in2 - mov r31 = in3 + tbit.nz p6,p7 = in5, 0 + adds r8 = 1f-1b,r8 ;; mov loc3 = psr mov loc0 = rp UNW(.body) - adds r8 = 1f-1b,r8 - ;; - rsm psr.i + mov r30 = in2 + +(p6) rsm psr.i | psr.ic + mov r31 = in3 mov b7 = loc2 + +(p7) rsm psr.i + ;; +(p6) srlz.i mov rp = r8 - ;; br.cond.sptk.few b7 1: mov psr.l = loc3 mov ar.pfs = loc1 diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index ecd7b0886..de71a2d22 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -10,11 +10,11 @@ * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> * * 05/26/2000 S.Eranian initial release + * 08/21/2000 S.Eranian updated to July 2000 PAL specs * * ISSUES: - * - because of some PAL bugs, some calls return invalid results or - * are empty for now. - * - remove hack to avoid problem with <= 256M RAM for itr. + * - as of 2.2.9/2.2.12, the following values are still wrong + * PAL_VM_SUMMARY: key & rid sizes */ #include <linux/config.h> #include <linux/types.h> @@ -111,7 +111,7 @@ static const char *rse_hints[]={ #define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *)) /* - * The current revision of the Volume 2 of + * 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: @@ -132,38 +132,6 @@ static const char *mem_attrib[]={ "NaTPage" /* 111 */ }; - - -/* - * Allocate a buffer suitable for calling PAL code in Virtual mode - * - * The documentation (PAL2.6) allows DTLB misses on the buffer. So - * using the TC is enough, no need to pin the entry. - * - * We allocate a kernel-sized page (at least 4KB). This is enough to - * hold any possible reply. - */ -static inline void * -get_palcall_buffer(void) -{ - void *tmp; - - tmp = (void *)__get_free_page(GFP_KERNEL); - if (tmp == 0) { - printk(KERN_ERR __FUNCTION__" : can't get a buffer page\n"); - } - return tmp; -} - -/* - * Free a palcall buffer allocated with the previous call - */ -static inline void -free_palcall_buffer(void *addr) -{ - __free_page(addr); -} - /* * Take a 64bit vector and produces a string such that * if bit n is set then 2^n in clear text is generated. The adjustment @@ -243,17 +211,12 @@ power_info(char *page) { s64 status; char *p = page; - pal_power_mgmt_info_u_t *halt_info; + u64 halt_info_buffer[8]; + pal_power_mgmt_info_u_t *halt_info =(pal_power_mgmt_info_u_t *)halt_info_buffer; int i; - halt_info = get_palcall_buffer(); - if (halt_info == 0) return 0; - status = ia64_pal_halt_info(halt_info); - if (status != 0) { - free_palcall_buffer(halt_info); - return 0; - } + if (status != 0) return 0; for (i=0; i < 8 ; i++ ) { if (halt_info[i].pal_power_mgmt_info_s.im == 1) { @@ -270,9 +233,6 @@ power_info(char *page) p += sprintf(p,"Power level %d: not implemented\n",i); } } - - free_palcall_buffer(halt_info); - return p - page; } @@ -502,7 +462,7 @@ register_info(char *page) "RSE load/store hints : %ld (%s)\n", phys_stacked, hints.ph_data, - hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)"); + hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(\?\?)"); if (ia64_pal_debug_info(&iregs, &dregs)) return 0; @@ -569,7 +529,9 @@ static const char *bus_features[]={ "Enable Half Transfer", 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, + "Enable Cache Line Repl. Exclusive", + "Enable Cache Line Repl. Shared", "Disable Transaction Queuing", "Disable Reponse Error Checking", "Disable Bus Error Checking", @@ -673,16 +635,10 @@ static int perfmon_info(char *page) { char *p = page; - u64 *pm_buffer; + u64 pm_buffer[16]; pal_perf_mon_info_u_t pm_info; - pm_buffer = (u64 *)get_palcall_buffer(); - if (pm_buffer == 0) return 0; - - if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) { - free_palcall_buffer(pm_buffer); - return 0; - } + if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) return 0; #ifdef IA64_PAL_PERF_MON_INFO_BUG /* @@ -719,8 +675,6 @@ perfmon_info(char *page) p += sprintf(p, "\n"); - free_palcall_buffer(pm_buffer); - return p - page; } diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index 80509c6a1..6293cdfa0 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -97,7 +97,8 @@ setup_swiotlb (void) 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", io_tlb_start, io_tlb_end); + printk("Placing software IO TLB between 0x%p - 0x%p\n", + (void *) io_tlb_start, (void *) io_tlb_end); } /* @@ -394,7 +395,7 @@ pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int * Once the device is given the dma address, the device owns this memory * until either pci_unmap_single or pci_dma_sync_single is performed. */ -extern inline dma_addr_t +dma_addr_t pci_map_single (struct pci_dev *hwdev, void *ptr, size_t size, int direction) { if (direction == PCI_DMA_NONE) @@ -410,7 +411,7 @@ pci_map_single (struct pci_dev *hwdev, void *ptr, size_t size, int direction) * After this call, reads by the cpu to the buffer are guarenteed to see * whatever the device wrote there. */ -extern inline void +void pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) { if (direction == PCI_DMA_NONE) @@ -433,7 +434,7 @@ pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int d * Device ownership issues as mentioned above for pci_map_single are * the same here. */ -extern inline int +int pci_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { if (direction == PCI_DMA_NONE) @@ -446,7 +447,7 @@ pci_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direct * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -extern inline void +void pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { if (direction == PCI_DMA_NONE) @@ -463,7 +464,7 @@ pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int dire * next point you give the PCI dma address back to the card, the * device again owns the buffer. */ -extern inline void +void pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) { if (direction == PCI_DMA_NONE) @@ -478,7 +479,7 @@ pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, * The same as pci_dma_sync_single but for a scatter-gather list, * same rules and usage. */ -extern inline void +void pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) { if (direction == PCI_DMA_NONE) diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 752b2a9a1..e5efbc8b5 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -10,15 +10,19 @@ #include <linux/config.h> #include <linux/kernel.h> +#include <linux/init.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/smp_lock.h> +#include <linux/proc_fs.h> +#include <linux/ptrace.h> #include <asm/errno.h> #include <asm/hw_irq.h> #include <asm/processor.h> #include <asm/system.h> #include <asm/uaccess.h> +#include <asm/pal.h> /* Long blurb on how this works: * We set dcr.pp, psr.pp, and the appropriate pmc control values with @@ -52,68 +56,107 @@ #ifdef CONFIG_PERFMON #define MAX_PERF_COUNTER 4 /* true for Itanium, at least */ +#define PMU_FIRST_COUNTER 4 /* first generic counter */ + #define WRITE_PMCS_AND_START 0xa0 #define WRITE_PMCS 0xa1 #define READ_PMDS 0xa2 #define STOP_PMCS 0xa3 -#define IA64_COUNTER_MASK 0xffffffffffffff6fL -#define PERF_OVFL_VAL 0xffffffffL -volatile int used_by_system; -struct perfmon_counter { - unsigned long data; - unsigned long counter_num; -}; +/* + * this structure needs to be enhanced + */ +typedef struct { + unsigned long pmu_reg_data; /* generic PMD register */ + unsigned long pmu_reg_num; /* which register number */ +} perfmon_reg_t; + +/* + * This structure is initialize at boot time and contains + * a description of the PMU main characteristic as indicated + * by PAL + */ +typedef struct { + unsigned long perf_ovfl_val; /* overflow value for generic counters */ + unsigned long max_pmc; /* highest PMC */ + unsigned long max_pmd; /* highest PMD */ + unsigned long max_counters; /* number of generic counter pairs (PMC/PMD) */ +} pmu_config_t; + +/* XXX will go static when ptrace() is cleaned */ +unsigned long perf_ovfl_val; /* overflow value for generic counters */ + +static pmu_config_t pmu_conf; +/* + * could optimize to avoid cache conflicts in SMP + */ unsigned long pmds[NR_CPUS][MAX_PERF_COUNTER]; asmlinkage unsigned long -sys_perfmonctl (int cmd1, int cmd2, void *ptr) +sys_perfmonctl (int cmd, int count, void *ptr, long arg4, long arg5, long arg6, long arg7, long arg8, long stack) { - struct perfmon_counter tmp, *cptr = ptr; - unsigned long cnum, dcr, flags; - struct perf_counter; + struct pt_regs *regs = (struct pt_regs *) &stack; + perfmon_reg_t tmp, *cptr = ptr; + unsigned long cnum; int i; - switch (cmd1) { + switch (cmd) { case WRITE_PMCS: /* Writes to PMC's and clears PMDs */ case WRITE_PMCS_AND_START: /* Also starts counting */ - if (cmd2 <= 0 || cmd2 > MAX_PERF_COUNTER - used_by_system) - return -EINVAL; - - if (!access_ok(VERIFY_READ, cptr, sizeof(struct perf_counter)*cmd2)) + if (!access_ok(VERIFY_READ, cptr, sizeof(struct perfmon_reg_t)*count)) return -EFAULT; - current->thread.flags |= IA64_THREAD_PM_VALID; + for (i = 0; i < count; i++, cptr++) { - for (i = 0; i < cmd2; i++, cptr++) { copy_from_user(&tmp, cptr, sizeof(tmp)); - /* XXX need to check validity of counter_num and perhaps data!! */ - if (tmp.counter_num < 4 - || tmp.counter_num >= 4 + MAX_PERF_COUNTER - used_by_system) - return -EFAULT; - - ia64_set_pmc(tmp.counter_num, tmp.data); - ia64_set_pmd(tmp.counter_num, 0); - pmds[smp_processor_id()][tmp.counter_num - 4] = 0; + + /* XXX need to check validity of pmu_reg_num and perhaps data!! */ + + if (tmp.pmu_reg_num > pmu_conf.max_pmc || tmp.pmu_reg_num == 0) return -EFAULT; + + ia64_set_pmc(tmp.pmu_reg_num, tmp.pmu_reg_data); + + /* to go away */ + if (tmp.pmu_reg_num >= PMU_FIRST_COUNTER && tmp.pmu_reg_num < PMU_FIRST_COUNTER+pmu_conf.max_counters) { + ia64_set_pmd(tmp.pmu_reg_num, 0); + pmds[smp_processor_id()][tmp.pmu_reg_num - PMU_FIRST_COUNTER] = 0; + + printk(__FUNCTION__" setting PMC/PMD[%ld] es=0x%lx pmd[%ld]=%lx\n", tmp.pmu_reg_num, (tmp.pmu_reg_data>>8) & 0x7f, tmp.pmu_reg_num, ia64_get_pmd(tmp.pmu_reg_num)); + } else + printk(__FUNCTION__" setting PMC[%ld]=0x%lx\n", tmp.pmu_reg_num, tmp.pmu_reg_data); } - if (cmd1 == WRITE_PMCS_AND_START) { + if (cmd == WRITE_PMCS_AND_START) { +#if 0 +/* irrelevant with user monitors */ local_irq_save(flags); + dcr = ia64_get_dcr(); dcr |= IA64_DCR_PP; ia64_set_dcr(dcr); + local_irq_restore(flags); +#endif + ia64_set_pmc(0, 0); + + /* will start monitoring right after rfi */ + ia64_psr(regs)->up = 1; } + /* + * mark the state as valid. + * this will trigger save/restore at context switch + */ + current->thread.flags |= IA64_THREAD_PM_VALID; break; case READ_PMDS: - if (cmd2 <= 0 || cmd2 > MAX_PERF_COUNTER - used_by_system) + if (count <= 0 || count > MAX_PERF_COUNTER) return -EINVAL; - if (!access_ok(VERIFY_WRITE, cptr, sizeof(struct perf_counter)*cmd2)) + if (!access_ok(VERIFY_WRITE, cptr, sizeof(struct perfmon_reg_t)*count)) return -EFAULT; /* This looks shady, but IMHO this will work fine. This is @@ -121,14 +164,15 @@ sys_perfmonctl (int cmd1, int cmd2, void *ptr) * with the interrupt handler. See explanation in the * following comment. */ - +#if 0 +/* irrelevant with user monitors */ local_irq_save(flags); __asm__ __volatile__("rsm psr.pp\n"); dcr = ia64_get_dcr(); dcr &= ~IA64_DCR_PP; ia64_set_dcr(dcr); local_irq_restore(flags); - +#endif /* * We cannot write to pmc[0] to stop counting here, as * that particular instruction might cause an overflow @@ -142,36 +186,47 @@ sys_perfmonctl (int cmd1, int cmd2, void *ptr) * when we re-enabled interrupts. When I muck with dcr, * is the irq_save/restore needed? */ - for (i = 0, cnum = 4;i < cmd2; i++, cnum++, cptr++) { - tmp.data = (pmds[smp_processor_id()][i] - + (ia64_get_pmd(cnum) & PERF_OVFL_VAL)); - tmp.counter_num = cnum; - if (copy_to_user(cptr, &tmp, sizeof(tmp))) - return -EFAULT; - //put_user(pmd, &cptr->data); + + + /* XXX: This needs to change to read more than just the counters */ + for (i = 0, cnum = PMU_FIRST_COUNTER;i < count; i++, cnum++, cptr++) { + + tmp.pmu_reg_data = (pmds[smp_processor_id()][i] + + (ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val)); + + tmp.pmu_reg_num = cnum; + + if (copy_to_user(cptr, &tmp, sizeof(tmp))) return -EFAULT; } +#if 0 +/* irrelevant with user monitors */ local_irq_save(flags); __asm__ __volatile__("ssm psr.pp"); dcr = ia64_get_dcr(); dcr |= IA64_DCR_PP; ia64_set_dcr(dcr); local_irq_restore(flags); +#endif break; case STOP_PMCS: ia64_set_pmc(0, 1); ia64_srlz_d(); - for (i = 0; i < MAX_PERF_COUNTER - used_by_system; ++i) + for (i = 0; i < MAX_PERF_COUNTER; ++i) ia64_set_pmc(4+i, 0); - if (!used_by_system) { - local_irq_save(flags); - dcr = ia64_get_dcr(); - dcr &= ~IA64_DCR_PP; - ia64_set_dcr(dcr); - local_irq_restore(flags); - } +#if 0 +/* irrelevant with user monitors */ + local_irq_save(flags); + dcr = ia64_get_dcr(); + dcr &= ~IA64_DCR_PP; + ia64_set_dcr(dcr); + local_irq_restore(flags); + ia64_psr(regs)->up = 0; +#endif + current->thread.flags &= ~(IA64_THREAD_PM_VALID); + break; default: @@ -187,13 +242,21 @@ update_counters (void) unsigned long mask, i, cnum, val; mask = ia64_get_pmc(0) >> 4; - for (i = 0, cnum = 4; i < MAX_PERF_COUNTER - used_by_system; cnum++, i++, mask >>= 1) { - val = 0; + for (i = 0, cnum = PMU_FIRST_COUNTER ; i < pmu_conf.max_counters; cnum++, i++, mask >>= 1) { + + + val = mask & 0x1 ? pmu_conf.perf_ovfl_val + 1 : 0; + if (mask & 0x1) - val += PERF_OVFL_VAL + 1; + printk(__FUNCTION__ " PMD%ld overflowed pmd=%lx pmod=%lx\n", cnum, ia64_get_pmd(cnum), pmds[smp_processor_id()][i]); + /* since we got an interrupt, might as well clear every pmd. */ - val += ia64_get_pmd(cnum) & PERF_OVFL_VAL; + val += ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val; + + printk(__FUNCTION__ " adding val=%lx to pmod[%ld]=%lx \n", val, i, pmds[smp_processor_id()][i]); + pmds[smp_processor_id()][i] += val; + ia64_set_pmd(cnum, 0); } } @@ -212,16 +275,69 @@ static struct irqaction perfmon_irqaction = { name: "perfmon" }; -void +static int +perfmon_proc_info(char *page) +{ + char *p = page; + u64 pmc0 = ia64_get_pmc(0); + + p += sprintf(p, "PMC[0]=%lx\n", pmc0); + + return p - page; +} + +static int +perfmon_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = perfmon_proc_info(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 struct proc_dir_entry *perfmon_dir; + +void __init perfmon_init (void) { + pal_perf_mon_info_u_t pm_info; + u64 pm_buffer[16]; + s64 status; + irq_desc[PERFMON_IRQ].status |= IRQ_PER_CPU; irq_desc[PERFMON_IRQ].handler = &irq_type_ia64_sapic; setup_irq(PERFMON_IRQ, &perfmon_irqaction); ia64_set_pmv(PERFMON_IRQ); ia64_srlz_d(); - printk("Initialized perfmon vector to %u\n",PERFMON_IRQ); + + printk("perfmon: Initialized vector to %u\n",PERFMON_IRQ); + + if ((status=ia64_pal_perf_mon_info(pm_buffer, &pm_info)) != 0) { + printk(__FUNCTION__ " pal call failed (%ld)\n", status); + return; + } + pmu_conf.perf_ovfl_val = perf_ovfl_val = (1L << pm_info.pal_perf_mon_info_s.width) - 1; + + /* XXX need to use PAL instead */ + pmu_conf.max_pmc = 13; + pmu_conf.max_pmd = 17; + pmu_conf.max_counters = pm_info.pal_perf_mon_info_s.generic; + + printk("perfmon: Counters are %d bits\n", pm_info.pal_perf_mon_info_s.width); + printk("perfmon: Maximum counter value 0x%lx\n", pmu_conf.perf_ovfl_val); + + /* + * for now here for debug purposes + */ + perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL); } void @@ -238,10 +354,13 @@ ia64_save_pm_regs (struct thread_struct *t) ia64_set_pmc(0, 1); ia64_srlz_d(); - for (i=0; i< IA64_NUM_PM_REGS - used_by_system ; i++) { - t->pmd[i] = ia64_get_pmd(4+i); + /* + * XXX: this will need to be extended beyong just counters + */ + for (i=0; i< IA64_NUM_PM_REGS; i++) { + t->pmd[i] = ia64_get_pmd(4+i); t->pmod[i] = pmds[smp_processor_id()][i]; - t->pmc[i] = ia64_get_pmc(4+i); + t->pmc[i] = ia64_get_pmc(4+i); } } @@ -250,7 +369,10 @@ ia64_load_pm_regs (struct thread_struct *t) { int i; - for (i=0; i< IA64_NUM_PM_REGS - used_by_system ; i++) { + /* + * XXX: this will need to be extended beyong just counters + */ + for (i=0; i< IA64_NUM_PM_REGS ; i++) { ia64_set_pmd(4+i, t->pmd[i]); pmds[smp_processor_id()][i] = t->pmod[i]; ia64_set_pmc(4+i, t->pmc[i]); @@ -262,7 +384,7 @@ ia64_load_pm_regs (struct thread_struct *t) #else /* !CONFIG_PERFMON */ asmlinkage unsigned long -sys_perfmonctl (int cmd1, int cmd2, void *ptr) +sys_perfmonctl (int cmd, int count, void *ptr) { return -ENOSYS; } diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index e586a4074..41db60a0c 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -294,7 +294,8 @@ copy_thread (int nr, unsigned long clone_flags, * call behavior where scratch registers are preserved across * system calls (unless used by the system call itself). */ -# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID) +# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \ + | IA64_THREAD_PM_VALID) # define THREAD_FLAGS_TO_SET 0 p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR) | THREAD_FLAGS_TO_SET); @@ -333,6 +334,17 @@ do_copy_regs (struct unw_frame_info *info, void *arg) if (ia64_peek(pt, current, addr, &val) == 0) access_process_vm(current, addr, &val, sizeof(val), 1); + /* + * coredump format: + * r0-r31 + * NaT bits (for r0-r31; bit N == 1 iff rN is a NaT) + * predicate registers (p0-p63) + * b0-b7 + * ip cfm user-mask + * ar.rsc ar.bsp ar.bspstore ar.rnat + * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec + */ + /* r0 is zero */ for (i = 1, mask = (1UL << i); i < 32; ++i) { unw_get_gr(info, i, &dst[i], &nat); @@ -370,7 +382,6 @@ do_copy_regs (struct unw_frame_info *info, void *arg) void do_dump_fpu (struct unw_frame_info *info, void *arg) { - struct task_struct *fpu_owner = ia64_get_fpu_owner(); elf_fpreg_t *dst = arg; int i; @@ -384,10 +395,9 @@ do_dump_fpu (struct unw_frame_info *info, void *arg) for (i = 2; i < 32; ++i) unw_get_fr(info, i, dst + i); - if ((fpu_owner == current) || (current->thread.flags & IA64_THREAD_FPH_VALID)) { - ia64_sync_fph(current); + ia64_flush_fph(current); + if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) memcpy(dst + 32, current->thread.fph, 96*16); - } } #endif /* CONFIG_IA64_NEW_UNWIND */ @@ -463,7 +473,6 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst) unw_init_running(do_dump_fpu, dst); #else struct switch_stack *sw = ((struct switch_stack *) pt) - 1; - struct task_struct *fpu_owner = ia64_get_fpu_owner(); memset(dst, 0, sizeof (dst)); /* don't leak any "random" bits */ @@ -472,12 +481,9 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst) dst[8] = pt->f8; dst[9] = pt->f9; memcpy(dst + 10, &sw->f10, 22*16); /* f10-f31 are contiguous */ - if ((fpu_owner == current) || (current->thread.flags & IA64_THREAD_FPH_VALID)) { - if (fpu_owner == current) { - __ia64_save_fpu(current->thread.fph); - } + ia64_flush_fph(current); + if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) memcpy(dst + 32, current->thread.fph, 96*16); - } #endif return 1; /* f0-f31 are always valid so we always return 1 */ } @@ -501,14 +507,14 @@ pid_t kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) { struct task_struct *parent = current; - int result; + int result, tid; - clone(flags | CLONE_VM, 0); + tid = clone(flags | CLONE_VM, 0); if (parent != current) { result = (*fn)(arg); _exit(result); } - return 0; /* parent: just return */ + return tid; } /* @@ -520,9 +526,10 @@ flush_thread (void) /* drop floating-point and debug-register state if it exists: */ current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); - if (ia64_get_fpu_owner() == current) { +#ifndef CONFIG_SMP + if (ia64_get_fpu_owner() == current) ia64_set_fpu_owner(0); - } +#endif } /* @@ -532,9 +539,28 @@ flush_thread (void) void exit_thread (void) { - if (ia64_get_fpu_owner() == current) { +#ifndef CONFIG_SMP + if (ia64_get_fpu_owner() == current) ia64_set_fpu_owner(0); +#endif +#ifdef CONFIG_PERFMON + /* stop monitoring */ + if ((current->thread.flags & IA64_THREAD_PM_VALID) != 0) { + /* + * we cannot rely on switch_to() to save the PMU + * context for the last time. There is a possible race + * condition in SMP mode between the child and the + * parent. by explicitly saving the PMU context here + * we garantee no race. this call we also stop + * monitoring + */ + ia64_save_pm_regs(¤t->thread); + /* + * make sure that switch_to() will not save context again + */ + current->thread.flags &= ~IA64_THREAD_PM_VALID; } +#endif } unsigned long diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 10868ce41..820a87854 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -376,7 +376,8 @@ ia64_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, ret = 0; } else { if ((unsigned long) laddr >= (unsigned long) high_memory) { - printk("yikes: trying to access long at %p\n", laddr); + printk("yikes: trying to access long at %p\n", + (void *) laddr); return -EIO; } ret = *laddr; @@ -543,21 +544,48 @@ sync_thread_rbs (struct task_struct *child, struct mm_struct *mm, int make_writa } /* - * Ensure the state in child->thread.fph is up-to-date. + * Write f32-f127 back to task->thread.fph if it has been modified. */ -void -ia64_sync_fph (struct task_struct *child) +inline void +ia64_flush_fph (struct task_struct *task) { - if (ia64_psr(ia64_task_regs(child))->mfh && ia64_get_fpu_owner() == child) { - ia64_psr(ia64_task_regs(child))->mfh = 0; - ia64_set_fpu_owner(0); - ia64_save_fpu(&child->thread.fph[0]); - child->thread.flags |= IA64_THREAD_FPH_VALID; + 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) { + psr->mfh = 0; + ia64_save_fpu(&task->thread.fph[0]); + task->thread.flags |= IA64_THREAD_FPH_VALID; } - if (!(child->thread.flags & IA64_THREAD_FPH_VALID)) { - memset(&child->thread.fph, 0, sizeof(child->thread.fph)); - child->thread.flags |= IA64_THREAD_FPH_VALID; +} + +/* + * Sync the fph state of the task so that it can be manipulated + * through thread.fph. If necessary, f32-f127 are written back to + * thread.fph or, if the fph state hasn't been used before, thread.fph + * is cleared to zeroes. Also, access to f32-f127 is disabled to + * ensure that the task picks up the state from thread.fph when it + * executes again. + */ +void +ia64_sync_fph (struct task_struct *task) +{ + struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); + + ia64_flush_fph(task); + if (!(task->thread.flags & IA64_THREAD_FPH_VALID)) { + 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 + psr->dfh = 1; } #ifdef CONFIG_IA64_NEW_UNWIND @@ -589,6 +617,7 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data struct switch_stack *sw; struct unw_frame_info info; struct pt_regs *pt; + unsigned long pmd_tmp; pt = ia64_task_regs(child); sw = (struct switch_stack *) (child->thread.ksp + 16); @@ -600,7 +629,10 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data if (addr < PT_F127 + 16) { /* accessing fph */ - ia64_sync_fph(child); + if (write_access) + ia64_sync_fph(child); + else + ia64_flush_fph(child); ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr); } else if (addr >= PT_F10 && addr < PT_F15 + 16) { /* scratch registers untouched by kernel (saved in switch_stack) */ @@ -656,6 +688,9 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data case PT_B1: case PT_B2: case PT_B3: case PT_B4: case PT_B5: return unw_access_br(&info, (addr - PT_B1)/8 + 1, data, write_access); + case PT_AR_EC: + return unw_access_ar(&info, UNW_AR_EC, data, write_access); + case PT_AR_LC: return unw_access_ar(&info, UNW_AR_LC, data, write_access); @@ -759,7 +794,11 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data addr); return -1; } - } else { + } else +#ifdef CONFIG_PERFMON + if (addr < PT_PMD) +#endif + { /* access debug registers */ if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) { @@ -782,6 +821,32 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data ptr += regnum; } +#ifdef CONFIG_PERFMON + else { + /* + * XXX: will eventually move back to perfmonctl() + */ + unsigned long pmd = (addr - PT_PMD) >> 3; + extern unsigned long perf_ovfl_val; + + /* we just use ptrace to read */ + if (write_access) return -1; + + if (pmd > 3) { + printk("ptrace: rejecting access to PMD[%ld] address 0x%lx\n", pmd, addr); + return -1; + } + + /* + * We always need to mask upper 32bits of pmd because value is random + */ + pmd_tmp = child->thread.pmod[pmd]+(child->thread.pmd[pmd]& perf_ovfl_val); + + /*printk(__FUNCTION__" child=%d reading pmd[%ld]=%lx\n", child->pid, pmd, pmd_tmp);*/ + + ptr = &pmd_tmp; + } +#endif if (write_access) *ptr = *data; else @@ -794,8 +859,9 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data static int access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data, int write_access) { - unsigned long *ptr, *rbs, *bspstore, ndirty, regnum; + unsigned long *ptr = NULL, *rbs, *bspstore, ndirty, regnum; struct switch_stack *sw; + unsigned long pmd_tmp; struct pt_regs *pt; if ((addr & 0x7) != 0) @@ -803,7 +869,10 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data if (addr < PT_F127+16) { /* accessing fph */ - ia64_sync_fph(child); + if (write_access) + ia64_sync_fph(child); + else + ia64_flush_fph(child); ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr); } else if (addr < PT_F9+16) { /* accessing switch_stack or pt_regs: */ @@ -864,6 +933,14 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data *data = (pt->cr_ipsr & IPSR_READ_MASK); return 0; + case PT_AR_EC: + if (write_access) + sw->ar_pfs = (((*data & 0x3f) << 52) + | (sw->ar_pfs & ~(0x3fUL << 52))); + else + *data = (sw->ar_pfs >> 52) & 0x3f; + break; + case PT_R1: case PT_R2: case PT_R3: case PT_R4: case PT_R5: case PT_R6: case PT_R7: case PT_R8: case PT_R9: case PT_R10: case PT_R11: @@ -900,7 +977,12 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data /* disallow accessing anything else... */ return -1; } - } else { + } else +#ifdef CONFIG_PERFMON + if (addr < PT_PMD) +#endif + { + /* access debug registers */ if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) { @@ -921,6 +1003,33 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data ptr += regnum; } +#ifdef CONFIG_PERFMON + else { + /* + * XXX: will eventually move back to perfmonctl() + */ + unsigned long pmd = (addr - PT_PMD) >> 3; + extern unsigned long perf_ovfl_val; + + /* we just use ptrace to read */ + if (write_access) return -1; + + if (pmd > 3) { + printk("ptrace: rejecting access to PMD[%ld] address 0x%lx\n", pmd, addr); + return -1; + } + + /* + * We always need to mask upper 32bits of pmd because value is random + */ + pmd_tmp = child->thread.pmod[pmd]+(child->thread.pmd[pmd]& perf_ovfl_val); + + /*printk(__FUNCTION__" child=%d reading pmd[%ld]=%lx\n", child->pid, pmd, pmd_tmp);*/ + + ptr = &pmd_tmp; + } +#endif + if (write_access) *ptr = *data; else @@ -996,10 +1105,12 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data, ret = -ESRCH; if (!(child->ptrace & PT_PTRACED)) goto out_tsk; + if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) + if (request != PTRACE_KILL && request != PTRACE_PEEKUSR) goto out_tsk; } + if (child->p_pptr != current) goto out_tsk; diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index f73cd8968..87c7befea 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c @@ -34,6 +34,7 @@ default_handler (void) } ia64_sal_handler ia64_sal = (ia64_sal_handler) default_handler; +ia64_sal_desc_ptc_t *ia64_ptc_domain_info; const char * ia64_sal_strerror (long status) @@ -127,6 +128,10 @@ ia64_sal_init (struct ia64_sal_systab *systab) ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp)); break; + case SAL_DESC_PTC: + ia64_ptc_domain_info = (ia64_sal_desc_ptc_t *)p; + break; + case SAL_DESC_AP_WAKEUP: #ifdef CONFIG_SMP { diff --git a/arch/ia64/kernel/semaphore.c b/arch/ia64/kernel/semaphore.c index 1bbe4feab..84ff34cf6 100644 --- a/arch/ia64/kernel/semaphore.c +++ b/arch/ia64/kernel/semaphore.c @@ -7,9 +7,9 @@ /* * Semaphores are implemented using a two-way counter: The "count" - * variable is decremented for each process that tries to aquire the + * variable is decremented for each process that tries to acquire the * semaphore, while the "sleepers" variable is a count of such - * aquires. + * acquires. * * Notably, the inline "up()" and "down()" functions can efficiently * test if they need to do any extra work (up needs to do something @@ -188,7 +188,7 @@ down_read_failed_biased (struct rw_semaphore *sem) } /* - * This gets called if we failed to aquire the lock and we are not + * This gets called if we failed to acquire the lock and we are not * biased to acquire the lock. We undo the decrement that was * done earlier, go to sleep, and then attempt to re-acquire the * lock afterwards. @@ -279,7 +279,7 @@ down_write_failed (struct rw_semaphore *sem) while (sem->count < 0) { set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (sem->count >= 0) - break; /* we must attempt to aquire or bias the lock */ + break; /* we must attempt to acquire or bias the lock */ schedule(); } diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 62e3e19ea..ed091d864 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -36,6 +36,7 @@ #include <asm/system.h> #include <asm/efi.h> #include <asm/mca.h> +#include <asm/smp.h> #ifdef CONFIG_BLK_DEV_RAM # include <linux/blk.h> @@ -43,7 +44,7 @@ extern char _end; -/* cpu_data[bootstrap_processor] is data for the bootstrap processor: */ +/* cpu_data[0] is data for the bootstrap processor: */ struct cpuinfo_ia64 cpu_data[NR_CPUS]; unsigned long ia64_cycles_per_usec; @@ -56,6 +57,8 @@ int cpu_now_booting = 0; volatile unsigned long cpu_online_map; #endif +unsigned long ia64_iobase; /* virtual address for I/O accesses */ + #define COMMAND_LINE_SIZE 512 char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */ @@ -111,6 +114,7 @@ free_available_memory (unsigned long start, unsigned long end, void *arg) void __init setup_arch (char **cmdline_p) { + extern unsigned long ia64_iobase; unsigned long max_pfn, bootmap_start, bootmap_size; unw_init(); @@ -157,7 +161,7 @@ setup_arch (char **cmdline_p) if (initrd_start >= PAGE_OFFSET) printk("Warning: boot loader passed virtual address " "for initrd, please upgrade the loader\n"); - } else + else #endif /* * The loader ONLY passes physical addresses @@ -215,9 +219,16 @@ setup_arch (char **cmdline_p) ia64_sal_init(efi.sal_systab); #ifdef CONFIG_SMP - bootstrap_processor = hard_smp_processor_id(); - current->processor = bootstrap_processor; + current->processor = 0; + cpu_physical_id(0) = hard_smp_processor_id(); #endif + /* + * Set `iobase' to the appropriate address in region 6 + * (uncached access range) + */ + __asm__ ("mov %0=ar.k0;;" : "=r"(ia64_iobase)); + ia64_iobase = __IA64_UNCACHED_OFFSET | (ia64_iobase & ~PAGE_OFFSET); + cpu_init(); /* initialize the bootstrap CPU */ #ifdef CONFIG_IA64_GENERIC @@ -259,6 +270,11 @@ setup_arch (char **cmdline_p) int get_cpuinfo (char *buffer) { +#ifdef CONFIG_SMP +# define lps c->loops_per_sec +#else +# define lps loops_per_sec +#endif char family[32], model[32], features[128], *cp, *p = buffer; struct cpuinfo_ia64 *c; unsigned long mask; @@ -309,7 +325,7 @@ get_cpuinfo (char *buffer) features, c->ppn, c->number, c->proc_freq / 1000000, c->proc_freq % 1000000, c->itc_freq / 1000000, c->itc_freq % 1000000, - loops_per_sec() / 500000, (loops_per_sec() / 5000) % 100); + lps / 500000, (lps / 5000) % 100); } return p - buffer; } @@ -371,8 +387,8 @@ identify_cpu (struct cpuinfo_ia64 *c) #endif phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size; } - printk("processor implements %lu virtual and %lu physical address bits\n", - impl_va_msb + 1, phys_addr_size); + printk("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)); @@ -405,9 +421,12 @@ cpu_init (void) * do NOT defer TLB misses, page-not-present, access bit, or * debug faults but kernel code should not rely on any * particular setting of these bits. - */ ia64_set_dcr(IA64_DCR_DR | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_PP); + */ + ia64_set_dcr(IA64_DCR_DR | IA64_DCR_DK | IA64_DCR_DX ); +#ifndef CONFIG_SMP ia64_set_fpu_owner(0); /* initialize ar.k5 */ +#endif atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 12f312672..e0adf1981 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -147,11 +147,12 @@ restore_sigcontext (struct sigcontext *sc, struct sigscratch *scr) ia64_put_nat_bits(&scr->pt, &scr->sw, nat); /* restore the original scratch NaT bits */ #endif - if (flags & IA64_SC_FLAG_FPH_VALID) { - struct task_struct *fpu_owner = ia64_get_fpu_owner(); + if ((flags & IA64_SC_FLAG_FPH_VALID) != 0) { + struct ia64_psr *psr = ia64_psr(&scr->pt); __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16); - if (fpu_owner == current) { + if (!psr->dfh) { + psr->mfh = 0; __ia64_load_fpu(current->thread.fph); } } @@ -235,9 +236,12 @@ ia64_rt_sigreturn (struct sigscratch *scr) goto give_sigsegv; sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); - current->blocked = set; - recalc_sigpending(current); + { + current->blocked = set; + recalc_sigpending(current); + } spin_unlock_irq(¤t->sigmask_lock); if (restore_sigcontext(sc, scr)) @@ -274,7 +278,6 @@ ia64_rt_sigreturn (struct sigscratch *scr) static long setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct sigscratch *scr) { - struct task_struct *fpu_owner = ia64_get_fpu_owner(); unsigned long flags = 0, ifs, nat; long err; @@ -286,11 +289,9 @@ setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct sigscratch *scr) /* if cr_ifs isn't valid, we got here through a syscall */ flags |= IA64_SC_FLAG_IN_SYSCALL; } - if ((fpu_owner == current) || (current->thread.flags & IA64_THREAD_FPH_VALID)) { + ia64_flush_fph(current); + if ((current->thread.flags & IA64_THREAD_FPH_VALID)) { flags |= IA64_SC_FLAG_FPH_VALID; - if (fpu_owner == current) { - __ia64_save_fpu(current->thread.fph); - } __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16); } @@ -425,9 +426,11 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse 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); + { + sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); + sigaddset(¤t->blocked, sig); + recalc_sigpending(current); + } spin_unlock_irq(¤t->sigmask_lock); } return 1; diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index d64305cf3..694711507 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -6,6 +6,8 @@ * * Lots of stuff stolen from arch/alpha/kernel/smp.c * + * 00/09/11 David Mosberger <davidm@hpl.hp.com> Do loops_per_sec calibration on each CPU. + * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> fixed logical processor id * 00/03/31 Rohit Seth <rohit.seth@intel.com> Fixes for Bootstrap Processor & cpu_online_map * now gets done here (instead of setup.c) * 99/10/05 davidm Update to bring it in sync with new command-line processing scheme. @@ -27,6 +29,7 @@ #include <asm/bitops.h> #include <asm/current.h> #include <asm/delay.h> +#include <asm/efi.h> #include <asm/io.h> #include <asm/irq.h> @@ -39,27 +42,31 @@ #include <asm/system.h> #include <asm/unistd.h> +extern void __init calibrate_delay(void); extern int cpu_idle(void * unused); -extern void _start(void); extern void machine_halt(void); +extern void start_ap(void); extern int cpu_now_booting; /* Used by head.S to find idle task */ extern volatile unsigned long cpu_online_map; /* Bitmap of available cpu's */ extern struct cpuinfo_ia64 cpu_data[NR_CPUS]; /* Duh... */ +struct smp_boot_data smp_boot_data __initdata; + spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; -struct smp_boot_data __initdata smp; -char __initdata no_int_routing = 0; +char __initdata no_int_routing; unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */ -volatile int __cpu_number_map[NR_CPUS] = { -1, }; /* SAPIC ID -> Logical ID */ -volatile int __cpu_logical_map[NR_CPUS] = { -1, }; /* logical ID -> SAPIC ID */ +volatile int __cpu_physical_id[NR_CPUS] = { -1, }; /* Logical ID -> SAPIC ID */ int smp_num_cpus = 1; -int bootstrap_processor = -1; /* SAPIC ID of BSP */ -int smp_threads_ready = 0; /* Set when the idlers are all forked */ -cycles_t cacheflush_time = 0; +volatile int smp_threads_ready; /* Set when the idlers are all forked */ +cycles_t cacheflush_time; unsigned long ap_wakeup_vector = -1; /* External Int to use to wakeup AP's */ + +static volatile unsigned long cpu_callin_map; +static volatile int smp_commenced; + static int max_cpus = -1; /* Command line */ static unsigned long ipi_op[NR_CPUS]; struct smp_call_struct { @@ -135,6 +142,7 @@ halt_processor(void) static inline int pointer_lock(void *lock, void *data, int retry) { + volatile long *ptr = lock; again: if (cmpxchg_acq((void **) lock, 0, data) == 0) return 0; @@ -142,7 +150,7 @@ pointer_lock(void *lock, void *data, int retry) if (!retry) return -EBUSY; - while (*(void **) lock) + while (*ptr) ; goto again; @@ -275,12 +283,10 @@ static inline void send_IPI_allbutself(int op) { int i; - int cpu_id = 0; for (i = 0; i < smp_num_cpus; i++) { - cpu_id = __cpu_logical_map[i]; - if (cpu_id != smp_processor_id()) - send_IPI_single(cpu_id, op); + if (i != smp_processor_id()) + send_IPI_single(i, op); } } @@ -290,7 +296,7 @@ send_IPI_all(int op) int i; for (i = 0; i < smp_num_cpus; i++) - send_IPI_single(__cpu_logical_map[i], op); + send_IPI_single(i, op); } static inline void @@ -335,7 +341,7 @@ int smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int retry, int wait) { struct smp_call_struct data; - long timeout; + unsigned long timeout; int cpus = 1; if (cpuid == smp_processor_id()) { @@ -387,7 +393,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, int wait) { struct smp_call_struct data; - long timeout; + unsigned long timeout; int cpus = smp_num_cpus - 1; if (cpus == 0) @@ -453,80 +459,16 @@ smp_do_timer(struct pt_regs *regs) if (--data->prof_counter <= 0) { data->prof_counter = data->prof_multiplier; - /* - * update_process_times() expects us to have done irq_enter(). - * Besides, if we don't timer interrupts ignore the global - * interrupt lock, which is the WrongThing (tm) to do. - */ - irq_enter(cpu, 0); update_process_times(user); - irq_exit(cpu, 0); } } -static inline void __init -smp_calibrate_delay(int cpuid) -{ - struct cpuinfo_ia64 *c = &cpu_data[cpuid]; -#if 0 - unsigned long old = loops_per_sec; - extern void calibrate_delay(void); - - loops_per_sec = 0; - calibrate_delay(); - c->loops_per_sec = loops_per_sec; - loops_per_sec = old; -#else - c->loops_per_sec = loops_per_sec; -#endif -} - -/* - * SAL shoves the AP's here when we start them. Physical mode, no kernel TR, - * no RRs set, better than even chance that psr is bogus. Fix all that and - * call _start. In effect, pretend to be lilo. - * - * Stolen from lilo_start.c. Thanks David! - */ -void -start_ap(void) -{ - unsigned long flags; - - /* - * Install a translation register that identity maps the - * kernel's 256MB page(s). - */ - ia64_clear_ic(flags); - ia64_set_rr( 0, (0x1000 << 8) | (_PAGE_SIZE_1M << 2)); - ia64_set_rr(PAGE_OFFSET, (ia64_rid(0, PAGE_OFFSET) << 8) | (_PAGE_SIZE_256M << 2)); - ia64_srlz_d(); - ia64_itr(0x3, 1, PAGE_OFFSET, - pte_val(mk_pte_phys(0, __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX))), - _PAGE_SIZE_256M); - ia64_srlz_i(); - - flags = (IA64_PSR_IT | IA64_PSR_IC | IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_DFH | - IA64_PSR_BN); - - asm volatile ("movl r8 = 1f\n" - ";;\n" - "mov cr.ipsr=%0\n" - "mov cr.iip=r8\n" - "mov cr.ifs=r0\n" - ";;\n" - "rfi;;" - "1:\n" - "movl r1 = __gp" :: "r"(flags) : "r8"); - _start(); -} - /* * AP's start using C here. */ void __init -smp_callin(void) +smp_callin (void) { extern void ia64_rid_init(void); extern void ia64_init_itm(void); @@ -534,12 +476,17 @@ smp_callin(void) #ifdef CONFIG_PERFMON extern void perfmon_init_percpu(void); #endif + int cpu = smp_processor_id(); - efi_map_pal_code(); + if (test_and_set_bit(cpu, &cpu_online_map)) { + printk("CPU#%d already initialized!\n", cpu); + machine_halt(); + } + efi_map_pal_code(); cpu_init(); - smp_setup_percpu_timer(smp_processor_id()); + smp_setup_percpu_timer(cpu); /* setup the CPU local timer tick */ ia64_init_itm(); @@ -552,16 +499,16 @@ smp_callin(void) ia64_set_lrr0(0, 1); ia64_set_lrr1(0, 1); - if (test_and_set_bit(smp_processor_id(), &cpu_online_map)) { - printk("CPU#%d already initialized!\n", smp_processor_id()); - machine_halt(); - } - while (!smp_threads_ready) - mb(); - local_irq_enable(); /* Interrupts have been off until now */ - smp_calibrate_delay(smp_processor_id()); - printk("SMP: CPU %d starting idle loop\n", smp_processor_id()); + + calibrate_delay(); + my_cpu_data.loops_per_sec = loops_per_sec; + + /* allow the master to continue */ + set_bit(cpu, &cpu_callin_map); + + /* finally, wait for the BP to finish initialization: */ + while (!smp_commenced); cpu_idle(NULL); } @@ -583,14 +530,13 @@ fork_by_hand(void) } /* - * Bring one cpu online. - * - * NB: cpuid is the CPU BUS-LOCAL ID, not the entire SAPIC ID. See asm/smp.h. + * Bring one cpu online. Return 0 if this fails for any reason. */ static int __init -smp_boot_one_cpu(int cpuid, int cpunum) +smp_boot_one_cpu(int cpu) { struct task_struct *idle; + int cpu_phys_id = cpu_physical_id(cpu); long timeout; /* @@ -603,50 +549,37 @@ smp_boot_one_cpu(int cpuid, int cpunum) * Sheesh . . . */ if (fork_by_hand() < 0) - panic("failed fork for CPU %d", cpuid); + panic("failed fork for CPU 0x%x", cpu_phys_id); /* * 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", cpuid); - init_tasks[cpunum] = idle; + panic("No idle process for CPU 0x%x", cpu_phys_id); + init_tasks[cpu] = idle; del_from_runqueue(idle); unhash_process(idle); /* Schedule the first task manually. */ - idle->processor = cpuid; + idle->processor = cpu; idle->has_cpu = 1; /* Let _start know what logical CPU we're booting (offset into init_tasks[] */ - cpu_now_booting = cpunum; - + cpu_now_booting = cpu; + /* Kick the AP in the butt */ - ipi_send(cpuid, ap_wakeup_vector, IA64_IPI_DM_INT, 0); - ia64_srlz_i(); - mb(); + ipi_send(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0); - /* - * OK, wait a bit for that CPU to finish staggering about. smp_callin() will - * call cpu_init() which will set a bit for this AP. When that bit flips, the AP - * is waiting for smp_threads_ready to be 1 and we can move on. - */ + /* wait up to 10s for the AP to start */ for (timeout = 0; timeout < 100000; timeout++) { - if (test_bit(cpuid, &cpu_online_map)) - goto alive; + if (test_bit(cpu, &cpu_callin_map)) + return 1; udelay(100); - barrier(); } - printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid); + printk(KERN_ERR "SMP: Processor 0x%x is stuck.\n", cpu_phys_id); return 0; - -alive: - /* Remember the AP data */ - __cpu_number_map[cpuid] = cpunum; - __cpu_logical_map[cpunum] = cpuid; - return 1; } @@ -663,21 +596,20 @@ smp_boot_cpus(void) unsigned long bogosum; /* Take care of some initial bookkeeping. */ - memset(&__cpu_number_map, -1, sizeof(__cpu_number_map)); - memset(&__cpu_logical_map, -1, sizeof(__cpu_logical_map)); + memset(&__cpu_physical_id, -1, sizeof(__cpu_physical_id)); memset(&ipi_op, 0, sizeof(ipi_op)); - /* Setup BSP mappings */ - __cpu_number_map[bootstrap_processor] = 0; - __cpu_logical_map[0] = bootstrap_processor; + /* Setup BP mappings */ + __cpu_physical_id[0] = hard_smp_processor_id(); - smp_calibrate_delay(smp_processor_id()); + /* on the BP, the kernel already called calibrate_delay_loop() in init/main.c */ + my_cpu_data.loops_per_sec = loops_per_sec; #if 0 smp_tune_scheduling(); #endif - smp_setup_percpu_timer(bootstrap_processor); + smp_setup_percpu_timer(0); - if (test_and_set_bit(bootstrap_processor, &cpu_online_map)) { + if (test_and_set_bit(0, &cpu_online_map)) { printk("CPU#%d already initialized!\n", smp_processor_id()); machine_halt(); } @@ -692,16 +624,18 @@ smp_boot_cpus(void) if (max_cpus != -1) printk("Limiting CPUs to %d\n", max_cpus); - if (smp.cpu_count > 1) { + if (smp_boot_data.cpu_count > 1) { printk(KERN_INFO "SMP: starting up secondaries.\n"); - for (i = 0; i < NR_CPUS; i++) { - if (smp.cpu_map[i] == -1 || - smp.cpu_map[i] == bootstrap_processor) + for (i = 0; i < smp_boot_data.cpu_count; i++) { + /* skip performance restricted and bootstrap cpu: */ + if (smp_boot_data.cpu_phys_id[i] == -1 + || smp_boot_data.cpu_phys_id[i] == hard_smp_processor_id()) continue; - if (smp_boot_one_cpu(smp.cpu_map[i], cpu_count) == 0) - continue; + cpu_physical_id(cpu_count) = smp_boot_data.cpu_phys_id[i]; + if (!smp_boot_one_cpu(cpu_count)) + continue; /* failed */ cpu_count++; /* Count good CPUs only... */ /* @@ -731,20 +665,12 @@ smp_boot_cpus(void) } /* - * Called from main.c by each AP. + * Called when the BP is just about to fire off init. */ void __init smp_commence(void) { - mb(); -} - -/* - * Not used; part of the i386 bringup - */ -void __init -initialize_secondary(void) -{ + smp_commenced = 1; } int __init @@ -759,9 +685,7 @@ setup_profiling_timer(unsigned int multiplier) * * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP(). * - * So this just gets the BSP SAPIC ID and print's it out. Dull, huh? - * - * Not anymore. This also registers the AP OS_MC_REDVEZ address with SAL. + * This also registers the AP OS_MC_REDVEZ address with SAL. */ void __init init_smp_config(void) @@ -772,9 +696,6 @@ init_smp_config(void) } *ap_startup; long sal_ret; - /* Grab the BSP ID */ - bootstrap_processor = hard_smp_processor_id(); - /* 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, diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 3550cc390..83bff8b0c 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -1,2 +1,74 @@ -unsigned long cpu_online_map; +/* + * SMP Support + * + * Application processor startup code, moved from smp.c to better support kernel profile + */ + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/smp.h> +#include <linux/kernel_stat.h> +#include <linux/mm.h> +#include <linux/delay.h> + +#include <asm/atomic.h> +#include <asm/bitops.h> +#include <asm/current.h> +#include <asm/delay.h> +#include <asm/efi.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/pgalloc.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/sal.h> +#include <asm/system.h> +#include <asm/unistd.h> + +/* + * SAL shoves the AP's here when we start them. Physical mode, no kernel TR, + * no RRs set, better than even chance that psr is bogus. Fix all that and + * call _start. In effect, pretend to be lilo. + * + * Stolen from lilo_start.c. Thanks David! + */ +void +start_ap(void) +{ + extern void _start (void); + unsigned long flags; + + /* + * Install a translation register that identity maps the + * kernel's 256MB page(s). + */ + ia64_clear_ic(flags); + ia64_set_rr( 0, (0x1000 << 8) | (_PAGE_SIZE_1M << 2)); + ia64_set_rr(PAGE_OFFSET, (ia64_rid(0, PAGE_OFFSET) << 8) | (_PAGE_SIZE_256M << 2)); + ia64_srlz_d(); + ia64_itr(0x3, 1, PAGE_OFFSET, + pte_val(mk_pte_phys(0, __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX))), + _PAGE_SIZE_256M); + ia64_srlz_i(); + + flags = (IA64_PSR_IT | IA64_PSR_IC | IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_DFH | + IA64_PSR_BN); + + asm volatile ("movl r8 = 1f\n" + ";;\n" + "mov cr.ipsr=%0\n" + "mov cr.iip=r8\n" + "mov cr.ifs=r0\n" + ";;\n" + "rfi;;" + "1:\n" + "movl r1 = __gp" :: "r"(flags) : "r8"); + _start(); +} + diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index a3e5242fc..f78512229 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -147,7 +147,7 @@ sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, l struct pt_regs *regs = (struct pt_regs *) &stack; addr = do_mmap2(addr, len, prot, flags, fd, pgoff); - if (!IS_ERR(addr)) + if (!IS_ERR((void *) addr)) regs->r8 = 0; /* ensure large addresses are not mistaken as failures... */ return addr; } @@ -162,26 +162,12 @@ sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, return -EINVAL; addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); - if (!IS_ERR(addr)) + if (!IS_ERR((void *) addr)) regs->r8 = 0; /* ensure large addresses are not mistaken as failures... */ return addr; } asmlinkage long -sys_ioperm (unsigned long from, unsigned long num, int on) -{ - printk(KERN_ERR "sys_ioperm(from=%lx, num=%lx, on=%d)\n", from, num, on); - return -EIO; -} - -asmlinkage long -sys_iopl (int level, long arg1, long arg2, long arg3) -{ - printk(KERN_ERR "sys_iopl(level=%d)!\n", level); - return -ENOSYS; -} - -asmlinkage long sys_vm86 (long arg0, long arg1, long arg2, long arg3) { printk(KERN_ERR "sys_vm86(%lx, %lx, %lx, %lx)!\n", arg0, arg1, arg2, arg3); @@ -204,7 +190,7 @@ ia64_create_module (const char *name_user, size_t size, long arg2, long arg3, unsigned long addr; addr = sys_create_module (name_user, size); - if (!IS_ERR(addr)) + if (!IS_ERR((void *) addr)) regs->r8 = 0; /* ensure large addresses are not mistaken as failures... */ return addr; } diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 96ff76c01..5e54e4f4b 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -183,7 +183,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) #ifdef CONFIG_SMP smp_do_timer(regs); - if (smp_processor_id() == bootstrap_processor) + if (smp_processor_id() == 0) do_timer(regs); #else do_timer(regs); @@ -303,7 +303,7 @@ ia64_init_itm (void) itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den; itm.delta = itc_freq / HZ; - printk("timer: CPU %d base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, ITC freq=%lu.%03luMHz\n", + printk("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); diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index bf1abd839..43340bf85 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -192,38 +192,45 @@ ia64_ni_syscall (unsigned long arg0, unsigned long arg1, unsigned long arg2, uns } /* - * disabled_fp_fault() is called when a user-level process attempts to - * access one of the registers f32..f127 while it doesn't own the + * disabled_fph_fault() is called when a user-level process attempts + * to access one of the registers f32..f127 when it doesn't own the * fp-high register partition. When this happens, we save the current * fph partition in the task_struct of the fpu-owner (if necessary) * and then load the fp-high partition of the current task (if - * necessary). + * necessary). Note that the kernel has access to fph by the time we + * get here, as the IVT's "Diabled FP-Register" handler takes care of + * clearing psr.dfh. */ static inline void disabled_fph_fault (struct pt_regs *regs) { - struct task_struct *fpu_owner = ia64_get_fpu_owner(); + struct ia64_psr *psr = ia64_psr(regs); - /* first, clear psr.dfh and psr.mfh: */ - regs->cr_ipsr &= ~(IA64_PSR_DFH | IA64_PSR_MFH); - if (fpu_owner != current) { - ia64_set_fpu_owner(current); + /* first, grant user-level access to fph partition: */ + psr->dfh = 0; +#ifndef CONFIG_SMP + { + struct task_struct *fpu_owner = ia64_get_fpu_owner(); - if (fpu_owner && ia64_psr(ia64_task_regs(fpu_owner))->mfh) { - ia64_psr(ia64_task_regs(fpu_owner))->mfh = 0; - fpu_owner->thread.flags |= IA64_THREAD_FPH_VALID; - __ia64_save_fpu(fpu_owner->thread.fph); - } - if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) { - __ia64_load_fpu(current->thread.fph); - } else { - __ia64_init_fpu(); - /* - * Set mfh because the state in thread.fph does not match - * the state in the fph partition. - */ - ia64_psr(regs)->mfh = 1; - } + if (fpu_owner == current) + return; + + if (fpu_owner) + ia64_flush_fph(fpu_owner); + + ia64_set_fpu_owner(current); + } +#endif /* !CONFIG_SMP */ + if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) { + __ia64_load_fpu(current->thread.fph); + psr->mfh = 0; + } else { + __ia64_init_fpu(); + /* + * Set mfh because the state in thread.fph does not match the state in + * the fph partition. + */ + psr->mfh = 1; } } @@ -247,20 +254,21 @@ fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long * kernel, so set those bits in the mask and set the low volatile * pointer to point to these registers. */ - fp_state.bitmask_low64 = 0xffc0; /* bit6..bit15 */ #ifndef FPSWA_BUG - fp_state.fp_state_low_volatile = ®s->f6; + fp_state.bitmask_low64 = 0x3c0; /* bit 6..9 */ + fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6; #else + fp_state.bitmask_low64 = 0xffc0; /* bit6..bit15 */ f6_15[0] = regs->f6; f6_15[1] = regs->f7; f6_15[2] = regs->f8; f6_15[3] = regs->f9; - __asm__ ("stf.spill %0=f10" : "=m"(f6_15[4])); - __asm__ ("stf.spill %0=f11" : "=m"(f6_15[5])); - __asm__ ("stf.spill %0=f12" : "=m"(f6_15[6])); - __asm__ ("stf.spill %0=f13" : "=m"(f6_15[7])); - __asm__ ("stf.spill %0=f14" : "=m"(f6_15[8])); - __asm__ ("stf.spill %0=f15" : "=m"(f6_15[9])); + __asm__ ("stf.spill %0=f10%P0" : "=m"(f6_15[4])); + __asm__ ("stf.spill %0=f11%P0" : "=m"(f6_15[5])); + __asm__ ("stf.spill %0=f12%P0" : "=m"(f6_15[6])); + __asm__ ("stf.spill %0=f13%P0" : "=m"(f6_15[7])); + __asm__ ("stf.spill %0=f14%P0" : "=m"(f6_15[8])); + __asm__ ("stf.spill %0=f15%P0" : "=m"(f6_15[9])); fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) f6_15; #endif /* @@ -279,12 +287,12 @@ fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long (unsigned long *) isr, (unsigned long *) pr, (unsigned long *) ifs, &fp_state); #ifdef FPSWA_BUG - __asm__ ("ldf.fill f10=%0" :: "m"(f6_15[4])); - __asm__ ("ldf.fill f11=%0" :: "m"(f6_15[5])); - __asm__ ("ldf.fill f12=%0" :: "m"(f6_15[6])); - __asm__ ("ldf.fill f13=%0" :: "m"(f6_15[7])); - __asm__ ("ldf.fill f14=%0" :: "m"(f6_15[8])); - __asm__ ("ldf.fill f15=%0" :: "m"(f6_15[9])); + __asm__ ("ldf.fill f10=%0%P0" :: "m"(f6_15[4])); + __asm__ ("ldf.fill f11=%0%P0" :: "m"(f6_15[5])); + __asm__ ("ldf.fill f12=%0%P0" :: "m"(f6_15[6])); + __asm__ ("ldf.fill f13=%0%P0" :: "m"(f6_15[7])); + __asm__ ("ldf.fill f14=%0%P0" :: "m"(f6_15[8])); + __asm__ ("ldf.fill f15=%0%P0" :: "m"(f6_15[9])); regs->f6 = f6_15[0]; regs->f7 = f6_15[1]; regs->f8 = f6_15[2]; diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index 7ca1146a0..7cc238a83 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c @@ -278,9 +278,9 @@ set_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long val, int nat) bspstore = (unsigned long *)regs->ar_bspstore; DPRINT(("rse_slot_num=0x%lx\n",ia64_rse_slot_num((unsigned long *)sw->ar_bspstore))); - DPRINT(("kbs=%p nlocals=%ld\n", kbs, nlocals)); + DPRINT(("kbs=%p nlocals=%ld\n", (void *) kbs, nlocals)); DPRINT(("bspstore next rnat slot %p\n", - ia64_rse_rnat_addr((unsigned long *)sw->ar_bspstore))); + (void *) ia64_rse_rnat_addr((unsigned long *)sw->ar_bspstore))); DPRINT(("on_kbs=%ld rnats=%ld\n", on_kbs, ((sw->ar_bspstore-(unsigned long)kbs)>>3) - on_kbs)); @@ -292,7 +292,7 @@ set_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long val, int nat) addr = slot = ia64_rse_skip_regs(bsp, r1 - 32); DPRINT(("ubs_end=%p bsp=%p addr=%p slot=0x%lx\n", - ubs_end, bsp, addr, ia64_rse_slot_num(addr))); + (void *) ubs_end, (void *) bsp, (void *) addr, ia64_rse_slot_num(addr))); ia64_poke(regs, current, (unsigned long)addr, val); @@ -303,7 +303,7 @@ set_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long val, int nat) ia64_peek(regs, current, (unsigned long)addr, &rnats); DPRINT(("rnat @%p = 0x%lx nat=%d rnatval=%lx\n", - addr, rnats, nat, rnats &ia64_rse_slot_num(slot))); + (void *) addr, rnats, nat, rnats &ia64_rse_slot_num(slot))); if (nat) { rnats |= __IA64_UL(1) << ia64_rse_slot_num(slot); @@ -312,7 +312,7 @@ set_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long val, int nat) } ia64_poke(regs, current, (unsigned long)addr, rnats); - DPRINT(("rnat changed to @%p = 0x%lx\n", addr, rnats)); + DPRINT(("rnat changed to @%p = 0x%lx\n", (void *) addr, rnats)); } @@ -373,7 +373,7 @@ get_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long *val, int *nat addr = slot = ia64_rse_skip_regs(bsp, r1 - 32); DPRINT(("ubs_end=%p bsp=%p addr=%p slot=0x%lx\n", - ubs_end, bsp, addr, ia64_rse_slot_num(addr))); + (void *) ubs_end, (void *) bsp, (void *) addr, ia64_rse_slot_num(addr))); ia64_peek(regs, current, (unsigned long)addr, val); @@ -383,7 +383,7 @@ get_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long *val, int *nat addr = ia64_rse_rnat_addr(addr); ia64_peek(regs, current, (unsigned long)addr, &rnats); - DPRINT(("rnat @%p = 0x%lx\n", addr, rnats)); + DPRINT(("rnat @%p = 0x%lx\n", (void *) addr, rnats)); if (nat) *nat = rnats >> ia64_rse_slot_num(slot) & 0x1; @@ -437,13 +437,13 @@ setreg(unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs) * UNAT bit_pos = GR[r3]{8:3} form EAS-2.4 */ bitmask = __IA64_UL(1) << (addr >> 3 & 0x3f); - DPRINT(("*0x%lx=0x%lx NaT=%d prev_unat @%p=%lx\n", addr, val, nat, unat, *unat)); + DPRINT(("*0x%lx=0x%lx NaT=%d prev_unat @%p=%lx\n", addr, val, nat, (void *) unat, *unat)); if (nat) { *unat |= bitmask; } else { *unat &= ~bitmask; } - DPRINT(("*0x%lx=0x%lx NaT=%d new unat: %p=%lx\n", addr, val, nat, unat,*unat)); + DPRINT(("*0x%lx=0x%lx NaT=%d new unat: %p=%lx\n", addr, val, nat, (void *) unat,*unat)); } #define IA64_FPH_OFFS(r) (r - IA64_FIRST_ROTATING_FR) @@ -455,16 +455,15 @@ setfpreg(unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs) unsigned long addr; /* - * From EAS-2.5: FPDisableFault has higher priority than - * Unaligned Fault. Thus, when we get here, we know the partition is - * enabled. + * From EAS-2.5: FPDisableFault has higher priority than Unaligned + * Fault. Thus, when we get here, we know the partition is enabled. + * To update f32-f127, there are three choices: + * + * (1) save f32-f127 to thread.fph and update the values there + * (2) use a gigantic switch statement to directly access the registers + * (3) generate code on the fly to update the desired register * - * The registers [32-127] are ususally saved in the tss. When get here, - * they are NECESSARILY live because they are only saved explicitely. - * We have 3 ways of updating the values: force a save of the range - * in tss, use a gigantic switch/case statement or generate code on the - * fly to store to the right register. - * For now, we are using the (slow) save/restore way. + * For now, we are using approach (1). */ if (regnum >= IA64_FIRST_ROTATING_FR) { ia64_sync_fph(current); @@ -491,7 +490,6 @@ setfpreg(unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs) * let's do it for safety. */ regs->cr_ipsr |= IA64_PSR_MFL; - } } @@ -522,12 +520,12 @@ getfpreg(unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs) * Unaligned Fault. Thus, when we get here, we know the partition is * enabled. * - * When regnum > 31, the register is still live and - * we need to force a save to the tss to get access to it. - * See discussion in setfpreg() for reasons and other ways of doing this. + * When regnum > 31, the register is still live and we need to force a save + * to current->thread.fph to get access to it. See discussion in setfpreg() + * for reasons and other ways of doing this. */ if (regnum >= IA64_FIRST_ROTATING_FR) { - ia64_sync_fph(current); + ia64_flush_fph(current); *fpval = current->thread.fph[IA64_FPH_OFFS(regnum)]; } else { /* @@ -1084,9 +1082,9 @@ emulate_load_floatpair(unsigned long ifa, load_store_t *ld, struct pt_regs *regs /* * XXX fixme * - * A possible optimization would be to drop fpr_final - * and directly use the storage from the saved context i.e., - * the actual final destination (pt_regs, switch_stack or tss). + * A possible optimization would be to drop fpr_final and directly + * use the storage from the saved context i.e., the actual final + * destination (pt_regs, switch_stack or thread structure). */ setfpreg(ld->r1, &fpr_final[0], regs); setfpreg(ld->imm, &fpr_final[1], regs); @@ -1212,9 +1210,9 @@ emulate_load_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs) /* * XXX fixme * - * A possible optimization would be to drop fpr_final - * and directly use the storage from the saved context i.e., - * the actual final destination (pt_regs, switch_stack or tss). + * A possible optimization would be to drop fpr_final and directly + * use the storage from the saved context i.e., the actual final + * destination (pt_regs, switch_stack or thread structure). */ setfpreg(ld->r1, &fpr_final, regs); } @@ -1223,9 +1221,7 @@ emulate_load_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs) * check for updates on any loads */ if (ld->op == 0x7 || ld->m) - emulate_load_updates(ld->op == 0x7 ? UPD_IMMEDIATE: UPD_REG, - ld, regs, ifa); - + emulate_load_updates(ld->op == 0x7 ? UPD_IMMEDIATE: UPD_REG, ld, regs, ifa); /* * invalidate ALAT entry in case of advanced floating point loads diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index 5d0049f32..21a2ead16 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c @@ -66,7 +66,7 @@ #define UNW_STATS 0 /* WARNING: this disabled interrupts for long time-spans!! */ #if UNW_DEBUG - static long unw_debug_level = 1; + static long unw_debug_level = 255; # define debug(level,format...) if (unw_debug_level > level) printk(format) # define dprintk(format...) printk(format) # define inline @@ -111,7 +111,7 @@ static struct { struct unw_table kernel_table; /* hash table that maps instruction pointer to script index: */ - unw_hash_index_t hash[UNW_HASH_SIZE]; + unsigned short hash[UNW_HASH_SIZE]; /* script cache: */ struct unw_script cache[UNW_CACHE_SIZE]; @@ -152,47 +152,47 @@ static struct { UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR }, preg_index: { - struct_offset(struct unw_frame_info, pri_unat)/8, /* PRI_UNAT_GR */ - struct_offset(struct unw_frame_info, pri_unat)/8, /* PRI_UNAT_MEM */ - struct_offset(struct unw_frame_info, pbsp)/8, - struct_offset(struct unw_frame_info, bspstore)/8, - struct_offset(struct unw_frame_info, pfs)/8, - struct_offset(struct unw_frame_info, rnat)/8, + 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)/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)/8, - struct_offset(struct unw_frame_info, pr)/8, - struct_offset(struct unw_frame_info, lc)/8, - struct_offset(struct unw_frame_info, fpsr)/8, - struct_offset(struct unw_frame_info, b1)/8, - struct_offset(struct unw_frame_info, b2)/8, - struct_offset(struct unw_frame_info, b3)/8, - struct_offset(struct unw_frame_info, b4)/8, - struct_offset(struct unw_frame_info, b5)/8, - struct_offset(struct unw_frame_info, f2)/8, - struct_offset(struct unw_frame_info, f3)/8, - struct_offset(struct unw_frame_info, f4)/8, - struct_offset(struct unw_frame_info, f5)/8, - struct_offset(struct unw_frame_info, fr[16 - 16])/8, - struct_offset(struct unw_frame_info, fr[17 - 16])/8, - struct_offset(struct unw_frame_info, fr[18 - 16])/8, - struct_offset(struct unw_frame_info, fr[19 - 16])/8, - struct_offset(struct unw_frame_info, fr[20 - 16])/8, - struct_offset(struct unw_frame_info, fr[21 - 16])/8, - struct_offset(struct unw_frame_info, fr[22 - 16])/8, - struct_offset(struct unw_frame_info, fr[23 - 16])/8, - struct_offset(struct unw_frame_info, fr[24 - 16])/8, - struct_offset(struct unw_frame_info, fr[25 - 16])/8, - struct_offset(struct unw_frame_info, fr[26 - 16])/8, - struct_offset(struct unw_frame_info, fr[27 - 16])/8, - struct_offset(struct unw_frame_info, fr[28 - 16])/8, - struct_offset(struct unw_frame_info, fr[29 - 16])/8, - struct_offset(struct unw_frame_info, fr[30 - 16])/8, - struct_offset(struct unw_frame_info, fr[31 - 16])/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, }, hash : { [0 ... UNW_HASH_SIZE - 1] = -1 }, #if UNW_DEBUG @@ -211,6 +211,27 @@ static struct { /* Unwind accessors. */ +/* + * Returns offset of rREG in struct pt_regs. + */ +static inline unsigned long +pt_regs_off (unsigned long reg) +{ + unsigned long off =0; + + 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; +} + int unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write) { @@ -251,26 +272,23 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char } /* fall through */ case UNW_NAT_NONE: + dummy_nat = 0; nat_addr = &dummy_nat; break; - case UNW_NAT_SCRATCH: - if (info->pri_unat) - nat_addr = info->pri_unat; - else - nat_addr = &info->sw->caller_unat; - case UNW_NAT_PRI_UNAT: + case UNW_NAT_MEMSTK: nat_mask = (1UL << ((long) addr & 0x1f8)/8); break; - case UNW_NAT_STACKED: + case UNW_NAT_REGSTK: nat_addr = ia64_rse_rnat_addr(addr); if ((unsigned long) addr < info->regstk.limit || (unsigned long) addr >= info->regstk.top) { - dprintk("unwind: 0x%p outside of regstk " - "[0x%lx-0x%lx)\n", addr, - info->regstk.limit, info->regstk.top); + dprintk("unwind: %p outside of regstk " + "[0x%lx-0x%lx)\n", (void *) addr, + info->regstk.limit, + info->regstk.top); return -1; } if ((unsigned long) nat_addr >= info->regstk.top) @@ -289,18 +307,11 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char pt = (struct pt_regs *) info->psp - 1; else pt = (struct pt_regs *) info->sp - 1; - if (regnum <= 3) - addr = &pt->r1 + (regnum - 1); - else if (regnum <= 11) - addr = &pt->r8 + (regnum - 8); - else if (regnum <= 15) - addr = &pt->r12 + (regnum - 12); - else - addr = &pt->r16 + (regnum - 16); - if (info->pri_unat) - nat_addr = info->pri_unat; + addr = (unsigned long *) ((long) pt + pt_regs_off(regnum)); + if (info->pri_unat_loc) + nat_addr = info->pri_unat_loc; else - nat_addr = &info->sw->caller_unat; + nat_addr = &info->sw->ar_unat; nat_mask = (1UL << ((long) addr & 0x1f8)/8); } } else { @@ -320,7 +331,10 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char if (write) { *addr = *val; - *nat_addr = (*nat_addr & ~nat_mask) | nat_mask; + if (*nat) + *nat_addr |= nat_mask; + else + *nat_addr &= ~nat_mask; } else { *val = *addr; *nat = (*nat_addr & nat_mask) != 0; @@ -346,7 +360,7 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int /* preserved: */ case 1: case 2: case 3: case 4: case 5: - addr = *(&info->b1 + (regnum - 1)); + addr = *(&info->b1_loc + (regnum - 1)); if (!addr) addr = &info->sw->b1 + (regnum - 1); break; @@ -379,7 +393,7 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, pt = (struct pt_regs *) info->sp - 1; if (regnum <= 5) { - addr = *(&info->f2 + (regnum - 2)); + addr = *(&info->f2_loc + (regnum - 2)); if (!addr) addr = &info->sw->f2 + (regnum - 2); } else if (regnum <= 15) { @@ -388,13 +402,16 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, else addr = &info->sw->f10 + (regnum - 10); } else if (regnum <= 31) { - addr = info->fr[regnum - 16]; + addr = info->fr_loc[regnum - 16]; if (!addr) addr = &info->sw->f16 + (regnum - 16); } else { struct task_struct *t = info->task; - ia64_sync_fph(t); + if (write) + ia64_sync_fph(t); + else + ia64_flush_fph(t); addr = t->thread.fph + (regnum - 32); } @@ -418,52 +435,53 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int switch (regnum) { case UNW_AR_BSP: - addr = info->pbsp; + addr = info->bsp_loc; if (!addr) addr = &info->sw->ar_bspstore; break; case UNW_AR_BSPSTORE: - addr = info->bspstore; + addr = info->bspstore_loc; if (!addr) addr = &info->sw->ar_bspstore; break; case UNW_AR_PFS: - addr = info->pfs; + addr = info->pfs_loc; if (!addr) addr = &info->sw->ar_pfs; break; case UNW_AR_RNAT: - addr = info->rnat; + addr = info->rnat_loc; if (!addr) addr = &info->sw->ar_rnat; break; case UNW_AR_UNAT: - addr = info->unat; + addr = info->unat_loc; if (!addr) addr = &info->sw->ar_unat; break; case UNW_AR_LC: - addr = info->lc; + addr = info->lc_loc; if (!addr) addr = &info->sw->ar_lc; break; case UNW_AR_EC: - if (!info->cfm) + if (!info->cfm_loc) return -1; if (write) - *info->cfm = (*info->cfm & ~(0x3fUL << 52)) | ((*val & 0x3f) << 52); + *info->cfm_loc = + (*info->cfm_loc & ~(0x3fUL << 52)) | ((*val & 0x3f) << 52); else - *val = (*info->cfm >> 52) & 0x3f; + *val = (*info->cfm_loc >> 52) & 0x3f; return 0; case UNW_AR_FPSR: - addr = info->fpsr; + addr = info->fpsr_loc; if (!addr) addr = &info->sw->ar_fpsr; break; @@ -493,7 +511,7 @@ unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write) { unsigned long *addr; - addr = info->pr; + addr = info->pr_loc; if (!addr) addr = &info->sw->pr; @@ -605,9 +623,8 @@ finish_prologue (struct unw_state_record *sr) int i; /* - * First, resolve implicit register save locations - * (see Section "11.4.2.3 Rules for Using Unwind - * Descriptors", rule 3): + * 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) { reg = sr->curr.reg + unw.save_order[i]; @@ -1045,16 +1062,16 @@ desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word static inline unw_hash_index_t hash (unsigned long ip) { -# define magic 0x9e3779b97f4a7c16 /* (sqrt(5)/2-1)*2^64 */ +# define magic 0x9e3779b97f4a7c16 /* based on (sqrt(5)/2-1)*2^64 */ return (ip >> 4)*magic >> (64 - UNW_LOG_HASH_SIZE); } static inline long -cache_match (struct unw_script *script, unsigned long ip, unsigned long pr_val) +cache_match (struct unw_script *script, unsigned long ip, unsigned long pr) { read_lock(&script->lock); - if ((ip) == (script)->ip && (((pr_val) ^ (script)->pr_val) & (script)->pr_mask) == 0) + if (ip == script->ip && ((pr ^ script->pr_val) & script->pr_mask) == 0) /* keep the read lock... */ return 1; read_unlock(&script->lock); @@ -1065,21 +1082,26 @@ static inline struct unw_script * script_lookup (struct unw_frame_info *info) { struct unw_script *script = unw.cache + info->hint; - unsigned long ip, pr_val; + unsigned short index; + unsigned long ip, pr; STAT(++unw.stat.cache.lookups); ip = info->ip; - pr_val = info->pr_val; + pr = info->pr; - if (cache_match(script, ip, pr_val)) { + if (cache_match(script, ip, pr)) { STAT(++unw.stat.cache.hinted_hits); return script; } - script = unw.cache + unw.hash[hash(ip)]; + index = unw.hash[hash(ip)]; + if (index >= UNW_CACHE_SIZE) + return 0; + + script = unw.cache + index; while (1) { - if (cache_match(script, ip, pr_val)) { + if (cache_match(script, ip, pr)) { /* update hint; no locking required as single-word writes are atomic */ STAT(++unw.stat.cache.normal_hits); unw.cache[info->prev_script].hint = script - unw.cache; @@ -1099,8 +1121,8 @@ static inline struct unw_script * script_new (unsigned long ip) { struct unw_script *script, *prev, *tmp; + unw_hash_index_t index; unsigned long flags; - unsigned char index; unsigned short head; STAT(++unw.stat.script.news); @@ -1133,22 +1155,24 @@ script_new (unsigned long ip) unw.lru_tail = head; /* remove the old script from the hash table (if it's there): */ - index = hash(script->ip); - tmp = unw.cache + unw.hash[index]; - prev = 0; - while (1) { - if (tmp == script) { - if (prev) - prev->coll_chain = tmp->coll_chain; - else - unw.hash[index] = tmp->coll_chain; - break; - } else - prev = tmp; - if (tmp->coll_chain >= UNW_CACHE_SIZE) + if (script->ip) { + index = hash(script->ip); + tmp = unw.cache + unw.hash[index]; + prev = 0; + while (1) { + if (tmp == script) { + if (prev) + prev->coll_chain = tmp->coll_chain; + else + unw.hash[index] = tmp->coll_chain; + break; + } else + prev = tmp; + if (tmp->coll_chain >= UNW_CACHE_SIZE) /* old script wasn't in the hash-table */ - break; - tmp = unw.cache + tmp->coll_chain; + break; + tmp = unw.cache + tmp->coll_chain; + } } /* enter new script in the hash table */ @@ -1198,19 +1222,17 @@ emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script) struct unw_reg_info *r = sr->curr.reg + i; enum unw_insn_opcode opc; struct unw_insn insn; - unsigned long val; + unsigned long val = 0; switch (r->where) { case UNW_WHERE_GR: if (r->val >= 32) { /* register got spilled to a stacked register */ opc = UNW_INSN_SETNAT_TYPE; - val = UNW_NAT_STACKED; - } else { + val = UNW_NAT_REGSTK; + } else /* register got spilled to a scratch register */ - opc = UNW_INSN_SETNAT_TYPE; - val = UNW_NAT_SCRATCH; - } + opc = UNW_INSN_SETNAT_MEMSTK; break; case UNW_WHERE_FR: @@ -1225,8 +1247,7 @@ emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script) case UNW_WHERE_PSPREL: case UNW_WHERE_SPREL: - opc = UNW_INSN_SETNAT_PRI_UNAT; - val = 0; + opc = UNW_INSN_SETNAT_MEMSTK; break; default: @@ -1267,18 +1288,8 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script) } val = unw.preg_index[UNW_REG_R4 + (rval - 4)]; } else { - opc = UNW_INSN_LOAD_SPREL; - val = -sizeof(struct pt_regs); - if (rval >= 1 && rval <= 3) - val += struct_offset(struct pt_regs, r1) + 8*(rval - 1); - else if (rval <= 11) - val += struct_offset(struct pt_regs, r8) + 8*(rval - 8); - else if (rval <= 15) - val += struct_offset(struct pt_regs, r12) + 8*(rval - 12); - else if (rval <= 31) - val += struct_offset(struct pt_regs, r16) + 8*(rval - 16); - else - dprintk("unwind: bad scratch reg r%lu\n", rval); + opc = UNW_INSN_ADD_SP; + val = -sizeof(struct pt_regs) + pt_regs_off(rval); } break; @@ -1288,7 +1299,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script) else if (rval >= 16 && rval <= 31) val = unw.preg_index[UNW_REG_F16 + (rval - 16)]; else { - opc = UNW_INSN_LOAD_SPREL; + opc = UNW_INSN_ADD_SP; val = -sizeof(struct pt_regs); if (rval <= 9) val += struct_offset(struct pt_regs, f6) + 16*(rval - 6); @@ -1301,7 +1312,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script) if (rval >= 1 && rval <= 5) val = unw.preg_index[UNW_REG_B1 + (rval - 1)]; else { - opc = UNW_INSN_LOAD_SPREL; + opc = UNW_INSN_ADD_SP; val = -sizeof(struct pt_regs); if (rval == 0) val += struct_offset(struct pt_regs, b0); @@ -1313,11 +1324,11 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script) break; case UNW_WHERE_SPREL: - opc = UNW_INSN_LOAD_SPREL; + opc = UNW_INSN_ADD_SP; break; case UNW_WHERE_PSPREL: - opc = UNW_INSN_LOAD_PSPREL; + opc = UNW_INSN_ADD_PSP; break; default: @@ -1330,6 +1341,18 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script) script_emit(script, insn); if (need_nat_info) emit_nat_info(sr, i, script); + + if (i == UNW_REG_PSP) { + /* + * info->psp must contain the _value_ of the previous + * sp, not it's save location. We get this by + * dereferencing the value we just stored in + * info->psp: + */ + insn.opc = UNW_INSN_LOAD; + insn.dst = insn.val = unw.preg_index[UNW_REG_PSP]; + script_emit(script, insn); + } } static inline struct unw_table_entry * @@ -1378,7 +1401,7 @@ build_script (struct unw_frame_info *info) memset(&sr, 0, sizeof(sr)); for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) r->when = UNW_WHEN_NEVER; - sr.pr_val = info->pr_val; + sr.pr_val = info->pr; script = script_new(ip); if (!script) { @@ -1447,8 +1470,8 @@ build_script (struct unw_frame_info *info) } #if UNW_DEBUG - printk ("unwind: state record for func 0x%lx, t=%u:\n", - table->segment_base + e->start_offset, sr.when_target); + printk("unwind: state record for func 0x%lx, t=%u:\n", + 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]); @@ -1463,7 +1486,7 @@ build_script (struct unw_frame_info *info) break; default: printk("BADWHERE(%d)", r->where); break; } - printk ("\t\t%d\n", r->when); + printk("\t\t%d\n", r->when); } } #endif @@ -1472,13 +1495,17 @@ build_script (struct unw_frame_info *info) /* translate state record into unwinder instructions: */ - if (sr.curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE - && sr.when_target > sr.curr.reg[UNW_REG_PSP].when && sr.curr.reg[UNW_REG_PSP].val != 0) - { + /* + * First, set psp if we're dealing with a fixed-size frame; + * subsequent instructions may depend on this value. + */ + if (sr.when_target > sr.curr.reg[UNW_REG_PSP].when + && (sr.curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE) + && sr.curr.reg[UNW_REG_PSP].val != 0) { /* new psp is sp plus frame size */ insn.opc = UNW_INSN_ADD; - insn.dst = unw.preg_index[UNW_REG_PSP]; - insn.val = sr.curr.reg[UNW_REG_PSP].val; + insn.dst = struct_offset(struct unw_frame_info, psp)/8; + insn.val = sr.curr.reg[UNW_REG_PSP].val; /* frame size */ script_emit(script, insn); } @@ -1562,23 +1589,34 @@ run_script (struct unw_script *script, struct unw_frame_info *state) val); break; - case UNW_INSN_LOAD_PSPREL: + case UNW_INSN_ADD_PSP: s[dst] = state->psp + val; break; - case UNW_INSN_LOAD_SPREL: + case UNW_INSN_ADD_SP: s[dst] = state->sp + val; break; - case UNW_INSN_SETNAT_PRI_UNAT: - if (!state->pri_unat) - state->pri_unat = &state->sw->caller_unat; - s[dst+1] = ((*state->pri_unat - s[dst]) << 32) | UNW_NAT_PRI_UNAT; + case UNW_INSN_SETNAT_MEMSTK: + if (!state->pri_unat_loc) + state->pri_unat_loc = &state->sw->ar_unat; + /* register off. is a multiple of 8, so the least 3 bits (type) are 0 */ + s[dst+1] = (*state->pri_unat_loc - s[dst]) | UNW_NAT_MEMSTK; break; case UNW_INSN_SETNAT_TYPE: s[dst+1] = val; break; + + case UNW_INSN_LOAD: +#if UNW_DEBUG + if ((s[val] & (my_cpu_data.unimpl_va_mask | 0x7)) || s[val] < TASK_SIZE) { + debug(1, "unwind: rejecting bad psp=0x%lx\n", s[val]); + break; + } +#endif + s[dst] = *(unsigned long *) s[val]; + break; } } STAT(unw.stat.script.run_time += ia64_get_itc() - start); @@ -1587,13 +1625,14 @@ run_script (struct unw_script *script, struct unw_frame_info *state) lazy_init: off = unw.sw_off[val]; s[val] = (unsigned long) state->sw + off; - if (off >= struct_offset (struct unw_frame_info, r4) - && off <= struct_offset (struct unw_frame_info, r7)) + if (off >= struct_offset(struct switch_stack, r4) + && off <= struct_offset(struct switch_stack, r7)) /* - * We're initializing a general register: init NaT info, too. Note that we - * rely on the fact that call_unat is the first field in struct switch_stack: + * 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] = (-off << 32) | UNW_NAT_PRI_UNAT; + s[val+1] = (struct_offset(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK; goto redo; } @@ -1603,11 +1642,10 @@ find_save_locs (struct unw_frame_info *info) int have_write_lock = 0; struct unw_script *scr; - if ((info->ip & (my_cpu_data.unimpl_va_mask | 0xf)) || rgn_index(info->ip) != RGN_KERNEL) - { + if ((info->ip & (my_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); - info->rp = 0; + info->rp_loc = 0; return -1; } @@ -1648,12 +1686,12 @@ unw_unwind (struct unw_frame_info *info) prev_bsp = info->bsp; /* restore the ip */ - if (!info->rp) { + if (!info->rp_loc) { debug(1, "unwind: failed to locate return link (ip=0x%lx)!\n", info->ip); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } - ip = info->ip = *info->rp; + ip = info->ip = *info->rp_loc; if (ip < GATE_ADDR + PAGE_SIZE) { /* * We don't have unwind info for the gate page, so we consider that part @@ -1665,23 +1703,23 @@ unw_unwind (struct unw_frame_info *info) } /* restore the cfm: */ - if (!info->pfs) { + if (!info->pfs_loc) { dprintk("unwind: failed to locate ar.pfs!\n"); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } - info->cfm = info->pfs; + info->cfm_loc = info->pfs_loc; /* restore the bsp: */ - pr = info->pr_val; + pr = info->pr; num_regs = 0; if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) { if ((pr & (1UL << pNonSys)) != 0) - num_regs = *info->cfm & 0x7f; /* size of frame */ - info->pfs = + num_regs = *info->cfm_loc & 0x7f; /* size of frame */ + info->pfs_loc = (unsigned long *) (info->sp + 16 + struct_offset(struct pt_regs, ar_pfs)); } else - num_regs = (*info->cfm >> 7) & 0x7f; /* size of locals */ + 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", @@ -1694,7 +1732,7 @@ unw_unwind (struct unw_frame_info *info) 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->regstk.top, info->regstk.limit); + info->sp, info->memstk.top, info->memstk.limit); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } @@ -1705,8 +1743,11 @@ unw_unwind (struct unw_frame_info *info) return -1; } + /* as we unwind, the saved ar.unat becomes the primary unat: */ + info->pri_unat_loc = info->unat_loc; + /* finally, restore the predicates: */ - unw_get_pr(info, &info->pr_val); + unw_get_pr(info, &info->pr); retval = find_save_locs(info); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); @@ -1773,11 +1814,11 @@ unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct info->task = t; info->sw = sw; info->sp = info->psp = (unsigned long) (sw + 1) - 16; - info->cfm = &sw->ar_pfs; - sol = (*info->cfm >> 7) & 0x7f; + 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_val = sw->pr; + info->pr = sw->pr; find_save_locs(info); STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags)); @@ -1808,7 +1849,7 @@ unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t) info->regstk.top = top; info->sw = sw; info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol); - info->cfm = &sw->ar_pfs; + info->cfm_loc = &sw->ar_pfs; info->ip = sw->b0; #endif } @@ -1845,7 +1886,7 @@ unw_init_from_current (struct unw_frame_info *info, struct pt_regs *regs) info->regstk.top = top; info->sw = sw; info->bsp = (unsigned long) ia64_rse_skip_regs(bsp, -sof); - info->cfm = ®s->cr_ifs; + info->cfm_loc = ®s->cr_ifs; info->ip = regs->cr_iip; #endif } @@ -1881,7 +1922,7 @@ read_reg (struct unw_frame_info *info, int regnum, int *is_nat) int unw_unwind (struct unw_frame_info *info) { - unsigned long sol, cfm = *info->cfm; + unsigned long sol, cfm = *info->cfm_loc; int is_nat; sol = (cfm >> 7) & 0x7f; /* size of locals */ @@ -1903,7 +1944,7 @@ unw_unwind (struct unw_frame_info *info) /* reject let obviously bad addresses */ return -1; - info->cfm = ia64_rse_skip_regs((unsigned long *) info->bsp, sol - 1); + info->cfm_loc = ia64_rse_skip_regs((unsigned long *) info->bsp, sol - 1); cfm = read_reg(info, sol - 1, &is_nat); if (is_nat) return -1; @@ -2006,7 +2047,7 @@ unw_remove_unwind_table (void *handle) if (prevt->next == table) break; if (!prevt) { - dprintk("unwind: failed to find unwind table %p\n", table); + dprintk("unwind: failed to find unwind table %p\n", (void *) table); spin_unlock_irqrestore(&unw.lock, flags); return; } @@ -2070,9 +2111,9 @@ unw_init (void) for (i = UNW_REG_F16, off = SW(F16); i <= UNW_REG_F31; ++i, off += 16) unw.sw_off[unw.preg_index[i]] = off; - unw.cache[0].coll_chain = -1; - for (i = 1; i < UNW_CACHE_SIZE; ++i) { - unw.cache[i].lru_chain = (i - 1); + for (i = 0; i < UNW_CACHE_SIZE; ++i) { + if (i > 0) + unw.cache[i].lru_chain = (i - 1); unw.cache[i].coll_chain = -1; unw.cache[i].lock = RW_LOCK_UNLOCKED; } diff --git a/arch/ia64/kernel/unwind_i.h b/arch/ia64/kernel/unwind_i.h index fea655efd..383d65eff 100644 --- a/arch/ia64/kernel/unwind_i.h +++ b/arch/ia64/kernel/unwind_i.h @@ -115,21 +115,21 @@ struct unw_state_record { enum unw_nat_type { UNW_NAT_NONE, /* NaT not represented */ UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */ - UNW_NAT_PRI_UNAT, /* NaT value is in unat word at offset OFF */ - UNW_NAT_SCRATCH, /* NaT value is in scratch.pri_unat */ - UNW_NAT_STACKED /* NaT is in rnat */ + UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */ + UNW_NAT_REGSTK /* NaT is in rnat */ }; enum unw_insn_opcode { UNW_INSN_ADD, /* s[dst] += val */ + UNW_INSN_ADD_PSP, /* s[dst] = (s.psp + val) */ + UNW_INSN_ADD_SP, /* s[dst] = (s.sp + val) */ UNW_INSN_MOVE, /* s[dst] = s[val] */ UNW_INSN_MOVE2, /* s[dst] = s[val]; s[dst+1] = s[val+1] */ UNW_INSN_MOVE_STACKED, /* s[dst] = ia64_rse_skip(*s.bsp, val) */ - UNW_INSN_LOAD_PSPREL, /* s[dst] = *(*s.psp + 8*val) */ - UNW_INSN_LOAD_SPREL, /* s[dst] = *(*s.sp + 8*val) */ - UNW_INSN_SETNAT_PRI_UNAT, /* s[dst+1].nat.type = PRI_UNAT; + 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_SETNAT_TYPE, /* s[dst+1].nat.type = val */ + UNW_INSN_LOAD /* s[dst] = *s[val] */ }; struct unw_insn { diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 318e314cc..90e697179 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -3,30 +3,49 @@ # .S.o: - $(CC) $(AFLAGS) -c $< -o $@ + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c $< -o $@ L_TARGET = lib.a -L_OBJS = __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \ - checksum.o clear_page.o csum_partial_copy.o copy_page.o \ - copy_user.o clear_user.o memcpy.o memset.o strncpy_from_user.o \ - strlen.o strlen_user.o strnlen_user.o \ +L_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ + __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \ + checksum.o clear_page.o csum_partial_copy.o copy_page.o \ + copy_user.o clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ flush.o do_csum.o +ifneq ($(CONFIG_ITANIUM_ASTEP_SPECIFIC),y) + L_OBJS += memcpy.o memset.o strlen.o +endif + LX_OBJS = io.o -IGNORE_FLAGS_OBJS = __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o +IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ + __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o -include $(TOPDIR)/Rules.make +$(L_TARGET): + +__divdi3.o: idiv64.S + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $@ $< + +__udivdi3.o: idiv64.S + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DUNSIGNED -c -o $@ $< -__divdi3.o: idiv.S - $(CC) $(AFLAGS) -c -o $@ $< +__moddi3.o: idiv64.S + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DMODULO -c -o $@ $< -__udivdi3.o: idiv.S - $(CC) $(AFLAGS) -c -DUNSIGNED -c -o $@ $< +__umoddi3.o: idiv64.S + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DMODULO -DUNSIGNED -c -o $@ $< -__moddi3.o: idiv.S - $(CC) $(AFLAGS) -c -DMODULO -c -o $@ $< +__divsi3.o: idiv32.S + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $@ $< -__umoddi3.o: idiv.S - $(CC) $(AFLAGS) -c -DMODULO -DUNSIGNED -c -o $@ $< +__udivsi3.o: idiv32.S + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DUNSIGNED -c -o $@ $< + +__modsi3.o: idiv32.S + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DMODULO -c -o $@ $< + +__umodsi3.o: idiv32.S + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DMODULO -DUNSIGNED -c -o $@ $< + +include $(TOPDIR)/Rules.make diff --git a/arch/ia64/lib/idiv32.S b/arch/ia64/lib/idiv32.S new file mode 100644 index 000000000..13f4608c3 --- /dev/null +++ b/arch/ia64/lib/idiv32.S @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2000 Hewlett-Packard Co + * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com> + * + * 32-bit integer division. + * + * This code is based on the application note entitled "Divide, Square Root + * and Remainder Algorithms for the IA-64 Architecture". This document + * is available as Intel document number 248725-002 or via the web at + * http://developer.intel.com/software/opensource/numerics/ + * + * For more details on the theory behind these algorithms, see "IA-64 + * and Elementary Functions" by Peter Markstein; HP Professional Books + * (http://www.hp.com/go/retailbooks/) + */ + +#include <asm/asmmacro.h> + +#ifdef MODULO +# define OP mod +#else +# define OP div +#endif + +#ifdef UNSIGNED +# define SGN u +# define EXTEND zxt4 +# define INT_TO_FP(a,b) fcvt.xuf.s1 a=b +# define FP_TO_INT(a,b) fcvt.fxu.trunc.s1 a=b +#else +# define SGN +# define EXTEND sxt4 +# define INT_TO_FP(a,b) fcvt.xf a=b +# define FP_TO_INT(a,b) fcvt.fx.trunc.s1 a=b +#endif + +#define PASTE1(a,b) a##b +#define PASTE(a,b) PASTE1(a,b) +#define NAME PASTE(PASTE(__,SGN),PASTE(OP,si3)) + +GLOBAL_ENTRY(NAME) + .regstk 2,0,0,0 + // Transfer inputs to FP registers. + mov r2 = 0xffdd // r2 = -34 + 65535 (fp reg format bias) + EXTEND in0 = in0 // in0 = a + EXTEND in1 = in1 // in1 = b + ;; + setf.sig f8 = in0 + setf.sig f9 = in1 +#ifdef MODULO + sub in1 = r0, in1 // in1 = -b +#endif + ;; + // Convert the inputs to FP, to avoid FP software-assist faults. + INT_TO_FP(f8, f8) + INT_TO_FP(f9, f9) + ;; + setf.exp f7 = r2 // f7 = 2^-34 + frcpa.s1 f6, p6 = f8, f9 // y0 = frcpa(b) + ;; +(p6) fmpy.s1 f8 = f8, f6 // q0 = a*y0 +(p6) fnma.s1 f6 = f9, f6, f1 // e0 = -b*y0 + 1 + ;; +#ifdef MODULO + setf.sig f9 = in1 // f9 = -b +#endif +(p6) fma.s1 f8 = f6, f8, f8 // q1 = e0*q0 + q0 +(p6) fma.s1 f6 = f6, f6, f7 // e1 = e0*e0 + 2^-34 + ;; +#ifdef MODULO + setf.sig f7 = in0 +#endif +(p6) fma.s1 f6 = f6, f8, f8 // q2 = e1*q1 + q1 + ;; + FP_TO_INT(f6, f6) // q = trunc(q2) + ;; +#ifdef MODULO + xma.l f6 = f6, f9, f7 // r = q*(-b) + a + ;; +#endif + getf.sig r8 = f6 // transfer result to result register + br.ret.sptk rp +END(NAME) diff --git a/arch/ia64/lib/idiv.S b/arch/ia64/lib/idiv64.S index da96863d3..db7d2284e 100644 --- a/arch/ia64/lib/idiv.S +++ b/arch/ia64/lib/idiv64.S @@ -1,25 +1,21 @@ /* - * Integer division routine. - * * Copyright (C) 1999-2000 Hewlett-Packard Co * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com> - */ - -#include <asm/asmmacro.h> - -/* - * Compute a 64-bit unsigned integer quotient. * - * Use reciprocal approximation and Newton-Raphson iteration to compute the - * quotient. frcpa gives 8.6 significant bits, so we need 3 iterations - * to get more than the 64 bits of precision that we need for DImode. + * 64-bit integer division. * - * Must use max precision for the reciprocal computations to get 64 bits of - * precision. + * This code is based on the application note entitled "Divide, Square Root + * and Remainder Algorithms for the IA-64 Architecture". This document + * is available as Intel document number 248725-002 or via the web at + * http://developer.intel.com/software/opensource/numerics/ * - * r32 holds the dividend. r33 holds the divisor. + * For more details on the theory behind these algorithms, see "IA-64 + * and Elementary Functions" by Peter Markstein; HP Professional Books + * (http://www.hp.com/go/retailbooks/) */ +#include <asm/asmmacro.h> + #ifdef MODULO # define OP mod #else @@ -59,40 +55,38 @@ GLOBAL_ENTRY(NAME) UNW(.body) INT_TO_FP(f9, f9) ;; - frcpa.s1 f17, p6 = f8, f9 // y = frcpa(b) + frcpa.s1 f17, p6 = f8, f9 // y0 = frcpa(b) ;; - /* - * This is the magic algorithm described in Section 8.6.2 of "IA-64 - * and Elementary Functions" by Peter Markstein; HP Professional Books - * (http://www.hp.com/go/retailbooks/) - */ -(p6) fmpy.s1 f7 = f8, f17 // q = a*y -(p6) fnma.s1 f6 = f9, f17, f1 // e = -b*y + 1 +(p6) fmpy.s1 f7 = f8, f17 // q0 = a*y0 +(p6) fnma.s1 f6 = f9, f17, f1 // e0 = -b*y0 + 1 ;; -(p6) fma.s1 f16 = f7, f6, f7 // q1 = q*e + q -(p6) fmpy.s1 f7 = f6, f6 // e1 = e*e +(p6) fma.s1 f16 = 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 = y*e + y +(p6) fma.s1 f6 = f17, f6, f17 // 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) fma.s1 f17 = f7, f6, f16 // q3 = r*y2 + q2 - ;; #ifdef MODULO - FP_TO_INT(f17, f17) // round quotient to an unsigned integer - ;; - INT_TO_FP(f17, f17) // renormalize - ;; - fnma.s1 f17 = f17, f9, f8 // compute remainder - ;; + setf.sig f8 = in0 // f8 = a + setf.sig f9 = in1 // f9 = -b #endif +(p6) fma.s1 f17 = f7, f6, f16 // q3 = r*y2 + q2 + ;; UNW(.restore sp) ldf.fill f16 = [sp], 16 - FP_TO_INT(f8, f17) // round result to an (unsigned) integer + FP_TO_INT(f17, f17) // q = trunc(q3) ;; +#ifdef MODULO + xma.l f17 = f17, f9, f8 // r = q*(-b) + a + ;; +#endif + getf.sig r8 = f17 // transfer result to result register ldf.fill f17 = [sp] - getf.sig r8 = f8 // transfer result to result register br.ret.sptk rp END(NAME) diff --git a/arch/ia64/lib/io.c b/arch/ia64/lib/io.c index 466335172..baa408e01 100644 --- a/arch/ia64/lib/io.c +++ b/arch/ia64/lib/io.c @@ -1,4 +1,3 @@ -#include <linux/module.h> #include <linux/types.h> #include <asm/io.h> @@ -49,6 +48,3 @@ __ia64_memset_c_io (unsigned long dst, unsigned long c, long count) } } -EXPORT_SYMBOL(__ia64_memcpy_fromio); -EXPORT_SYMBOL(__ia64_memcpy_toio); -EXPORT_SYMBOL(__ia64_memset_c_io); diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 3652cfc80..b2cd880ad 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -357,6 +357,7 @@ ia64_rid_init (void) panic("mm/init: overlap between virtually mapped linear page table and " "mapped kernel space!"); pta = POW2(61) - POW2(impl_va_msb); +#ifndef CONFIG_DISABLE_VHPT /* * Set the (virtually mapped linear) page table address. Bit * 8 selects between the short and long format, bits 2-7 the @@ -364,6 +365,9 @@ ia64_rid_init (void) * enabled. */ ia64_set_pta(pta | (0<<8) | ((3*(PAGE_SHIFT-3)+3)<<2) | 1); +#else + ia64_set_pta(pta | (0<<8) | ((3*(PAGE_SHIFT-3)+3)<<2) | 0); +#endif } /* @@ -445,15 +449,6 @@ mem_init (void) /* install the gate page in the global page table: */ put_gate_page(virt_to_page(__start_gate_section), GATE_ADDR); -#ifndef CONFIG_IA64_SOFTSDV_HACKS - /* - * (Some) SoftSDVs seem to have a problem with this call. - * Since it's mostly a performance optimization, just don't do - * it for now... --davidm 99/12/6 - */ - efi_enter_virtual_mode(); -#endif - #ifdef CONFIG_IA32_SUPPORT ia32_gdt_init(); #endif diff --git a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile index 0e6d78450..f98e2d1f3 100644 --- a/arch/ia64/tools/Makefile +++ b/arch/ia64/tools/Makefile @@ -46,4 +46,4 @@ print_offsets.s: print_offsets.c endif -.PHONY: all modules +.PHONY: all modules modules_install diff --git a/arch/m68k/amiga/amiga_ksyms.c b/arch/m68k/amiga/amiga_ksyms.c index 9b686100a..e9fee546e 100644 --- a/arch/m68k/amiga/amiga_ksyms.c +++ b/arch/m68k/amiga/amiga_ksyms.c @@ -1,7 +1,6 @@ #include <linux/config.h> #include <linux/module.h> #include <linux/types.h> -#include <linux/zorro.h> #include <asm/ptrace.h> #include <asm/amigahw.h> #include <asm/amigaints.h> diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index 43df3f6c2..b7f9f0508 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c @@ -8,7 +8,7 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/zorro.h> +#include <linux/ioport.h> #include <asm/amigahw.h> struct chip_desc { diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 3eca427f5..528f206ff 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -20,7 +20,9 @@ #include <linux/tty.h> #include <linux/console.h> #include <linux/init.h> +#ifdef CONFIG_ZORRO #include <linux/zorro.h> +#endif #include <asm/bootinfo.h> #include <asm/setup.h> @@ -89,17 +91,10 @@ static void amiga_heartbeat(int on); #endif static struct console amiga_console_driver = { - "debug", - NULL, /* write */ - NULL, /* read */ - NULL, /* device */ - amiga_wait_key, /* wait_key */ - NULL, /* unblank */ - NULL, /* setup */ - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "debug", + wait_key: amiga_wait_key, + flags: CON_PRINTBUFFER, + index: -1, }; #ifdef CONFIG_MAGIC_SYSRQ @@ -168,6 +163,7 @@ int amiga_parse_bootinfo(const struct bi_record *record) break; case BI_AMIGA_AUTOCON: +#ifdef CONFIG_ZORRO if (zorro_num_autocon < ZORRO_NUM_AUTO) { const struct ConfigDev *cd = (struct ConfigDev *)data; struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; @@ -178,6 +174,7 @@ int amiga_parse_bootinfo(const struct bi_record *record) dev->resource.end = dev->resource.start+cd->cd_BoardSize-1; } else printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); +#endif break; case BI_AMIGA_SERPER: @@ -1004,11 +1001,13 @@ static int amiga_get_hardware_list(char *buffer) AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); +#ifdef CONFIG_ZORRO if (AMIGAHW_PRESENT(ZORRO)) len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " "Device%s\n", AMIGAHW_PRESENT(ZORRO3) ? "I" : "", zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); +#endif #undef AMIGAHW_ANNOUNCE diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c index e30cb4e55..2900f7758 100644 --- a/arch/m68k/atari/debug.c +++ b/arch/m68k/atari/debug.c @@ -31,17 +31,9 @@ int atari_SCC_init_done = 0; int atari_SCC_reset_done = 0; static struct console atari_console_driver = { - "debug", - NULL, /* write */ - NULL, /* read */ - NULL, /* device */ - NULL, /* wait_key */ - NULL, /* unblank */ - NULL, /* setup */ - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "debug", + flags: CON_PRINTBUFFER, + index: -1, }; diff --git a/arch/m68k/config.in b/arch/m68k/config.in index 83381857f..b06fdb516 100644 --- a/arch/m68k/config.in +++ b/arch/m68k/config.in @@ -139,9 +139,8 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then fi fi -if [ "$CONFIG_PCI" = "y" ]; then - source drivers/pci/Config.in -fi +source drivers/pci/Config.in +source drivers/zorro/Config.in endmenu diff --git a/arch/m68k/kernel/semaphore.c b/arch/m68k/kernel/semaphore.c index b873ee9c7..139a75b64 100644 --- a/arch/m68k/kernel/semaphore.c +++ b/arch/m68k/kernel/semaphore.c @@ -182,7 +182,7 @@ void down_write_failed(struct rw_semaphore *sem) while (atomic_read(&sem->count) < 0) { set_task_state(current, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (atomic_read(&sem->count) >= 0) - break; /* we must attempt to aquire or bias the lock */ + break; /* we must attempt to acquire or bias the lock */ schedule(); } diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 7a6637a2e..a2e3f47f1 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -68,13 +68,13 @@ char saved_command_line[CL_SIZE]; char m68k_debug_device[6] = ""; -void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata; +void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; /* machine dependent keyboard functions */ -int (*mach_keyb_init) (void) __initdata; +int (*mach_keyb_init) (void) __initdata = NULL; int (*mach_kbdrate) (struct kbd_repeat *) = NULL; void (*mach_kbd_leds) (unsigned int) = NULL; /* machine dependent irq functions */ -void (*mach_init_IRQ) (void) __initdata; +void (*mach_init_IRQ) (void) __initdata = NULL; void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; void (*mach_get_model) (char *model) = NULL; int (*mach_get_hardware_list) (char *buffer) = NULL; @@ -365,7 +365,7 @@ void __init setup_arch(char **cmdline_p) high_memory += m68k_memory[i].size; } - availmem += init_bootmem_node(0, availmem >> PAGE_SHIFT, + availmem += init_bootmem_node(NODE_DATA(0), availmem >> PAGE_SHIFT, startmem >> PAGE_SHIFT, endmem >> PAGE_SHIFT); for (i = 0; i < m68k_num_memory; i++) diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index c1154b6aa..a0486cf95 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -127,7 +127,6 @@ void mac_waitbut (void) } #endif -extern struct consw fb_con; extern struct fb_info *mac_fb_init(long *); extern void mac_default_handler(int, void *, struct pt_regs *); diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c index fa3910b5e..330d30955 100644 --- a/arch/m68k/mac/debug.c +++ b/arch/m68k/mac/debug.c @@ -159,17 +159,9 @@ int mac_SCC_reset_done = 0; static int scc_port = -1; static struct console mac_console_driver = { - "debug", - NULL, /* write */ - NULL, /* read */ - NULL, /* device */ - NULL, /* wait_key */ - NULL, /* unblank */ - NULL, /* setup */ - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "debug", + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index 612d51eda..dbb3d81e2 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c @@ -32,7 +32,7 @@ #include <asm/atari_stram.h> #endif -static unsigned long totalram_pages = 0; +static unsigned long totalram_pages; #ifdef CONFIG_SUN3 void mmu_emu_reserve_pages(unsigned long max_page); diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index df0a57762..2496aa9ba 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -74,17 +74,10 @@ static unsigned char bin2bcd (unsigned char b); static int q40_wait_key(struct console *co){return 0;} static struct console q40_console_driver = { - "debug", - NULL, /* write */ - NULL, /* read */ - NULL, /* device */ - q40_wait_key, /* wait_key */ - NULL, /* unblank */ - NULL, /* setup */ - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "debug", + wait_key: q40_wait_key, + flags: CON_PRINTBUFFER, + index: -1, }; diff --git a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c index 733f52695..2fd91c9c9 100644 --- a/arch/mips/baget/irq.c +++ b/arch/mips/baget/irq.c @@ -178,7 +178,7 @@ static void do_IRQ(int irq, struct pt_regs * regs) int do_random, cpu; cpu = smp_processor_id(); - irq_enter(cpu); + irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; mask_irq(irq); @@ -200,7 +200,7 @@ static void do_IRQ(int irq, struct pt_regs * regs) printk("do_IRQ: Unregistered IRQ (0x%X) occured\n", irq); } unmask_irq(irq); - irq_exit(cpu); + irq_exit(cpu, irq); /* unmasking and bottom half handling is done magically for us. */ } diff --git a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c index dda980e0e..12021daf4 100644 --- a/arch/mips/baget/vacserial.c +++ b/arch/mips/baget/vacserial.c @@ -2811,17 +2811,13 @@ static int __init serial_console_setup(struct console *co, char *options) } static struct console sercons = { - "ttyS", - serial_console_write, - NULL, - serial_console_device, - serial_console_wait_key, - NULL, - serial_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/arch/mips/dec/irq.c b/arch/mips/dec/irq.c index a15e2a45c..00430c352 100644 --- a/arch/mips/dec/irq.c +++ b/arch/mips/dec/irq.c @@ -2,9 +2,7 @@ * Code to handle DECstation IRQs plus some generic interrupt stuff. * * Copyright (C) 1992 Linus Torvalds - * Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle - * - * $Id: irq.c,v 1.6 2000/02/04 07:40:23 ralf Exp $ + * Copyright (C) 1994, 1995, 1996, 1997, 2000 Ralf Baechle */ #include <linux/errno.h> #include <linux/init.h> @@ -121,7 +119,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) int do_random, cpu; cpu = smp_processor_id(); - irq_enter(cpu); + irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; mask_irq(irq); @@ -138,7 +136,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) } while (action); if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); - unmask_irq(irq); + unmask_irq(irq, irq); __cli(); } irq_exit(cpu); diff --git a/arch/mips/dec/promcon.c b/arch/mips/dec/promcon.c index de9eaf5b2..2c8ba4d7f 100644 --- a/arch/mips/dec/promcon.c +++ b/arch/mips/dec/promcon.c @@ -47,17 +47,13 @@ static kdev_t prom_console_device(struct console *c) static struct console sercons = { - "ttyS", - prom_console_write, - NULL, - prom_console_device, - prom_console_wait_key, - NULL, - prom_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: prom_console_write, + device: prom_console_device, + wait_key: prom_console_wait_key, + setup: prom_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 4e1ec7ba1..4bfb83f30 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c @@ -46,7 +46,7 @@ extern rwlock_t xtime_lock; /* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi = 0, timerlo = 0; +static unsigned int timerhi, timerlo; /* * Cached "1/(clocks per usec)*2^32" value. @@ -317,7 +317,7 @@ static int set_rtc_mmss(unsigned long nowtime) } /* last time the cmos clock got updated */ -static long last_rtc_update = 0; +static long last_rtc_update; /* * timer_interrupt() needs to keep up the real-time clock, diff --git a/arch/mips/defconfig b/arch/mips/defconfig index d47c8b52d..b66bb0dfa 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -144,6 +144,7 @@ CONFIG_IP_PNP_BOOTP=y # 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 diff --git a/arch/mips/defconfig-atlas b/arch/mips/defconfig-atlas index 518886123..2e050a7dd 100644 --- a/arch/mips/defconfig-atlas +++ b/arch/mips/defconfig-atlas @@ -139,6 +139,7 @@ CONFIG_IP_PNP=y # 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 @@ -264,6 +265,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set diff --git a/arch/mips/defconfig-ddb5476 b/arch/mips/defconfig-ddb5476 index 7a597eb18..bfdcd7419 100644 --- a/arch/mips/defconfig-ddb5476 +++ b/arch/mips/defconfig-ddb5476 @@ -144,6 +144,7 @@ CONFIG_IP_PNP_BOOTP=y # 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 @@ -223,7 +224,9 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set # CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_OSB4 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 @@ -271,6 +274,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set diff --git a/arch/mips/defconfig-decstation b/arch/mips/defconfig-decstation index 0abb60523..987c40c54 100644 --- a/arch/mips/defconfig-decstation +++ b/arch/mips/defconfig-decstation @@ -138,6 +138,7 @@ CONFIG_IP_PNP_BOOTP=y # 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 diff --git a/arch/mips/defconfig-ev96100 b/arch/mips/defconfig-ev96100 index 27c26978c..144d4b92d 100644 --- a/arch/mips/defconfig-ev96100 +++ b/arch/mips/defconfig-ev96100 @@ -140,6 +140,7 @@ CONFIG_IP_PNP_BOOTP=y # 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 @@ -204,6 +205,7 @@ CONFIG_MIPS_GT96100ETH=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22 index d47c8b52d..b66bb0dfa 100644 --- a/arch/mips/defconfig-ip22 +++ b/arch/mips/defconfig-ip22 @@ -144,6 +144,7 @@ CONFIG_IP_PNP_BOOTP=y # 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 diff --git a/arch/mips/defconfig-malta b/arch/mips/defconfig-malta index 0ce1b23cb..a5618827e 100644 --- a/arch/mips/defconfig-malta +++ b/arch/mips/defconfig-malta @@ -137,6 +137,7 @@ CONFIG_IP_PNP=y # 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 @@ -262,6 +263,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set diff --git a/arch/mips/defconfig-orion b/arch/mips/defconfig-orion index 4758af94c..791b5b5b5 100644 --- a/arch/mips/defconfig-orion +++ b/arch/mips/defconfig-orion @@ -128,6 +128,7 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET_AUNUDP is not set # CONFIG_ECONET_NATIVE is not set # CONFIG_WAN_ROUTER is not set diff --git a/arch/mips/defconfig-rm200 b/arch/mips/defconfig-rm200 index 38df380d7..5331234e2 100644 --- a/arch/mips/defconfig-rm200 +++ b/arch/mips/defconfig-rm200 @@ -146,6 +146,7 @@ CONFIG_INET=y # 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 diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 4a55e2325..fcebe3fe2 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -1,12 +1,11 @@ -/* $Id: ptrace.c,v 1.17 1999/09/28 22:25:47 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1992 Ross Biro * Copyright (C) Linus Torvalds - * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle + * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle * Copyright (C) 1996 David S. Miller */ #include <linux/kernel.h> @@ -269,7 +268,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) res = -EIO; if ((unsigned long) data > _NSIG) break; - child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); + child->ptrace = 0; child->exit_code = data; write_lock_irq(&tasklist_lock); REMOVE_LINKS(child); @@ -280,6 +279,15 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) res = 0; break; + case PTRACE_SETOPTIONS: { + if (data & PTRACE_O_TRACESYSGOOD) + child->ptrace |= PT_TRACESYSGOOD; + else + child->ptrace &= ~PT_TRACESYSGOOD; + ret = 0; + break; + } + default: res = -EIO; goto out; @@ -296,7 +304,10 @@ asmlinkage void syscall_trace(void) if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) != (PT_PTRACED|PT_TRACESYS)) return; - current->exit_code = SIGTRAP; + /* The 0x80 provides a way for the tracing parent to distinguish + between a syscall stop and SIGTRAP delivery */ + current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0); current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule(); diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 609593c6b..6b65801d5 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -26,7 +26,7 @@ #include <linux/timex.h> extern volatile unsigned long wall_jiffies; -unsigned long r4k_interval = 0; +unsigned long r4k_interval; extern rwlock_t xtime_lock; /* @@ -40,7 +40,7 @@ extern rwlock_t xtime_lock; /* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi = 0, timerlo = 0; +static unsigned int timerhi, timerlo; /* * On MIPS only R4000 and better have a cycle counter. @@ -53,14 +53,14 @@ static unsigned long do_fast_gettimeoffset(void) unsigned long res, tmp; /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies=0; + static unsigned long last_jiffies; unsigned long quotient; /* * Cached "1/(clocks per usec)*2^32" value. * It has to be recalculated once each jiffy. */ - static unsigned long cached_quotient=0; + static unsigned long cached_quotient; tmp = jiffies; @@ -153,7 +153,7 @@ static unsigned long do_slow_gettimeoffset(void) int count; static int count_p = LATCH; /* for the first call after boot */ - static unsigned long jiffies_p = 0; + static unsigned long jiffies_p; /* * cache volatile jiffies temporarily; we have IRQs turned off. @@ -331,7 +331,7 @@ static int set_rtc_mmss(unsigned long nowtime) } /* last time the cmos clock got updated */ -static long last_rtc_update = 0; +static long last_rtc_update; /* * timer_interrupt() needs to keep up the real-time clock, @@ -341,7 +341,7 @@ static void inline timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { #ifdef CONFIG_DDB5074 - static unsigned cnt = 0, period = 0, dist = 0; + static unsigned cnt, period, dist; if (cnt == 0 || cnt == dist) ddb5074_led_d2(1); diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index a6f448e05..289dcd041 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -39,7 +39,7 @@ #endif #include <asm/mmu_context.h> -static unsigned long totalram_pages = 0; +static unsigned long totalram_pages; extern void prom_fixup_mem_map(unsigned long start, unsigned long end); extern void prom_free_prom_memory(void); diff --git a/arch/mips/orion/irq.c b/arch/mips/orion/irq.c index 8be436370..8ec0ba80f 100644 --- a/arch/mips/orion/irq.c +++ b/arch/mips/orion/irq.c @@ -162,7 +162,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) int status; cpu = smp_processor_id(); - irq_enter(cpu); + irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; status = 0; @@ -197,7 +197,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) irq_desc[irq].handler->end(irq); } - irq_exit(cpu); + irq_exit(cpu, irq); if (softirq_active(cpu) & softirq_mask(cpu)) do_softirq(); diff --git a/arch/mips/orion/promcon.c b/arch/mips/orion/promcon.c index 564d6cfae..20120b4b7 100644 --- a/arch/mips/orion/promcon.c +++ b/arch/mips/orion/promcon.c @@ -67,17 +67,13 @@ static kdev_t prom_console_device(struct console *c) static struct console sercons = { - "ttyS", - prom_console_write, - NULL, - prom_console_device, - prom_console_wait_key, - NULL, - prom_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: prom_console_write, + device: prom_console_device, + wait_key: prom_console_wait_key, + setup: prom_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c index 1ad77fc18..ab9168cb6 100644 --- a/arch/mips/sgi/kernel/indy_int.c +++ b/arch/mips/sgi/kernel/indy_int.c @@ -284,7 +284,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) int do_random, cpu; cpu = smp_processor_id(); - irq_enter(cpu); + irq_enter(cpu, irq); kstat.irqs[0][irq]++; printk("Got irq %d, press a key.", irq); @@ -320,7 +320,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) add_interrupt_randomness(irq); __cli(); } - irq_exit(cpu); + irq_exit(cpu, irq); /* unmasking and bottom half handling is done magically for us. */ } @@ -455,18 +455,16 @@ void indy_local0_irqdispatch(struct pt_regs *regs) /* if action == NULL, then we do have a handler for the irq */ if ( action == NULL ) { goto no_handler; } - irq_enter(cpu); + irq_enter(cpu, irq); kstat.irqs[0][irq + 16]++; action->handler(irq, action->dev_id, regs); - irq_exit(cpu); + irq_exit(cpu, irq); goto end; no_handler: printk("No handler for local0 irq: %i\n", irq); end: - return; - } void indy_local1_irqdispatch(struct pt_regs *regs) @@ -493,10 +491,10 @@ void indy_local1_irqdispatch(struct pt_regs *regs) /* if action == NULL, then we do have a handler for the irq */ if ( action == NULL ) { goto no_handler; } - irq_enter(cpu); + irq_enter(cpu, irq); kstat.irqs[0][irq + 24]++; action->handler(irq, action->dev_id, regs); - irq_exit(cpu); + irq_exit(cpu, irq); goto end; no_handler: @@ -511,13 +509,13 @@ void indy_buserror_irq(struct pt_regs *regs) int cpu = smp_processor_id(); int irq = 6; - irq_enter(cpu); + irq_enter(cpu, irq); kstat.irqs[0][irq]++; printk("Got a bus error IRQ, shouldn't happen yet\n"); show_regs(regs); printk("Spinning...\n"); while(1); - irq_exit(cpu); + irq_exit(cpu, irq); } /* Misc. crap just to keep the kernel linking... */ diff --git a/arch/mips/sgi/kernel/time.c b/arch/mips/sgi/kernel/time.c index ea85b75db..47ee4f163 100644 --- a/arch/mips/sgi/kernel/time.c +++ b/arch/mips/sgi/kernel/time.c @@ -9,13 +9,13 @@ void indy_8254timer_irq(void) { - int cpu = smp_processor_id(); - int irq = 4; + int cpu = smp_processor_id(); + int irq = 4; - irq_enter(cpu); - kstat.irqs[0][irq]++; - printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n"); - prom_getchar(); - prom_imode(); - irq_exit(cpu); + irq_enter(cpu, irq); + kstat.irqs[0][irq]++; + printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n"); + prom_getchar(); + prom_imode(); + irq_exit(cpu, irq); } diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig index 51d2d3c06..8c86e86f3 100644 --- a/arch/mips64/defconfig +++ b/arch/mips64/defconfig @@ -234,6 +234,7 @@ CONFIG_SGI_IOC3_ETH=y # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27 index 51d2d3c06..8c86e86f3 100644 --- a/arch/mips64/defconfig-ip27 +++ b/arch/mips64/defconfig-ip27 @@ -234,6 +234,7 @@ CONFIG_SGI_IOC3_ETH=y # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set diff --git a/arch/mips64/kernel/ptrace.c b/arch/mips64/kernel/ptrace.c index 579fc8855..86e17a009 100644 --- a/arch/mips64/kernel/ptrace.c +++ b/arch/mips64/kernel/ptrace.c @@ -5,7 +5,7 @@ * * Copyright (C) 1992 Ross Biro * Copyright (C) Linus Torvalds - * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle + * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle * Copyright (C) 1996 David S. Miller * Copyright (C) 2000 Ulf Carlsson * @@ -268,7 +268,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); + child->ptrace = 0; child->exit_code = data; write_lock_irq(&tasklist_lock); REMOVE_LINKS(child); @@ -280,6 +280,15 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) break; } + case PTRACE_SETOPTIONS: { + if (data & PTRACE_O_TRACESYSGOOD) + child->ptrace |= PT_TRACESYSGOOD; + else + child->ptrace &= ~PT_TRACESYSGOOD; + ret = 0; + break; + } + default: ret = -EIO; break; @@ -534,7 +543,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); + child->ptrace = 0; child->exit_code = data; write_lock_irq(&tasklist_lock); REMOVE_LINKS(child); @@ -546,6 +555,15 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) break; } + case PTRACE_SETOPTIONS: { + if (data & PTRACE_O_TRACESYSGOOD) + child->ptrace |= PT_TRACESYSGOOD; + else + child->ptrace &= ~PT_TRACESYSGOOD; + ret = 0; + break; + } + default: ret = -EIO; break; @@ -564,7 +582,10 @@ asmlinkage void syscall_trace(void) != (PT_PTRACED|PT_TRACESYS)) return; - current->exit_code = SIGTRAP; + /* The 0x80 provides a way for the tracing parent to distinguish + between a syscall stop and SIGTRAP delivery */ + current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0); current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule(); diff --git a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c index b004f6777..655d2add2 100644 --- a/arch/mips64/kernel/smp.c +++ b/arch/mips64/kernel/smp.c @@ -54,7 +54,7 @@ static void sendintr(int destid, unsigned char status) /* The 'big kernel lock' */ spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; -int smp_threads_ready = 0; /* Not used */ +int smp_threads_ready; /* Not used */ atomic_t smp_commenced = ATOMIC_INIT(0); struct cpuinfo_mips cpu_data[NR_CPUS]; int smp_num_cpus; /* Number that came online. */ @@ -130,7 +130,7 @@ static volatile struct call_data_struct { atomic_t started; atomic_t finished; int wait; -} *call_data = NULL; +} *call_data; int smp_call_function (void (*func) (void *info), void *info, int retry, int wait) diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c index f1d95c702..a594c69a0 100644 --- a/arch/mips64/mm/init.c +++ b/arch/mips64/mm/init.c @@ -38,7 +38,7 @@ #endif #include <asm/mmu_context.h> -unsigned long totalram_pages = 0; +unsigned long totalram_pages; void __bad_pte_kernel(pmd_t *pmd) { diff --git a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c index 76ed0c214..e98ec596e 100644 --- a/arch/mips64/sgi-ip22/ip22-timer.c +++ b/arch/mips64/sgi-ip22/ip22-timer.c @@ -79,8 +79,8 @@ static int set_rtc_mmss(unsigned long nowtime) return retval; } -static long last_rtc_update = 0; -unsigned long missed_heart_beats = 0; +static long last_rtc_update; +unsigned long missed_heart_beats; void indy_timer_interrupt(struct pt_regs *regs) { diff --git a/arch/mips64/sgi-ip27/ip27-console.c b/arch/mips64/sgi-ip27/ip27-console.c index e45a078b5..fa3ffb1cb 100644 --- a/arch/mips64/sgi-ip27/ip27-console.c +++ b/arch/mips64/sgi-ip27/ip27-console.c @@ -28,7 +28,7 @@ void prom_putchar(char c) char __init prom_getchar(void) { - return(0); + return 0; } static void @@ -44,17 +44,11 @@ ip27prom_console_dev(struct console *c) } static struct console ip27_prom_console = { - "prom", - ip27prom_console_write, - NULL, - ip27prom_console_dev, - NULL, - NULL, - NULL, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "prom", + write: ip27prom_console_write, + device: ip27prom_console_dev, + flags: CON_PRINTBUFFER, + index: -1, }; __init void ip27_setup_console(void) diff --git a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c index f858d098f..0e469ce4b 100644 --- a/arch/mips64/sgi-ip27/ip27-memory.c +++ b/arch/mips64/sgi-ip27/ip27-memory.c @@ -200,11 +200,11 @@ void __init prom_meminit(void) << PAGE_SHIFT)); NODE_DATA(node)->bdata = plat_node_bdata + node; slot_freepfn += node_datasz; - bootmap_size = init_bootmem_node(node, slot_freepfn, + bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, slot_firstpfn, slot_lastpfn); - free_bootmem_node(node, slot_firstpfn << PAGE_SHIFT, + free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, (slot_lastpfn - slot_firstpfn) << PAGE_SHIFT); - reserve_bootmem_node(node, slot_firstpfn << PAGE_SHIFT, + reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size); } printk("Total memory probed : 0x%lx pages\n", numpages); @@ -278,7 +278,7 @@ void __init mem_init(void) /* * This will free up the bootmem, ie, slot 0 memory. */ - totalram_pages += free_all_bootmem_node(nid); + totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); /* * We need to manually do the other slots. diff --git a/arch/mips64/sgi-ip27/ip27-rtc.c b/arch/mips64/sgi-ip27/ip27-rtc.c index bb5209d64..b29af3d73 100644 --- a/arch/mips64/sgi-ip27/ip27-rtc.c +++ b/arch/mips64/sgi-ip27/ip27-rtc.c @@ -60,8 +60,8 @@ static void get_rtc_time(struct rtc_time *rtc_tm); #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 = 0; /* bitmapped status byte. */ -static unsigned long rtc_freq = 0; /* Current periodic IRQ rate */ +static unsigned char rtc_status; /* bitmapped status byte. */ +static unsigned long rtc_freq; /* Current periodic IRQ rate */ static struct m48t35_rtc *rtc; /* diff --git a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c index 8cbb943c8..edbeb9e11 100644 --- a/arch/mips64/sgi-ip27/ip27-timer.c +++ b/arch/mips64/sgi-ip27/ip27-timer.c @@ -37,7 +37,7 @@ #define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ) static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */ -static long last_rtc_update = 0; /* Last time the rtc clock got updated */ +static long last_rtc_update; /* Last time the rtc clock got updated */ extern rwlock_t xtime_lock; extern volatile unsigned long wall_jiffies; diff --git a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c index 97c4cb880..f7ce9da03 100644 --- a/arch/ppc/8260_io/uart.c +++ b/arch/ppc/8260_io/uart.c @@ -2268,17 +2268,13 @@ static kdev_t serial_console_device(struct console *c) static struct console sercons = { - "ttyS", - serial_console_write, - NULL, - serial_console_device, - serial_console_wait_key, - NULL, - serial_console_setup, - CON_PRINTBUFFER, - CONFIG_SERIAL_CONSOLE_PORT, - 0, - NULL + name: "ttyS", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: CONFIG_SERIAL_CONSOLE_PORT, }; /* diff --git a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c index b9f791832..7c05954c2 100644 --- a/arch/ppc/8xx_io/uart.c +++ b/arch/ppc/8xx_io/uart.c @@ -2407,17 +2407,13 @@ static kdev_t serial_console_device(struct console *c) static struct console sercons = { - "ttyS", - serial_console_write, - NULL, - serial_console_device, - serial_console_wait_key, - NULL, - serial_console_setup, - CON_PRINTBUFFER, - CONFIG_SERIAL_CONSOLE_PORT, - 0, - NULL + name: "ttyS", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: CONFIG_SERIAL_CONSOLE_PORT, }; /* diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c index 652eb1582..83e33e17b 100644 --- a/arch/ppc/amiga/config.c +++ b/arch/ppc/amiga/config.c @@ -97,17 +97,10 @@ static void amiga_heartbeat(int on); #endif static struct console amiga_console_driver = { - "debug", - NULL, /* write */ - NULL, /* read */ - NULL, /* device */ - amiga_wait_key, /* wait_key */ - NULL, /* unblank */ - NULL, /* setup */ - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "debug", + wait_key: amiga_wait_key, + flags: CON_PRINTBUFFER, + index: -1, }; #ifdef CONFIG_MAGIC_SYSRQ diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 0a217d4c9..ef17e6334 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -104,11 +104,11 @@ if [ "$CONFIG_APUS" = "y" -o "$CONFIG_4xx" = "y" -o \ "$CONFIG_8260" = "y" ]; then define_bool CONFIG_PCI n else - if [ "$CONFIG_6xx" = "y" -o "$CONFIG_PPC64BRIDGE" = "y" ]; then - define_bool CONFIG_PCI y + if [ "$CONFIG_8xx" = "y" ]; then + bool 'QSpan PCI' CONFIG_PCI_QSPAN + define_bool CONFIG_PCI $CONFIG_PCI_QSPAN else - # CONFIG_8xx - bool 'QSpan PCI' CONFIG_PCI + define_bool CONFIG_PCI y fi fi @@ -126,6 +126,7 @@ define_bool CONFIG_KERNEL_ELF y tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC source drivers/pci/Config.in +source drivers/zorro/Config.in bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG @@ -151,7 +152,7 @@ if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then fi if [ "$CONFIG_PREP" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then - bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL y + bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2" fi diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index d75663be5..5979c9312 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -82,13 +82,13 @@ char debug_device[6] __apusdata = ""; extern void amiga_init_IRQ(void); -void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata; +void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; /* machine dependent keyboard functions */ -int (*mach_keyb_init) (void) __initdata; +int (*mach_keyb_init) (void) __initdata = NULL; int (*mach_kbdrate) (struct kbd_repeat *) __apusdata = NULL; void (*mach_kbd_leds) (unsigned int) __apusdata = NULL; /* machine dependent irq functions */ -void (*mach_init_IRQ) (void) __initdata; +void (*mach_init_IRQ) (void) __initdata = NULL; void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) __apusdata = NULL; void (*mach_get_model) (char *model) __apusdata = NULL; int (*mach_get_hardware_list) (char *buffer) __apusdata = NULL; diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index d72e74735..6e30462aa 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -384,8 +384,8 @@ void __init prep_res_calibrate_decr(void) * 2 following ones measure the interval. The precision of the method * is still doubtful due to the short interval sampled. */ -static __initdata volatile int calibrate_steps = 3; -static __initdata unsigned tbstamp; +static volatile int calibrate_steps __initdata = 3; +static unsigned tbstamp __initdata = 0; void __init prep_calibrate_decr_handler(int irq, diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 0a66d6c6b..fb7f38444 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -41,8 +41,8 @@ #include <asm/time.h> #include "open_pic.h" -int smp_threads_ready = 0; -volatile int smp_commenced = 0; +int smp_threads_ready; +volatile int smp_commenced; int smp_num_cpus = 1; struct cpuinfo_PPC cpu_data[NR_CPUS]; struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 }; @@ -54,10 +54,10 @@ unsigned int prof_counter[NR_CPUS]; cycles_t cacheflush_time; /* this has to go in the data section because it is accessed from prom_init */ -int smp_hw_index[NR_CPUS] = {0}; +int smp_hw_index[NR_CPUS]; /* all cpu mappings are 1-1 -- Cort */ -volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; +volatile unsigned long cpu_callin_map[NR_CPUS]; int start_secondary(void *); extern int cpu_idle(void *unused); @@ -226,7 +226,7 @@ static volatile struct call_data_struct { atomic_t started; atomic_t finished; int wait; -} *call_data = NULL; +} *call_data; /* * this function sends a 'generic call function' IPI to all other CPUs diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index be7d1f063..cc8d2290a 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -82,8 +82,8 @@ unsigned long total_lowmem; int mem_init_done; int init_bootmem_done; int boot_mapsize; -unsigned long totalram_pages = 0; -unsigned long totalhigh_pages = 0; +unsigned long totalram_pages; +unsigned long totalhigh_pages; extern pgd_t swapper_pg_dir[]; extern char _start[], _end[]; extern char etext[], _stext[]; @@ -138,10 +138,10 @@ struct mem_pieces phys_mem; char *klimit = _end; struct mem_pieces phys_avail; -PTE *Hash=0, *Hash_end; -unsigned long Hash_size=0, Hash_mask; +PTE *Hash, *Hash_end; +unsigned long Hash_size, Hash_mask; #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) -unsigned long _SDR1=0; +unsigned long _SDR1; static void hash_init(void); union ubat { /* BAT register values to be loaded */ @@ -195,7 +195,7 @@ static inline unsigned long p_mapped_by_bats(unsigned long pa) * (i.e. page tables) instead of the bats. * -- Cort */ -int __map_without_bats = 0; +int __map_without_bats; /* max amount of RAM to use */ unsigned long __max_memory; diff --git a/arch/s390/config.in b/arch/s390/config.in index cdb88b757..894e40d5b 100644 --- a/arch/s390/config.in +++ b/arch/s390/config.in @@ -46,11 +46,16 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF endmenu source drivers/s390/Config.in + +mainmenu_option next_comment +comment 'Character devices' bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 fi +endmenu + if [ "$CONFIG_NET" = "y" ]; then source net/Config.in fi diff --git a/arch/s390/kernel/semaphore.c b/arch/s390/kernel/semaphore.c index 368692222..86aef0185 100644 --- a/arch/s390/kernel/semaphore.c +++ b/arch/s390/kernel/semaphore.c @@ -16,8 +16,8 @@ /* * Semaphores are implemented using a two-way counter: * The "count" variable is decremented for each process - * that tries to aquire the semaphore, while the "sleeping" - * variable is a count of such aquires. + * that tries to acquire the semaphore, while the "sleeping" + * variable is a count of such acquires. * * Notably, the inline "up()" and "down()" functions can * efficiently test if they need to do any extra work (up @@ -242,7 +242,7 @@ void down_write_failed(struct rw_semaphore *sem) while (atomic_read(&sem->count) < 0) { set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (atomic_read(&sem->count) >= 0) - break; /* we must attempt to aquire or bias the lock */ + break; /* we must attempt to acquire or bias the lock */ schedule(); } diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index a45d02ed8..1a22e429b 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -36,7 +36,7 @@ #include <asm/dma.h> #include <asm/lowcore.h> -static unsigned long totalram_pages = 0; +static unsigned long totalram_pages; /* * BAD_PAGE is the page that is used for page faults when linux diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index 3b74e2d8e..37d29a6c4 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -149,52 +149,55 @@ SYSCALL_NR = (16*4+6*4) .align 2 tlb_miss_load: - mov.l 2f, $r0 - mov.l @$r0, $r6 - mov $r15, $r4 - mov.l 1f, $r0 - jmp @$r0 + bra call_dpf mov #0, $r5 .align 2 tlb_miss_store: - mov.l 2f, $r0 - mov.l @$r0, $r6 - mov $r15, $r4 - mov.l 1f, $r0 - jmp @$r0 + bra call_dpf mov #1, $r5 .align 2 initial_page_write: - mov.l 2f, $r0 - mov.l @$r0, $r6 - mov $r15, $r4 - mov.l 1f, $r0 - jmp @$r0 + bra call_dpf mov #1, $r5 .align 2 tlb_protection_violation_load: - mov.l 2f, $r0 - mov.l @$r0, $r6 - mov $r15, $r4 - mov.l 1f, $r0 - jmp @$r0 + bra call_dpf mov #0, $r5 .align 2 tlb_protection_violation_store: - mov.l 2f, $r0 - mov.l @$r0, $r6 - mov $r15, $r4 + bra call_dpf + mov #1, $r5 + +call_dpf: mov.l 1f, $r0 + mov $r5, $r8 + mov.l @$r0, $r6 + mov $r6, $r9 + mov.l 2f, $r0 + sts $pr, $r10 + jsr @$r0 + mov $r15, $r4 + ! + tst #0xff, $r0 + bf/s 0f + lds $r10, $pr + rts + nop +0: STI() + mov.l 3f, $r0 + mov $r9, $r6 + mov $r8, $r5 jmp @$r0 - mov #1, $r5 + mov $r15, $r4 .align 2 -1: .long SYMBOL_NAME(__do_page_fault) -2: .long MMU_TEA +1: .long MMU_TEA +2: .long SYMBOL_NAME(__do_page_fault) +3: .long SYMBOL_NAME(do_page_fault) #if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS) .align 2 diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c index f733501c1..990960aa8 100644 --- a/arch/sh/kernel/semaphore.c +++ b/arch/sh/kernel/semaphore.c @@ -253,7 +253,7 @@ struct rw_semaphore *down_write_failed(struct rw_semaphore *sem) while (atomic_read(&sem->count) < 0) { set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (atomic_read(&sem->count) >= 0) - break; /* we must attempt to aquire or bias the lock */ + break; /* we must attempt to acquire or bias the lock */ schedule(); } diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index aaea2e6df..2f9e722fe 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -166,17 +166,13 @@ static int __init sh_console_setup(struct console *co, char *options) } static struct console sh_console = { - "bios", - sh_console_write, - NULL, - sh_console_device, - sh_console_wait_key, - NULL, - sh_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "bios", + write: sh_console_write, + device: sh_console_device, + wait_key: sh_console_wait_key, + setup: sh_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; void sh_console_init(void) @@ -371,7 +367,7 @@ void __init setup_arch(char **cmdline_p) * bootstrap step all allocations (until the page allocator * is intact) must be done via bootmem_alloc(). */ - bootmap_size = init_bootmem_node(0, start_pfn, + bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, __MEMORY_START>>PAGE_SHIFT, max_low_pfn); diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 5af1e6de8..552cbb3d3 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -213,7 +213,7 @@ static int set_rtc_time(unsigned long nowtime) } /* last time the RTC clock got updated */ -static long last_rtc_update = 0; +static long last_rtc_update; /* * timer_interrupt() needs to keep up the real-time clock, diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 9c06626da..b9c8c991b 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -231,8 +231,11 @@ do_sigbus: goto no_context; } -static int __do_page_fault1(struct pt_regs *regs, unsigned long writeaccess, - unsigned long address) +/* + * Called with interrupt disabled. + */ +asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, + unsigned long address) { pgd_t *dir; pmd_t *pmd; @@ -240,8 +243,6 @@ static int __do_page_fault1(struct pt_regs *regs, unsigned long writeaccess, pte_t entry; if (address >= VMALLOC_START && address < VMALLOC_END) - /* We can change the implementation of P3 area pte entries. - set_pgdir and such. */ dir = pgd_offset_k(address); else dir = pgd_offset(current->mm, address); @@ -275,23 +276,6 @@ static int __do_page_fault1(struct pt_regs *regs, unsigned long writeaccess, return 0; } -/* - * Called with interrupt disabled. - */ -asmlinkage void __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, - unsigned long address) -{ - /* - * XXX: Could you please implement this (calling __do_page_fault1) - * in assembler language in entry.S? - */ - if (__do_page_fault1(regs, writeaccess, address) == 0) - /* Done. */ - return; - sti(); - do_page_fault(regs, writeaccess, address); -} - void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) { diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 8568afb31..5a0ac1f10 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -40,8 +40,8 @@ */ unsigned long mmu_context_cache; -static unsigned long totalram_pages = 0; -static unsigned long totalhigh_pages = 0; +static unsigned long totalram_pages; +static unsigned long totalhigh_pages; extern unsigned long init_smp_mappings(unsigned long); diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index 2dd1e6ec2..d859f3440 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -17,6 +17,9 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned l unsigned long phys_addr, unsigned long flags) { unsigned long end; + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | + _PAGE_DIRTY | _PAGE_ACCESSED | + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | flags); address &= ~PMD_MASK; end = address + size; @@ -25,8 +28,7 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned l do { if (!pte_none(*pte)) printk("remap_area_pte: page already exists\n"); - set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | _PAGE_RW | - _PAGE_DIRTY | _PAGE_ACCESSED | flags))); + set_pte(pte, mk_pte_phys(phys_addr, pgprot)); address += PAGE_SIZE; phys_addr += PAGE_SIZE; pte++; @@ -55,22 +57,21 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo } static int remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) + unsigned long size, unsigned long flags) { pgd_t * dir; unsigned long end = address + size; phys_addr -= address; - dir = pgd_offset(&init_mm, address); + dir = pgd_offset_k(address); flush_cache_all(); while (address < end) { pmd_t *pmd = pmd_alloc_kernel(dir, address); if (!pmd) return -ENOMEM; if (remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) + phys_addr + address, flags)) return -ENOMEM; - set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } diff --git a/arch/sparc/config.in b/arch/sparc/config.in index 0a7c2140a..cb615fa0b 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.102 2000/08/23 05:59:28 davem Exp $ +# $Id: config.in,v 1.104 2000/10/04 09:01:38 anton Exp $ # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. # @@ -94,7 +94,7 @@ dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET # bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y #fi -include drivers/md/Config.in +source drivers/md/Config.in tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index b508bab4c..f61be9932 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -1,4 +1,4 @@ -/* $Id: ebus.c,v 1.10 2000/06/20 01:10:00 anton Exp $ +/* $Id: ebus.c,v 1.11 2000/10/10 01:07:38 davem Exp $ * ebus.c: PCI to EBus bridge device. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -27,9 +27,6 @@ struct linux_ebus *ebus_chain = 0; #ifdef CONFIG_SUN_OPENPROMIO extern int openprom_init(void); #endif -#ifdef CONFIG_SPARCAUDIO -extern int sparcaudio_init(void); -#endif #ifdef CONFIG_SUN_AUXIO extern void auxio_probe(void); #endif @@ -374,9 +371,6 @@ void __init ebus_init(void) openprom_init(); #endif -#ifdef CONFIG_SPARCAUDIO - sparcaudio_init(); -#endif #ifdef CONFIG_SUN_BPP bpp_init(); #endif diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index ca81aa872..e0be43e08 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -1,4 +1,4 @@ -/* $Id: ioport.c,v 1.39 2000/06/20 01:10:00 anton Exp $ +/* $Id: ioport.c,v 1.40 2000/10/10 09:44:46 anton Exp $ * ioport.c: Simple io mapping allocator. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -244,6 +244,7 @@ static void _sparc_free_io(struct resource *res) unsigned long plen; plen = res->end - res->start + 1; + plen = (plen + PAGE_SIZE-1) & PAGE_MASK; while (plen != 0) { plen -= PAGE_SIZE; (*_sparc_unmapioaddr)(res->start + plen); @@ -323,7 +324,7 @@ void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba) return; } - if (((unsigned long)p & (PAGE_MASK-1)) != 0) { + if (((unsigned long)p & (PAGE_SIZE-1)) != 0) { printk("sbus_free_consistent: unaligned va %p\n", p); return; } @@ -496,7 +497,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba) if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { free_pages(va, order); - printk("sbus_alloc_consistent: no core\n"); + printk("pci_alloc_consistent: no core\n"); return NULL; } memset((char*)res, 0, sizeof(struct resource)); @@ -546,18 +547,18 @@ void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba) if ((res = _sparc_find_resource(&_sparc_dvma, (unsigned long)p)) == NULL) { - printk("sbus_free_consistent: cannot free %p\n", p); + printk("pci_free_consistent: cannot free %p\n", p); return; } - if (((unsigned long)p & (PAGE_MASK-1)) != 0) { - printk("sbus_free_consistent: unaligned va %p\n", p); + if (((unsigned long)p & (PAGE_SIZE-1)) != 0) { + printk("pci_free_consistent: unaligned va %p\n", p); return; } n = (n + PAGE_SIZE-1) & PAGE_MASK; if ((res->end-res->start)+1 != n) { - printk("sbus_free_consistent: region 0x%lx asked 0x%lx\n", + printk("pci_free_consistent: region 0x%lx asked 0x%lx\n", (long)((res->end-res->start)+1), (long)n); return; } diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index fe45f1f3c..878147763 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.153 2000/09/06 00:45:01 davem Exp $ +/* $Id: process.c,v 1.154 2000/10/05 06:12:57 anton Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -234,6 +234,7 @@ void show_backtrace(void) void smp_show_backtrace_all_cpus(void) { xc0((smpfunc_t) show_backtrace); + show_backtrace(); } #endif diff --git a/arch/sparc/kernel/semaphore.c b/arch/sparc/kernel/semaphore.c index 1dcf35d42..4359ec232 100644 --- a/arch/sparc/kernel/semaphore.c +++ b/arch/sparc/kernel/semaphore.c @@ -1,4 +1,4 @@ -/* $Id: semaphore.c,v 1.2 1999/12/28 11:50:37 jj Exp $ +/* $Id: semaphore.c,v 1.3 2000/10/14 10:09:00 davem Exp $ * Generic semaphore code. Buyer beware. Do your own * specific changes in <asm/semaphore-helper.h> */ @@ -218,7 +218,7 @@ void down_write_failed(struct rw_semaphore *sem) while (sem->count < 0) { set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (sem->count >= 0) - break; /* we must attempt to aquire or bias the lock */ + break; /* we must attempt to acquire or bias the lock */ schedule(); } diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index bce4ffcdf..2a0fe9a27 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.119 2000/08/31 10:24:17 anton Exp $ +/* $Id: setup.c,v 1.120 2000/10/14 10:09:00 davem Exp $ * linux/arch/sparc/kernel/setup.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -287,7 +287,9 @@ static void prom_cons_write(struct console *con, const char *str, unsigned count } static struct console prom_console = { - "PROM", prom_cons_write, 0, 0, 0, 0, 0, CON_PRINTBUFFER, 0, 0, 0 + name: "PROM", + write: prom_cons_write, + flags: CON_PRINTBUFFER, }; #endif diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 0e1944411..414dfd076 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c @@ -145,33 +145,33 @@ void __init smp_boot_cpus(void) void smp_flush_cache_all(void) { xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); + local_flush_cache_all(); } void smp_flush_tlb_all(void) { xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all)); + local_flush_tlb_all(); } void smp_flush_cache_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_cache_mm(mm); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm); + local_flush_cache_mm(mm); } } void smp_flush_tlb_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) { - local_flush_tlb_mm(mm); - } else { + if(mm->cpu_vm_mask != (1 << smp_processor_id())) { xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm); if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) mm->cpu_vm_mask = (1 << smp_processor_id()); } + local_flush_tlb_mm(mm); } } @@ -179,10 +179,9 @@ void smp_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_cache_range(mm, start, end); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) mm, start, end); + local_flush_cache_range(mm, start, end); } } @@ -190,10 +189,9 @@ void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_tlb_range(mm, start, end); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) mm, start, end); + local_flush_tlb_range(mm, start, end); } } @@ -202,10 +200,9 @@ void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_cache_page(vma, page); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page); + local_flush_cache_page(vma, page); } } @@ -214,10 +211,9 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_tlb_page(vma, page); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page); + local_flush_tlb_page(vma, page); } } @@ -231,17 +227,15 @@ void smp_flush_page_to_ram(unsigned long page) */ #if 1 xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_to_ram), page); -#else - local_flush_page_to_ram(page); #endif + local_flush_page_to_ram(page); } void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_sig_insns(mm, insn_addr); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr); + local_flush_sig_insns(mm, insn_addr); } /* Reschedule call back. */ diff --git a/arch/sparc/kernel/sparc-stub.c b/arch/sparc/kernel/sparc-stub.c index a0e5f6ad2..828e4deed 100644 --- a/arch/sparc/kernel/sparc-stub.c +++ b/arch/sparc/kernel/sparc-stub.c @@ -1,4 +1,4 @@ -/* $Id: sparc-stub.c,v 1.26 1999/12/27 06:08:34 anton Exp $ +/* $Id: sparc-stub.c,v 1.27 2000/10/03 07:28:49 anton Exp $ * sparc-stub.c: KGDB support for the Linux kernel. * * Modifications to run under Linux diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 3a4e93eb8..280392629 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -376,9 +376,6 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } } - /* First, run local copy. */ - func(arg1, arg2, arg3, arg4, arg5); - { register int i; @@ -396,8 +393,6 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } spin_unlock_irqrestore(&cross_call_lock, flags); - } else { - func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */ } } diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 52c37f51b..d6c126d00 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -405,9 +405,6 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } } - /* First, run local copy. */ - func(arg1, arg2, arg3, arg4, arg5); - { register int i; @@ -425,8 +422,6 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } spin_unlock_irqrestore(&cross_call_lock, flags); - } else { - func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */ } } diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c index 4c86d7658..0deef8989 100644 --- a/arch/sparc/mm/fault.c +++ b/arch/sparc/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.116 2000/05/03 06:37:03 davem Exp $ +/* $Id: fault.c,v 1.117 2000/10/16 14:32:50 anton Exp $ * fault.c: Page fault handlers for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -200,11 +200,24 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, siginfo_t info; int from_user = !(regs->psr & PSR_PS); - info.si_code = SEGV_MAPERR; if(text_fault) address = regs->pc; /* + * We fault-in kernel-space virtual memory on-demand. The + * 'reference' page table is init_mm.pgd. + * + * NOTE! We MUST NOT take any locks for this case. We may + * be in an interrupt or a critical region, and should + * only copy the information from the master page table, + * nothing more. + */ + if (!ARCH_SUN4C_SUN4 && address >= TASK_SIZE) + goto vmalloc_fault; + + info.si_code = SEGV_MAPERR; + + /* * If we're in an interrupt or have no user * context, we must not take the fault.. */ @@ -271,6 +284,7 @@ good_area: bad_area: up(&mm->mmap_sem); +bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if(from_user) { #if 0 @@ -340,6 +354,35 @@ do_sigbus: force_sig_info (SIGBUS, &info, tsk); if (!from_user) goto no_context; + +vmalloc_fault: + { + /* + * Synchronize this task's top level page-table + * with the 'reference' page table. + */ + int offset = pgd_index(address); + pgd_t *pgd, *pgd_k; + pmd_t *pmd, *pmd_k; + + pgd = tsk->active_mm->pgd + offset; + pgd_k = init_mm.pgd + offset; + + if (!pgd_present(*pgd)) { + if (!pgd_present(*pgd_k)) + goto bad_area_nosemaphore; + pgd_set(pgd, *pgd_k); + return; + } + + pmd = pmd_offset(pgd, address); + pmd_k = pmd_offset(pgd_k, address); + + if (pmd_present(*pmd) || !pmd_present(*pmd_k)) + goto bad_area_nosemaphore; + pmd_set(pmd, *pmd_k); + return; + } } asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write, diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index 642c986bd..9cbbb1c9c 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.93 2000/08/31 11:40:55 anton Exp $ +/* $Id: init.c,v 1.94 2000/10/19 00:49:51 davem Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -42,7 +42,7 @@ unsigned long page_kernel; struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; unsigned long sparc_unmapped_base; -struct pgtable_cache_struct pgt_quicklists = { 0, 0, 0, 0 }; +struct pgtable_cache_struct pgt_quicklists; /* References to section boundaries */ extern char __init_begin, __init_end, _start, _end, etext , edata; diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 408d59cbf..a91809d03 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.222 2000/08/29 08:59:23 davem Exp $ +/* $Id: srmmu.c,v 1.223 2000/10/16 14:32:49 anton Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -69,9 +69,6 @@ pgd_t *srmmu_swapper_pg_dir; #define FLUSH_END } #endif -BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *) -#define pmd_set(pmdp,ptep) BTFIXUP_CALL(pmd_set)(pmdp,ptep) - BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long) #define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page) @@ -482,19 +479,6 @@ static void srmmu_pmd_free(pmd_t * pmd) srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE); } -static void srmmu_set_pgdir(unsigned long address, pgd_t entry) -{ - struct task_struct * p; - - read_lock(&tasklist_lock); - for_each_task(p) { - if (!p->mm) - continue; - *srmmu_pgd_offset(p->mm,address) = entry; - } - read_unlock(&tasklist_lock); -} - static inline void alloc_context(struct mm_struct *old_mm, struct mm_struct *mm) { struct ctx_list *ctxp; @@ -2148,8 +2132,6 @@ void __init ld_mmu_srmmu(void) #endif BTFIXUPSET_CALL(do_check_pgt_cache, srmmu_check_pgt_cache, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(set_pgdir, srmmu_set_pgdir, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(set_pte, srmmu_set_pte, BTFIXUPCALL_SWAPO0O1); BTFIXUPSET_CALL(switch_mm, srmmu_switch_mm, BTFIXUPCALL_NORM); @@ -2175,6 +2157,7 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(mk_pte_phys, srmmu_mk_pte_phys, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(mk_pte_io, srmmu_mk_pte_io, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pgd_set, srmmu_pgd_set, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_set, srmmu_pmd_set, BTFIXUPCALL_NORM); BTFIXUPSET_INT(pte_modify_mask, SRMMU_CHG_MASK); BTFIXUPSET_CALL(pmd_offset, srmmu_pmd_offset, BTFIXUPCALL_NORM); @@ -2209,9 +2192,6 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(free_task_struct, srmmu_free_task_struct, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(get_task_struct, srmmu_get_task_struct, BTFIXUPCALL_NORM); - /* SRMMU specific. */ - BTFIXUPSET_CALL(pmd_set, srmmu_pmd_set, BTFIXUPCALL_NORM); - get_srmmu_type(); patch_window_trap_handlers(); diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index a99ce736e..a416ecf19 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.199 2000/08/29 08:59:23 davem Exp $ +/* $Id: sun4c.c,v 1.200 2000/10/16 14:32:49 anton Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -1904,6 +1904,10 @@ static void sun4c_pgd_set(pgd_t * pgdp, pmd_t * pmdp) { } +static void sun4c_pmd_set(pmd_t * pmdp, pte_t * ptep) +{ +} + void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly) { @@ -2267,11 +2271,6 @@ extern __inline__ pgd_t *sun4c_get_pgd_fast(void) return (pgd_t *)ret; } -static void sun4c_set_pgdir(unsigned long address, pgd_t entry) -{ - /* Nothing to do */ -} - extern __inline__ void sun4c_free_pgd_fast(pgd_t *pgd) { *(unsigned long *)pgd = (unsigned long) pgd_quicklist; @@ -2616,8 +2615,6 @@ void __init ld_mmu_sun4c(void) #endif BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(set_pgdir, sun4c_set_pgdir, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(flush_cache_all, sun4c_flush_cache_all, BTFIXUPCALL_NORM); if (sun4c_vacinfo.do_hwflushes) { @@ -2719,4 +2716,5 @@ void __init ld_mmu_sun4c(void) /* These should _never_ get called with two level tables. */ BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP); BTFIXUPSET_CALL(pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NOP); } diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index c49a87ebf..a754b796b 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.121 2000/08/23 05:59:28 davem Exp $ +# $Id: config.in,v 1.125 2000/10/10 01:05:53 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -89,12 +89,7 @@ bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET -#tristate 'Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM N -#if [ "$CONFIG_BLK_DEV_LVM" != "n" ]; then -# bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y -#fi - -include drivers/md/Config.in +source drivers/md/Config.in tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then @@ -166,7 +161,7 @@ if [ "$CONFIG_SCSI" != "n" ]; then if [ "$CONFIG_PCI" != "n" ]; then dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then - bool ' Enable tagged command queueing (TCQ) by default' CONFIG_AIC7XXX_TAGGED_QUEUEING Y + bool ' Enable tagged command queueing (TCQ) by default' CONFIG_AIC7XXX_TAGGED_QUEUEING int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8 bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5 diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index b2088bc86..7c2f852b3 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -138,10 +138,18 @@ CONFIG_SPARCAUDIO_CS4231=y CONFIG_BLK_DEV_FD=y CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m + +# +# 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_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set @@ -181,6 +189,7 @@ CONFIG_DECNET_SIOCGIFCONF=y # 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 @@ -254,10 +263,11 @@ CONFIG_BLK_DEV_NS87415=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set # CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_OSB4 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_VIA82CXXX_TUNING is not set # CONFIG_IDE_CHIPSETS is not set CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index 84b4224e5..9f7cd59e9 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.98 2000/08/16 12:33:00 davem Exp $ +/* $Id: ioctl32.c,v 1.99 2000/10/17 16:20:33 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -3221,9 +3221,16 @@ COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)) /* Little p (/dev/rtc, /dev/envctrl, etc.) */ COMPATIBLE_IOCTL(RTCGET) COMPATIBLE_IOCTL(RTCSET) -COMPATIBLE_IOCTL(I2CIOCSADR) -COMPATIBLE_IOCTL(I2CIOCGADR) -COMPATIBLE_IOCTL(D7SIOCRD) +COMPATIBLE_IOCTL(ENVCTRL_RD_WARNING_TEMPERATURE) +COMPATIBLE_IOCTL(ENVCTRL_RD_SHUTDOWN_TEMPERATURE) +COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_TEMPERATURE) +COMPATIBLE_IOCTL(ENVCTRL_RD_FAN_STATUS) +COMPATIBLE_IOCTL(ENVCTRL_RD_VOLTAGE_STATUS) +COMPATIBLE_IOCTL(ENVCTRL_RD_SCSI_TEMPERATURE) +COMPATIBLE_IOCTL(ENVCTRL_RD_ETHERNET_TEMPERATURE) +COMPATIBLE_IOCTL(ENVCTRL_RD_MTHRBD_TEMPERATURE) +COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_VOLTAGE) +/* COMPATIBLE_IOCTL(D7SIOCRD) same value as ENVCTRL_RD_VOLTAGE_STATUS */ COMPATIBLE_IOCTL(D7SIOCWR) COMPATIBLE_IOCTL(D7SIOCTM) /* Little m */ diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 24b1a7217..dd153a24e 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.17 2000/09/05 06:49:44 anton Exp $ +/* $Id: pci.c,v 1.18 2000/10/03 11:31:42 anton Exp $ * pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c index 0919089ef..8cb6e7211 100644 --- a/arch/sparc64/kernel/semaphore.c +++ b/arch/sparc64/kernel/semaphore.c @@ -1,4 +1,4 @@ -/* $Id: semaphore.c,v 1.3 2000/03/27 10:38:46 davem Exp $ +/* $Id: semaphore.c,v 1.4 2000/10/14 10:09:00 davem Exp $ * Generic semaphore code. Buyer beware. Do your own * specific changes in <asm/semaphore-helper.h> */ @@ -275,7 +275,7 @@ void down_write_failed(struct rw_semaphore *sem) while (sem->count < 0) { set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (sem->count >= 0) - break; /* we must attempt to aquire or bias the lock */ + break; /* we must attempt to acquire or bias the lock */ schedule(); } diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 84cc201fd..fa46489c1 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.56 2000/09/21 06:29:01 anton Exp $ +/* $Id: setup.c,v 1.57 2000/10/14 10:09:00 davem Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -75,17 +75,10 @@ prom_console_write(struct console *con, const char *s, unsigned n) } static struct console prom_console = { - "prom", - prom_console_write, - NULL, - NULL, - NULL, - NULL, - NULL, - CON_CONSDEV | CON_ENABLED, - -1, - 0, - NULL + name: "prom", + write: prom_console_write, + flags: CON_CONSDEV | CON_ENABLED, + index: -1, }; #define PROM_TRUE -1 @@ -294,17 +287,10 @@ unsigned long cmdline_memory_size = 0; #ifdef PROM_DEBUG_CONSOLE static struct console prom_debug_console = { - "debug", - prom_console_write, - NULL, - NULL, - NULL, - NULL, - NULL, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "debug", + write: prom_console_write, + flags: CON_PRINTBUFFER, + index: -1, }; #endif diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index dbcb1f09e..d32fd4721 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -28,6 +28,7 @@ #include <asm/softirq.h> #include <asm/uaccess.h> #include <asm/timer.h> +#include <asm/starfire.h> #define __KERNEL_SYSCALLS__ #include <linux/unistd.h> @@ -302,9 +303,17 @@ void __init smp_boot_cpus(void) static inline void xcall_deliver(u64 data0, u64 data1, u64 data2, u64 pstate, unsigned long cpu) { - u64 result, target = (cpu << 14) | 0x70; + u64 result, target; int stuck, tmp; + if (this_is_starfire) { + /* map to real upaid */ + cpu = (((cpu & 0x3c) << 1) | + ((cpu & 0x40) >> 4) | + (cpu & 0x3)); + } + + target = (cpu << 14) | 0x70; #ifdef XCALL_DEBUG printk("CPU[%d]: xcall(data[%016lx:%016lx:%016lx],tgt[%016lx])\n", smp_processor_id(), data0, data1, data2, target); diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index c5559ef79..6e7f59309 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.92 2000/08/09 08:45:40 anton Exp $ +/* $Id: sparc64_ksyms.c,v 1.95 2000/10/30 21:01:40 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -18,6 +18,8 @@ #include <linux/in6.h> #include <linux/pci.h> #include <linux/interrupt.h> +#include <linux/fs_struct.h> +#include <linux/mm.h> #include <asm/oplib.h> #include <asm/delay.h> @@ -29,6 +31,7 @@ #include <asm/hardirq.h> #include <asm/idprom.h> #include <asm/svr4.h> +#include <asm/elf.h> #include <asm/head.h> #include <asm/smp.h> #include <asm/mostek.h> @@ -37,6 +40,7 @@ #include <asm/uaccess.h> #include <asm/checksum.h> #include <asm/fpumacro.h> +#include <asm/pgalloc.h> #ifdef CONFIG_SBUS #include <asm/sbus.h> #include <asm/dma.h> @@ -88,6 +92,7 @@ extern void __flush_dcache_page(void *addr); extern int __ashrdi3(int, int); extern void dump_thread(struct pt_regs *, struct user *); +extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); #ifdef CONFIG_SMP extern spinlock_t kernel_flag; @@ -230,6 +235,13 @@ EXPORT_SYMBOL(_sigpause_common); /* Should really be in linux/kernel/ksyms.c */ EXPORT_SYMBOL(dump_thread); +EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(get_pmd_slow); +EXPORT_SYMBOL(get_pte_slow); +#ifndef CONFIG_SMP +EXPORT_SYMBOL(pgt_quicklists); +#endif +EXPORT_SYMBOL(put_fs_struct); /* math-emu wants this */ EXPORT_SYMBOL(die_if_kernel); @@ -262,10 +274,9 @@ EXPORT_SYMBOL(__prom_getsibling); /* sparc library symbols */ EXPORT_SYMBOL(__strlen); -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 EXPORT_SYMBOL(strlen); -#endif EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(__strlen_user); EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strncpy); EXPORT_SYMBOL(strcat); diff --git a/arch/sparc64/kernel/starfire.c b/arch/sparc64/kernel/starfire.c index dc8f96b7a..6899e7c4a 100644 --- a/arch/sparc64/kernel/starfire.c +++ b/arch/sparc64/kernel/starfire.c @@ -1,4 +1,4 @@ -/* $Id: starfire.c,v 1.7 2000/09/22 23:02:13 davem Exp $ +/* $Id: starfire.c,v 1.8 2000/10/27 18:36:47 anton Exp $ * starfire.c: Starfire/E10000 support. * * Copyright (C) 1998 David S. Miller (davem@redhat.com) @@ -31,7 +31,12 @@ void check_if_starfire(void) void starfire_cpu_setup(void) { if (this_is_starfire) { -/* We do this in starfire_translate - Anton */ +/* + * We do this in starfire_translate and xcall_deliver. When we fix our cpu + * arrays to support > 64 processors we can use the real upaid instead + * of the logical cpuid in __cpu_number_map etc, then we can get rid of + * the translations everywhere. - Anton + */ #if 0 int i; diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 071510bbc..24c8cd593 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.164 2000/09/14 10:42:47 davem Exp $ +/* $Id: sys_sparc32.c,v 1.165 2000/10/10 04:47:31 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -2893,7 +2893,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact, /* * count32() counts the number of arguments/envelopes */ -static int count32(u32 * argv) +static int count32(u32 * argv, int max) { int i = 0; @@ -2902,9 +2902,13 @@ static int count32(u32 * argv) u32 p; int error; error = get_user(p,argv); - if (error) return error; - if (!p) break; - argv++; i++; + if (error) + return error; + if (!p) + break; + argv++; + if (++i > max) + return -E2BIG; } } return i; @@ -3001,12 +3005,12 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs) bprm.sh_bang = 0; bprm.loader = 0; bprm.exec = 0; - if ((bprm.argc = count32(argv)) < 0) { + if ((bprm.argc = count32(argv, bprm.p / sizeof(u32))) < 0) { allow_write_access(file); fput(file); return bprm.argc; } - if ((bprm.envc = count32(envp)) < 0) { + if ((bprm.envc = count32(envp, bprm.p / sizeof(u32))) < 0) { allow_write_access(file); fput(file); return bprm.envc; diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index d694e40f9..65fbd6e37 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.156 2000/09/21 06:34:48 anton Exp $ +/* $Id: init.c,v 1.157 2000/10/19 00:49:52 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -873,7 +873,7 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) } #endif /* Initialize the boot-time allocator. */ - bootmap_size = init_bootmem_node(0, bootmap_pfn, phys_base>>PAGE_SHIFT, end_pfn); + bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, phys_base>>PAGE_SHIFT, end_pfn); /* Now register the available physical memory with the * allocator. diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c index c40225584..bf2182381 100644 --- a/arch/sparc64/solaris/socksys.c +++ b/arch/sparc64/solaris/socksys.c @@ -1,4 +1,4 @@ -/* $Id: socksys.c,v 1.16 2000/07/27 00:03:48 davem Exp $ +/* $Id: socksys.c,v 1.17 2000/10/19 00:49:53 davem Exp $ * socksys.c: /dev/inet/ stuff for Solaris emulation. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -161,7 +161,7 @@ static struct file_operations socksys_fops = { release: socksys_release, }; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; int __init init_socksys(void) diff --git a/drivers/Makefile b/drivers/Makefile index 1720f7997..9b5c9ec6d 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -28,9 +28,9 @@ subdir-$(CONFIG_USB) += usb subdir-$(CONFIG_INPUT) += input subdir-$(CONFIG_PHONE) += telephony subdir-$(CONFIG_SGI) += sgi -subdir-$(CONFIG_I2O) += i2o subdir-$(CONFIG_IDE) += ide subdir-$(CONFIG_SCSI) += scsi +subdir-$(CONFIG_I2O) += i2o subdir-$(CONFIG_MD) += md subdir-$(CONFIG_IEEE1394) += ieee1394 subdir-$(CONFIG_PNP) += pnp diff --git a/drivers/acorn/char/defkeymap-acorn.c b/drivers/acorn/char/defkeymap-acorn.c index 44bca7093..1d2d8a640 100644 --- a/drivers/acorn/char/defkeymap-acorn.c +++ b/drivers/acorn/char/defkeymap-acorn.c @@ -285,7 +285,7 @@ char func_buf[] = { char *funcbufptr = func_buf; int funcbufsize = sizeof(func_buf); -int funcbufleft = 0; /* space left */ +int funcbufleft; /* space left */ char *func_table[MAX_NR_FUNC] = { func_buf + 0, diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index a8bda5927..5d4fdd543 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2920,7 +2920,7 @@ fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page) #ifdef MODULE -static unsigned int __init +static int __init fore200e_module_init(void) { DPRINTK(1, "module loaded\n"); diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 3550acd41..e4d709cb0 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -259,7 +259,7 @@ static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr); /* Global variables ***********************************************************/ static struct ns_dev *cards[NS_MAX_CARDS]; -static unsigned num_cards = 0; +static unsigned num_cards; static struct atmdev_ops atm_ops = { open: ns_open, diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 318e14f86..dba6b5adf 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -51,7 +51,7 @@ */ static int - DAC960_ControllerCount = 0; + DAC960_ControllerCount; /* @@ -60,7 +60,7 @@ static int */ static int - DAC960_ActiveControllerCount = 0; + DAC960_ActiveControllerCount; /* @@ -69,7 +69,7 @@ static int */ static DAC960_Controller_T - *DAC960_Controllers[DAC960_MaxControllers] = { NULL }; + *DAC960_Controllers[DAC960_MaxControllers]; /* @@ -5679,7 +5679,7 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel, } if (MessageLevel == DAC960_AnnounceLevel) { - static int AnnouncementLines = 0; + static int AnnouncementLines; if (++AnnouncementLines <= 2) printk("%sDAC960: %s", DAC960_MessageLevelMap[MessageLevel], Buffer); diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c index b8f1c693e..35bab96fe 100644 --- a/drivers/block/acsi_slm.c +++ b/drivers/block/acsi_slm.c @@ -942,7 +942,7 @@ static int slm_get_pagesize( int device, int *w, int *h ) int attach_slm( int target, int lun ) -{ static int did_register = 0; +{ static int did_register; int len; if (N_SLM_Printers >= MAX_SLM) { @@ -992,7 +992,7 @@ int attach_slm( int target, int lun ) return( 1 ); } -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; int slm_init( void ) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index f88762bb1..75f59e77a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -71,10 +71,10 @@ static struct board_type products[] = { #define READ_AHEAD 128 #define NR_CMDS 128 /* #commands that can be outstanding */ #define MAX_CTLR 8 -static int nr_ctlr =0; -static ctlr_info_t *hba[MAX_CTLR] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static int nr_ctlr; +static ctlr_info_t *hba[MAX_CTLR]; -static struct proc_dir_entry *proc_cciss = NULL; +static struct proc_dir_entry *proc_cciss; static void do_cciss_request(int i); /* diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index f26611bc3..0bfa895b7 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -68,10 +68,10 @@ MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers"); #define MAX_CTLR 8 #define CTLR_SHIFT 8 -static int nr_ctlr = 0; -static ctlr_info_t *hba[MAX_CTLR] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static int nr_ctlr; +static ctlr_info_t *hba[MAX_CTLR]; -static int eisa[8] = { 0, 0 ,0 ,0, 0, 0 ,0 ,0 }; +static int eisa[8]; #define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type)) @@ -103,7 +103,7 @@ static int * ida_blocksizes; static int * ida_hardsizes; static struct gendisk ida_gendisk[MAX_CTLR]; -static struct proc_dir_entry *proc_array = NULL; +static struct proc_dir_entry *proc_array; /* Debug... */ #define DBG(s) do { s } while(0) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 2b26bb66b..613841745 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3435,6 +3435,7 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g) static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param) { +#define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data) #define OUT(c,x) case c: outparam = (const char *) (x); break #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0 @@ -3502,7 +3503,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return -EINVAL; /* permission checks */ - if (((cmd & 0x40) && !(filp->f_mode & 2)) || + if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) || ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))) return -EPERM; @@ -3708,6 +3709,8 @@ static int floppy_open(struct inode * inode, struct file * filp) return -EIO; } + filp->private_data = (void*) 0; + drive = DRIVE(inode->i_rdev); if (drive >= N_DRIVE || !(allowed_drive_mask & (1 << drive)) || @@ -3775,6 +3778,13 @@ static int floppy_open(struct inode * inode, struct file * filp) invalidate_buffers(MKDEV(FLOPPY_MAJOR,old_dev)); } + /* Allow ioctls if we have write-permissions even if read-only open. + * Needed so that programs such as fdrawcmd still can work on write + * protected disks */ + if ((filp->f_mode & 2) || + (inode->i_sb && (permission(inode,2) == 0))) + filp->private_data = (void*) 8; + if (UFDCS->rawcmd == 1) UFDCS->rawcmd = 2; diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index db562b8ac..d9d3f8622 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -328,7 +328,7 @@ static int ll_merge_requests_fn(request_queue_t *q, struct request *req, * on the list. * * This is called with interrupts off and no requests on the queue. - * (and with the request spinlock aquired) + * (and with the request spinlock acquired) */ static void generic_plug_device(request_queue_t *q, kdev_t dev) { @@ -570,7 +570,7 @@ inline void drive_stat_acct (kdev_t dev, int rw, /* * add-request adds a request to the linked list. - * It disables interrupts (aquires the request spinlock) so that it can muck + * It disables interrupts (acquires the request spinlock) so that it can muck * with the request-lists in peace. Thus it should be called with no spinlocks * held. * @@ -624,7 +624,7 @@ void inline blkdev_release_request(struct request *req) } /* - * Has to be called with the request spinlock aquired + * Has to be called with the request spinlock acquired */ static void attempt_merge(request_queue_t * q, struct request *req, diff --git a/drivers/block/loop.c b/drivers/block/loop.c index da1d6629d..329d10c9c 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -80,7 +80,7 @@ static int max_loop = 8; static struct loop_device *loop_dev; static int *loop_sizes; static int *loop_blksizes; -static devfs_handle_t devfs_handle = NULL; /* For the directory */ +static devfs_handle_t devfs_handle; /* For the directory */ #define FALSE 0 #define TRUE (!FALSE) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 436969bb4..7dfb101ab 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -55,7 +55,7 @@ static int nbd_sizes[MAX_NBD]; static u64 nbd_bytesizes[MAX_NBD]; static struct nbd_device nbd_dev[MAX_NBD]; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; #define DEBUG( s ) /* #define DEBUG( s ) printk( s ) @@ -106,7 +106,7 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size) do { - sock->sk->allocation = GFP_ATOMIC; + sock->sk->allocation = GFP_BUFFER; iov.iov_base = buf; iov.iov_len = size; msg.msg_name = NULL; diff --git a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile index 9f5293530..86dbc0a89 100644 --- a/drivers/block/paride/Makefile +++ b/drivers/block/paride/Makefile @@ -1,183 +1,34 @@ # -# Makefile for PARIDE +# Makefile for Parallel port IDE device drivers. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). +# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> +# Rewritten to use lists instead of if-statements. # -# Note 2! The CFLAGS definitions are now inherited from the -# parent makes.. - -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -ALL_SUB_DIRS := $(SUB_DIRS) L_TARGET := paride.a -MX_OBJS := -LX_OBJS := -MI_OBJS := -MIX_OBJS := - -ifeq ($(CONFIG_PARIDE),y) - LX_OBJS += paride.o -else - ifeq ($(CONFIG_PARIDE),m) - MX_OBJS += paride.o - endif -endif - -ifeq ($(CONFIG_PARIDE_PD),y) - LX_OBJS += pd.o -else - ifeq ($(CONFIG_PARIDE_PD),m) - M_OBJS += pd.o - endif -endif - -ifeq ($(CONFIG_PARIDE_PCD),y) - LX_OBJS += pcd.o -else - ifeq ($(CONFIG_PARIDE_PCD),m) - M_OBJS += pcd.o - endif -endif - -ifeq ($(CONFIG_PARIDE_PF),y) - LX_OBJS += pf.o -else - ifeq ($(CONFIG_PARIDE_PF),m) - M_OBJS += pf.o - endif -endif - -ifeq ($(CONFIG_PARIDE_PT),y) - LX_OBJS += pt.o -else - ifeq ($(CONFIG_PARIDE_PT),m) - M_OBJS += pt.o - endif -endif - -ifeq ($(CONFIG_PARIDE_PG),y) - LX_OBJS += pg.o -else - ifeq ($(CONFIG_PARIDE_PG),m) - M_OBJS += pg.o - endif -endif - -ifeq ($(CONFIG_PARIDE_ATEN),y) - LX_OBJS += aten.o -else - ifeq ($(CONFIG_PARIDE_ATEN),m) - M_OBJS += aten.o - endif -endif - -ifeq ($(CONFIG_PARIDE_BPCK),y) - LX_OBJS += bpck.o -else - ifeq ($(CONFIG_PARIDE_BPCK),m) - M_OBJS += bpck.o - endif -endif - -ifeq ($(CONFIG_PARIDE_COMM),y) - LX_OBJS += comm.o -else - ifeq ($(CONFIG_PARIDE_COMM),m) - M_OBJS += comm.o - endif -endif - -ifeq ($(CONFIG_PARIDE_DSTR),y) - LX_OBJS += dstr.o -else - ifeq ($(CONFIG_PARIDE_DSTR),m) - M_OBJS += dstr.o - endif -endif -ifeq ($(CONFIG_PARIDE_KBIC),y) - LX_OBJS += kbic.o -else - ifeq ($(CONFIG_PARIDE_KBIC),m) - M_OBJS += kbic.o - endif -endif - -ifeq ($(CONFIG_PARIDE_EPAT),y) - LX_OBJS += epat.o -else - ifeq ($(CONFIG_PARIDE_EPAT),m) - M_OBJS += epat.o - endif -endif - -ifeq ($(CONFIG_PARIDE_EPIA),y) - LX_OBJS += epia.o -else - ifeq ($(CONFIG_PARIDE_EPIA),m) - M_OBJS += epia.o - endif -endif - -ifeq ($(CONFIG_PARIDE_FIT2),y) - LX_OBJS += fit2.o -else - ifeq ($(CONFIG_PARIDE_FIT2),m) - M_OBJS += fit2.o - endif -endif - -ifeq ($(CONFIG_PARIDE_FIT3),y) - LX_OBJS += fit3.o -else - ifeq ($(CONFIG_PARIDE_FIT3),m) - M_OBJS += fit3.o - endif -endif - -ifeq ($(CONFIG_PARIDE_FRPW),y) - LX_OBJS += frpw.o -else - ifeq ($(CONFIG_PARIDE_FRPW),m) - M_OBJS += frpw.o - endif -endif - - -ifeq ($(CONFIG_PARIDE_FRIQ),y) - LX_OBJS += friq.o -else - ifeq ($(CONFIG_PARIDE_FRIQ),m) - M_OBJS += friq.o - endif -endif - -ifeq ($(CONFIG_PARIDE_ON20),y) - LX_OBJS += on20.o -else - ifeq ($(CONFIG_PARIDE_ON20),m) - M_OBJS += on20.o - endif -endif - -ifeq ($(CONFIG_PARIDE_ON26),y) - LX_OBJS += on26.o -else - ifeq ($(CONFIG_PARIDE_ON26),m) - M_OBJS += on26.o - endif -endif - -ifeq ($(CONFIG_PARIDE_KTTI),y) - LX_OBJS += ktti.o -else - ifeq ($(CONFIG_PARIDE_KTTI),m) - M_OBJS += ktti.o - endif -endif +obj-$(CONFIG_PARIDE) += paride.o +obj-$(CONFIG_PARIDE_PD) += pd.o +obj-$(CONFIG_PARIDE_PCD) += pcd.o +obj-$(CONFIG_PARIDE_PF) += pf.o +obj-$(CONFIG_PARIDE_PT) += pt.o +obj-$(CONFIG_PARIDE_PG) += pg.o +obj-$(CONFIG_PARIDE_ATEN) += aten.o +obj-$(CONFIG_PARIDE_BPCK) += bpck.o +obj-$(CONFIG_PARIDE_COMM) += comm.o +obj-$(CONFIG_PARIDE_DSTR) += dstr.o +obj-$(CONFIG_PARIDE_KBIC) += kbic.o +obj-$(CONFIG_PARIDE_EPAT) += epat.o +obj-$(CONFIG_PARIDE_EPIA) += epia.o +obj-$(CONFIG_PARIDE_FIT2) += fit2.o +obj-$(CONFIG_PARIDE_FIT3) += fit3.o +obj-$(CONFIG_PARIDE_FRPW) += frpw.o +obj-$(CONFIG_PARIDE_FRIQ) += friq.o +obj-$(CONFIG_PARIDE_ON20) += on20.o +obj-$(CONFIG_PARIDE_ON26) += on26.o +obj-$(CONFIG_PARIDE_KTTI) += ktti.o + +L_OBJS := $(obj-y) +M_OBJS := $(obj-m) include $(TOPDIR)/Rules.make - diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index e2709ce97..65ab11859 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -289,7 +289,7 @@ void pg_init_units( void ) } } -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; int pg_init (void) /* preliminary initialisation */ diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 5cb91ae0a..51f67b903 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -293,7 +293,7 @@ void pt_init_units( void ) } } -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; int pt_init (void) /* preliminary initialisation */ diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 2db08531a..6f583c3de 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -99,7 +99,7 @@ static unsigned long rd_length[NUM_RAMDISKS]; /* Size of RAM disks in bytes */ static int rd_hardsec[NUM_RAMDISKS]; /* Size of real blocks in bytes */ static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */ static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */ -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static struct inode *rd_inode[NUM_RAMDISKS]; /* Protected device inodes */ /* @@ -778,11 +778,11 @@ typedef unsigned long ulg; static uch *inbuf; static uch *window; -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 */ -static int exit_code = 0; -static long bytes_out = 0; +static unsigned insize; /* valid bytes in inbuf */ +static unsigned inptr; /* index of next byte to be processed in inbuf */ +static unsigned outcnt; /* bytes in output buffer */ +static int exit_code; +static long bytes_out; static struct file *crd_infp, *crd_outfp; #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) diff --git a/drivers/block/xd.c b/drivers/block/xd.c index b5df63bd9..6726535c4 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -142,9 +142,9 @@ static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open); static u_char xd_valid[XD_MAXDRIVES] = { 0,0 }; static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors; -static u_char xd_override __initdata, xd_type __initdata; +static u_char xd_override __initdata = 0, xd_type __initdata = 0; static u_short xd_iobase = 0x320; -static int xd_geo[XD_MAXDRIVES*3] __initdata; +static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, }; static volatile int xdc_busy; static DECLARE_WAIT_QUEUE_HEAD(xdc_wait); @@ -518,7 +518,7 @@ static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count) if (nodma) return (PIO_MODE); - if (((u_int) buffer & 0xFFFF0000) != (((u_int) buffer + count) & 0xFFFF0000)) { + if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) { #ifdef DEBUG_OTHER printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n"); #endif /* DEBUG_OTHER */ @@ -529,7 +529,7 @@ static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count) disable_dma(xd_dma); clear_dma_ff(xd_dma); set_dma_mode(xd_dma,mode); - set_dma_addr(xd_dma,(u_int) buffer); + set_dma_addr(xd_dma, (unsigned long) buffer); set_dma_count(xd_dma,count); release_dma_lock(f); diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 912402678..23fe03584 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -267,15 +267,15 @@ #include <asm/uaccess.h> /* used to tell the module to turn on full debugging messages */ -static int debug = 0; +static int debug; /* used to keep tray locked at all times */ -static int keeplocked = 0; +static int keeplocked; /* default compatibility mode */ static int autoclose=1; -static int autoeject=0; +static int autoeject; static int lockdoor = 1; /* will we ever get to use this... sigh. */ -static int check_media_type = 0; +static int check_media_type; MODULE_PARM(debug, "i"); MODULE_PARM(autoclose, "i"); MODULE_PARM(autoeject, "i"); @@ -326,8 +326,8 @@ int cdrom_get_next_writable(kdev_t dev, long *next_writable); #ifdef CONFIG_SYSCTL static void cdrom_sysctl_register(void); #endif /* CONFIG_SYSCTL */ -static struct cdrom_device_info *topCdromPtr = NULL; -static devfs_handle_t devfs_handle = NULL; +static struct cdrom_device_info *topCdromPtr; +static devfs_handle_t devfs_handle; struct block_device_operations cdrom_fops = { @@ -346,12 +346,12 @@ struct block_device_operations cdrom_fops = int register_cdrom(struct cdrom_device_info *cdi) { - static char banner_printed = 0; + static char banner_printed; int major = MAJOR(cdi->dev); struct cdrom_device_ops *cdo = cdi->ops; int *change_capability = (int *)&cdo->capability; /* hack */ char vname[16]; - static unsigned int cdrom_counter = 0; + static unsigned int cdrom_counter; cdinfo(CD_OPEN, "entering register_cdrom\n"); @@ -2566,7 +2566,7 @@ static struct ctl_table_header *cdrom_sysctl_header; static void cdrom_sysctl_register(void) { - static int initialized = 0; + static int initialized; if (initialized == 1) return; diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c index 07e97a1d7..4cec5680d 100644 --- a/drivers/cdrom/sbpcd.c +++ b/drivers/cdrom/sbpcd.c @@ -561,9 +561,9 @@ static int sbpcd_debug = 0 & ((1<<DBG_INF) | static int sbpcd_ioaddr = CDROM_PORT; /* default I/O base address */ static int sbpro_type = SBPRO; -static unsigned char setup_done = 0; -static unsigned char f_16bit = 0; -static unsigned char do_16bit = 0; +static unsigned char setup_done; +static unsigned char f_16bit; +static unsigned char do_16bit; static int CDo_command, CDo_reset; static int CDo_sel_i_d, CDo_enable; static int CDi_info, CDi_status, CDi_data; @@ -575,7 +575,7 @@ static struct cdrom_subchnl SC; static struct cdrom_volctrl volctrl; static struct cdrom_read_audio read_audio; -static unsigned char msgnum=0; +static unsigned char msgnum; static char msgbuf[80]; static const char *str_sb = "SoundBlaster"; @@ -618,26 +618,26 @@ static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */ static u_char familyT[]="CD-55"; /* TEAC CD-55A */ static u_char familyV[]="ECS-AT"; /* ECS Vertos 100 */ -static u_int recursion=0; /* internal testing only */ -static u_int fatal_err=0; /* internal testing only */ -static u_int response_count=0; +static u_int recursion; /* internal testing only */ +static u_int fatal_err; /* internal testing only */ +static u_int response_count; static u_int flags_cmd_out; -static u_char cmd_type=0; +static u_char cmd_type; static u_char drvcmd[10]; static u_char infobuf[20]; static u_char xa_head_buf[CD_XA_HEAD]; static u_char xa_tail_buf[CD_XA_TAIL]; #if OLD_BUSY -static volatile u_char busy_data=0; -static volatile u_char busy_audio=0; /* true semaphores would be safer */ +static volatile u_char busy_data; +static volatile u_char busy_audio; /* true semaphores would be safer */ #endif OLD_BUSY static DECLARE_MUTEX(ioctl_read_sem); static u_long timeout; -static volatile u_char timed_out_delay=0; -static volatile u_char timed_out_data=0; +static volatile u_char timed_out_delay; +static volatile u_char timed_out_data; #if 0 -static volatile u_char timed_out_audio=0; +static volatile u_char timed_out_audio; #endif static u_int datarate= 1000000; static u_int maxtim16=16000000; @@ -656,15 +656,15 @@ static int n_retries=6; #endif /*==========================================================================*/ -static int ndrives=0; +static int ndrives; static u_char drv_pattern[NR_SBPCD]={speed_auto,speed_auto,speed_auto,speed_auto}; -static int sbpcd_blocksizes[NR_SBPCD] = {0, }; +static int sbpcd_blocksizes[NR_SBPCD]; /*==========================================================================*/ /* * drive space begins here (needed separate for each unit) */ -static int d=0; /* DriveStruct index: drive number */ +static int d; /* DriveStruct index: drive number */ static struct { char drv_id; /* "jumpered" drive ID or -1 */ @@ -5654,7 +5654,7 @@ static int __init config_spea(void) * Called once at boot or load time. */ -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; #ifdef MODULE int __init __SBPCD_INIT(void) diff --git a/drivers/char/acquirewdt.c b/drivers/char/acquirewdt.c index b685c4b85..272296b69 100644 --- a/drivers/char/acquirewdt.c +++ b/drivers/char/acquirewdt.c @@ -40,7 +40,7 @@ #include <linux/spinlock.h> #include <linux/smp_lock.h> -static int acq_is_open=0; +static int acq_is_open; static spinlock_t acq_lock; /* diff --git a/drivers/char/console.c b/drivers/char/console.c index 67654551c..ea44cace4 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -108,7 +108,7 @@ #include "console_macros.h" -struct consw *conswitchp = NULL; +const struct consw *conswitchp; /* A bitmap for codes <32. A bit of 1 indicates that the code * corresponding to that bit number invokes some special action @@ -136,7 +136,7 @@ static struct termios *console_termios_locked[MAX_NR_CONSOLES]; struct vc vc_cons [MAX_NR_CONSOLES]; #ifndef VT_SINGLE_DRIVER -static struct consw *con_driver_map[MAX_NR_CONSOLES]; +static const struct consw *con_driver_map[MAX_NR_CONSOLES]; #endif static int con_open(struct tty_struct *, struct file *); @@ -152,14 +152,14 @@ static void set_cursor(int currcons); static void hide_cursor(int currcons); static void unblank_screen_t(unsigned long dummy); -static int printable = 0; /* Is console ready for printing? */ +static int printable; /* Is console ready for printing? */ -int do_poke_blanked_console = 0; -int console_blanked = 0; +int do_poke_blanked_console; +int console_blanked; -static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ +static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ static int blankinterval = 10*60*HZ; -static int vesa_off_interval = 0; +static int vesa_off_interval; /* * fg_console is the current virtual console, @@ -167,10 +167,10 @@ static int vesa_off_interval = 0; * want_console is the console we want to switch to, * kmsg_redirect is the console for kernel messages, */ -int fg_console = 0; -int last_console = 0; +int fg_console; +int last_console; int want_console = -1; -int kmsg_redirect = 0; +int kmsg_redirect; /* * For each existing display, we have a pointer to console currently visible @@ -178,7 +178,7 @@ int kmsg_redirect = 0; * appropriately. Unless the low-level driver supplies its own display_fg * variable, we use this one for the "master display". */ -static struct vc_data *master_display_fg = NULL; +static struct vc_data *master_display_fg; /* * Unfortunately, we need to delay tty echo when we're currently writing to the @@ -192,13 +192,13 @@ DECLARE_TASK_QUEUE(con_task_queue); /* * For the same reason, we defer scrollback to the console tasklet. */ -static int scrollback_delta = 0; +static int scrollback_delta; /* * Hook so that the power management routines can (un)blank * the console on our behalf. */ -int (*console_blank_hook)(int) = NULL; +int (*console_blank_hook)(int); static struct timer_list console_timer; @@ -216,7 +216,7 @@ static struct timer_list console_timer; #endif static int pm_con_request(struct pm_dev *dev, pm_request_t rqst, void *data); -static struct pm_dev *pm_con = NULL; +static struct pm_dev *pm_con; static inline unsigned short *screenpos(int currcons, int offset, int viewed) { @@ -415,9 +415,9 @@ void invert_screen(int currcons, int offset, int count, int viewed) /* used by selection: complement pointer position */ void complement_pos(int currcons, int offset) { - static unsigned short *p = NULL; - static unsigned short old = 0; - static unsigned short oldx = 0, oldy = 0; + static unsigned short *p; + static unsigned short old; + static unsigned short oldx, oldy; if (p) { scr_writew(old, p); @@ -2056,7 +2056,7 @@ void vt_console_print(struct console *co, const char * b, unsigned count) { int currcons = fg_console; unsigned char c; - static unsigned long printing = 0; + static unsigned long printing; const ushort *start; ushort cnt = 0; ushort myx; @@ -2147,17 +2147,13 @@ static kdev_t vt_console_device(struct console *c) } struct console vt_console_driver = { - "tty", - vt_console_print, - NULL, - vt_console_device, - keyboard_wait_for_keypress, - unblank_screen, - NULL, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "tty", + write: vt_console_print, + device: vt_console_device, + wait_key: keyboard_wait_for_keypress, + unblank: unblank_screen, + flags: CON_PRINTBUFFER, + index: -1, }; #endif @@ -2484,7 +2480,7 @@ static void clear_buffer_attributes(int currcons) * and become default driver for newly opened ones. */ -void take_over_console(struct consw *csw, int first, int last, int deflt) +void take_over_console(const struct consw *csw, int first, int last, int deflt) { int i, j = -1; const char *desc; @@ -2532,7 +2528,7 @@ void take_over_console(struct consw *csw, int first, int last, int deflt) printk("to %s\n", desc); } -void give_up_console(struct consw *csw) +void give_up_console(const struct consw *csw) { int i; diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index d0e801180..e5bdb6ccf 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -770,7 +770,7 @@ static struct cyclades_card cy_card[NR_CARDS]; */ static struct cyclades_port cy_port[NR_PORTS]; -static int cy_next_channel = 0; /* next minor available */ +static int cy_next_channel; /* next minor available */ static struct tty_struct *serial_table[NR_PORTS]; static struct termios *serial_termios[NR_PORTS]; @@ -862,9 +862,9 @@ static int cy_chip_offset [] = /* PCI related definitions */ -static unsigned short cy_pci_nboard = 0; -static unsigned short cy_isa_nboard = 0; -static unsigned short cy_nboard = 0; +static unsigned short cy_pci_nboard; +static unsigned short cy_isa_nboard; +static unsigned short cy_nboard; #ifdef CONFIG_PCI static unsigned short cy_pci_dev_id[] = { PCI_DEVICE_ID_CYCLOM_Y_Lo, /* PCI < 1Mb */ diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 0ada290ac..535566b63 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -509,7 +509,7 @@ static struct file_operations dsp56k_fops = { /****** Init and module functions ******/ -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; int __init dsp56k_init(void) { diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 867a7fcec..943ceb7eb 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c @@ -392,7 +392,6 @@ static void dtlk_delay(int ms) { current->state = TASK_INTERRUPTIBLE; schedule_timeout((ms * HZ + 1000 - HZ) / 1000); - current->state = TASK_RUNNING; } static int dtlk_readable(void) diff --git a/drivers/char/dz.c b/drivers/char/dz.c index 8302f9df6..da018374d 100644 --- a/drivers/char/dz.c +++ b/drivers/char/dz.c @@ -1553,17 +1553,13 @@ static int __init dz_console_setup(struct console *co, char *options) } static struct console dz_sercons = { - "ttyS", - dz_console_print, - NULL, - dz_console_device, - dz_console_wait_key, - NULL, - dz_console_setup, - CON_CONSDEV | CON_PRINTBUFFER, - CONSOLE_LINE, - 0, - NULL + name: "ttyS", + write: dz_console_print, + device: dz_console_device, + wait_key: dz_console_wait_key, + setup: dz_console_setup, + flags: CON_CONSDEV | CON_PRINTBUFFER, + index: CONSOLE_LINE, }; void __init dz_serial_console_init(void) diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 1e122acba..8991f65bb 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -78,11 +78,11 @@ /* ----------------- Begin global definitions ------------------- */ static char mesg[100]; -static int pc_refcount, nbdevs = 0, num_cards = 0, liloconfig = 0; +static int pc_refcount, nbdevs, num_cards, liloconfig; static int digi_poller_inhibited = 1 ; -static int setup_error_code = 0; -static int invalid_lilo_config = 0; +static int setup_error_code; +static int invalid_lilo_config; /* ----------------------------------------------------------------------- MAXBOARDS is typically 12, but ISA and EISA cards are restricted to diff --git a/drivers/char/esp.c b/drivers/char/esp.c index e3cea9e5d..478b05aa5 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c @@ -70,9 +70,8 @@ #define NR_PRIMARY 8 /* maximum number of primary ports */ /* The following variables can be set by giving module options */ -static int irq[NR_PRIMARY] = {0,0,0,0,0,0,0,0}; /* IRQ for each base port */ -static unsigned int divisor[NR_PRIMARY] = {0,0,0,0,0,0,0,0}; - /* custom divisor for each port */ +static int irq[NR_PRIMARY]; /* IRQ for each base port */ +static unsigned int divisor[NR_PRIMARY]; /* custom divisor for each port */ static unsigned int dma = ESP_DMA_CHANNEL; /* DMA channel */ static unsigned int rx_trigger = ESP_RX_TRIGGER; static unsigned int tx_trigger = ESP_TX_TRIGGER; @@ -168,7 +167,7 @@ static struct termios *serial_termios_locked[NR_PORTS]; * buffer across all the serial ports, since it significantly saves * memory if large numbers of serial ports are open. */ -static unsigned char *tmp_buf = 0; +static unsigned char *tmp_buf; static DECLARE_MUTEX(tmp_buf_sem); static inline int serial_paranoia_check(struct esp_struct *info, diff --git a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c index 12d1e1a6e..ea67cd9f4 100644 --- a/drivers/char/ftape/lowlevel/fdc-io.c +++ b/drivers/char/ftape/lowlevel/fdc-io.c @@ -50,10 +50,10 @@ /* Global vars. */ -int ftape_motor = 0; +int ftape_motor; volatile int ftape_current_cylinder = -1; volatile fdc_mode_enum fdc_mode = fdc_idle; -fdc_config_info fdc = {0}; +fdc_config_info fdc; DECLARE_WAIT_QUEUE_HEAD(ftape_wait_intr); unsigned int ft_fdc_base = CONFIG_FT_FDC_BASE; @@ -73,15 +73,15 @@ volatile __u8 fdc_head; /* FDC head from sector id */ volatile __u8 fdc_cyl; /* FDC track from sector id */ volatile __u8 fdc_sect; /* FDC sector from sector id */ static int fdc_data_rate = 500; /* data rate (Kbps) */ -static int fdc_rate_code = 0; /* data rate code (0 == 500 Kbps) */ +static int fdc_rate_code; /* data rate code (0 == 500 Kbps) */ static int fdc_seek_rate = 2; /* step rate (msec) */ static void (*do_ftape) (void); static int fdc_fifo_state; /* original fifo setting - fifo enabled */ static int fdc_fifo_thr; /* original fifo setting - threshold */ static int fdc_lock_state; /* original lock setting - locked */ -static int fdc_fifo_locked = 0; /* has fifo && lock set ? */ -static __u8 fdc_precomp = 0; /* default precomp. value (nsec) */ -static __u8 fdc_prec_code = 0; /* fdc precomp. select code */ +static int fdc_fifo_locked; /* has fifo && lock set ? */ +static __u8 fdc_precomp; /* default precomp. value (nsec) */ +static __u8 fdc_prec_code; /* fdc precomp. select code */ static char ftape_id[] = "ftape"; /* used by request irq and free irq */ @@ -188,7 +188,7 @@ int fdc_command(const __u8 * cmd_data, int cmd_len) int count = cmd_len; int retry = 0; #ifdef TESTING - static unsigned int last_time = 0; + static unsigned int last_time; unsigned int time; #endif TRACE_FUN(ft_t_any); @@ -387,7 +387,7 @@ int fdc_interrupt_wait(unsigned int time) { DECLARE_WAITQUEUE(wait,current); sigset_t old_sigmask; - static int resetting = 0; + static int resetting; long timeout; TRACE_FUN(ft_t_fdc_dma); @@ -868,7 +868,7 @@ int fdc_recalibrate(void) TRACE_EXIT 0; } -static int perpend_mode = 0; /* set if fdc is in perpendicular mode */ +static int perpend_mode; /* set if fdc is in perpendicular mode */ static int perpend_off(void) { @@ -1113,7 +1113,7 @@ static int fdc_fifo_enable(void) /* Determine fd controller type */ -static __u8 fdc_save_state[2] = {0, 0}; +static __u8 fdc_save_state[2]; int fdc_probe(void) { @@ -1283,7 +1283,7 @@ static int fdc_config_regs(unsigned int fdc_base, static int fdc_config(void) { - static int already_done = 0; + static int already_done; TRACE_FUN(ft_t_any); if (already_done) { diff --git a/drivers/char/ftape/lowlevel/fdc-isr.c b/drivers/char/ftape/lowlevel/fdc-isr.c index 4c3975add..3fdae227e 100644 --- a/drivers/char/ftape/lowlevel/fdc-isr.c +++ b/drivers/char/ftape/lowlevel/fdc-isr.c @@ -44,10 +44,10 @@ /* Global vars. */ -volatile int ft_expected_stray_interrupts = 0; -volatile int ft_interrupt_seen = 0; -volatile int ft_seek_completed = 0; -volatile int ft_hide_interrupt = 0; +volatile int ft_expected_stray_interrupts; +volatile int ft_interrupt_seen; +volatile int ft_seek_completed; +volatile int ft_hide_interrupt; /* Local vars. */ typedef enum { @@ -55,7 +55,7 @@ typedef enum { data_am_error = 0x04, data_crc_error = 0x08, no_data_error = 0x10, overrun_error = 0x20, } error_cause; -static int stop_read_ahead = 0; +static int stop_read_ahead; static void print_error_cause(int cause) @@ -730,7 +730,7 @@ static void continue_formatting(buffer_struct *buff) */ static void handle_fdc_busy(buffer_struct *buff) { - static int no_data_error_count = 0; + static int no_data_error_count; int retry = 0; error_cause cause; __u8 in[7]; @@ -1077,7 +1077,7 @@ static void handle_fdc_busy(buffer_struct *buff) */ void fdc_isr(void) { - static int isr_active = 0; + static int isr_active; #ifdef TESTING unsigned int t0 = ftape_timestamp(); #endif diff --git a/drivers/char/ftape/lowlevel/ftape-bsm.c b/drivers/char/ftape/lowlevel/ftape-bsm.c index 2fcc85e50..ad157a1c7 100644 --- a/drivers/char/ftape/lowlevel/ftape-bsm.c +++ b/drivers/char/ftape/lowlevel/ftape-bsm.c @@ -39,8 +39,8 @@ /* Local vars. */ -static __u8 *bad_sector_map = NULL; -static SectorCount *bsm_hash_ptr = NULL; +static __u8 *bad_sector_map; +static SectorCount *bsm_hash_ptr; typedef enum { forward, backward @@ -454,7 +454,7 @@ SectorMap ftape_get_bad_sector_entry(int segment_id) * For true random access it may have to be redesigned. */ static int last_reference = -1; - static SectorMap map = 0; + static SectorMap map; if (segment_id > last_reference) { /* Skip all sectors before segment_id diff --git a/drivers/char/ftape/lowlevel/ftape-format.c b/drivers/char/ftape/lowlevel/ftape-format.c index 015911918..41f43dffb 100644 --- a/drivers/char/ftape/lowlevel/ftape-format.c +++ b/drivers/char/ftape/lowlevel/ftape-format.c @@ -47,7 +47,7 @@ /* * first segment of the new buffer */ -static int switch_segment = 0; +static int switch_segment; /* * at most 256 segments fit into one 32 kb buffer. Even TR-1 cartridges have diff --git a/drivers/char/ftape/lowlevel/ftape-io.c b/drivers/char/ftape/lowlevel/ftape-io.c index 464b792d3..c13b8e3c8 100644 --- a/drivers/char/ftape/lowlevel/ftape-io.c +++ b/drivers/char/ftape/lowlevel/ftape-io.c @@ -50,14 +50,14 @@ */ /* NOTE: sectors start numbering at 1, all others at 0 ! */ ft_timeout_table ftape_timeout; -unsigned int ftape_tape_len = 0; +unsigned int ftape_tape_len; volatile qic117_cmd_t ftape_current_command; const struct qic117_command_table qic117_cmds[] = QIC117_COMMANDS; int ftape_might_be_off_track; /* Local vars. */ -static int diagnostic_mode = 0; +static int diagnostic_mode; static unsigned int ftape_udelay_count; static unsigned int ftape_udelay_time; @@ -232,7 +232,7 @@ static int ft_check_cmd_restrictions(qic117_cmd_t command) int ftape_command(qic117_cmd_t command) { int result = 0; - static int level = 0; + static int level; TRACE_FUN(ft_t_any); if ((unsigned int)command > NR_ITEMS(qic117_cmds)) { @@ -778,7 +778,7 @@ int ftape_set_data_rate(unsigned int new_rate /* Kbps */, unsigned int qic_std) int status; int result = 0; unsigned int data_rate = new_rate; - static int supported = 0; + static int supported; int rate_changed = 0; qic_model dummy_model; unsigned int dummy_qic_std, dummy_tape_len; diff --git a/drivers/char/ftape/lowlevel/ftape-rw.c b/drivers/char/ftape/lowlevel/ftape-rw.c index 2c14f468e..e6ac3b625 100644 --- a/drivers/char/ftape/lowlevel/ftape-rw.c +++ b/drivers/char/ftape/lowlevel/ftape-rw.c @@ -43,18 +43,18 @@ /* Global vars. */ -int ft_nr_buffers = 0; -buffer_struct *ft_buffer[FT_MAX_NR_BUFFERS] = {NULL, }; +int ft_nr_buffers; +buffer_struct *ft_buffer[FT_MAX_NR_BUFFERS]; static volatile int ft_head; static volatile int ft_tail; /* not volatile but need same type as head */ int fdc_setup_error; location_record ft_location = {-1, 0}; -volatile int ftape_tape_running = 0; +volatile int ftape_tape_running; /* Local vars. */ -static int overrun_count_offset = 0; -static int inhibit_correction = 0; +static int overrun_count_offset; +static int inhibit_correction; /* maxmimal allowed overshoot when fast seeking */ diff --git a/drivers/char/ftape/lowlevel/ftape-tracing.c b/drivers/char/ftape/lowlevel/ftape-tracing.c index 95e3df8e8..7fdc65674 100644 --- a/drivers/char/ftape/lowlevel/ftape-tracing.c +++ b/drivers/char/ftape/lowlevel/ftape-tracing.c @@ -43,11 +43,11 @@ * 8 + everything else */ ft_trace_t ftape_tracing = ft_t_info; /* Default level: information and up */ -int ftape_function_nest_level = 0; +int ftape_function_nest_level; /* Local vars. */ -static __u8 trace_id = 0; +static __u8 trace_id; static char spacing[] = "* "; void ftape_trace_call(const char *file, const char *name) diff --git a/drivers/char/ftape/lowlevel/ftape-write.c b/drivers/char/ftape/lowlevel/ftape-write.c index a0f095b9a..c4cb18779 100644 --- a/drivers/char/ftape/lowlevel/ftape-write.c +++ b/drivers/char/ftape/lowlevel/ftape-write.c @@ -47,7 +47,7 @@ /* Local vars. */ -static int last_write_failed = 0; +static int last_write_failed; void ftape_zap_write_buffers(void) { diff --git a/drivers/char/ftape/zftape/zftape-buffers.c b/drivers/char/ftape/zftape/zftape-buffers.c index bafc7e1a9..f3dace343 100644 --- a/drivers/char/ftape/zftape/zftape-buffers.c +++ b/drivers/char/ftape/zftape/zftape-buffers.c @@ -48,8 +48,8 @@ /* local varibales */ -static unsigned int used_memory = 0; -static unsigned int peak_memory = 0; +static unsigned int used_memory; +static unsigned int peak_memory; void zft_memory_stats(void) { diff --git a/drivers/char/ftape/zftape/zftape-ctl.c b/drivers/char/ftape/zftape/zftape-ctl.c index da2010ceb..6441ca929 100644 --- a/drivers/char/ftape/zftape/zftape-ctl.c +++ b/drivers/char/ftape/zftape/zftape-ctl.c @@ -49,16 +49,16 @@ /* Global vars. */ -int zft_write_protected = 0; /* this is when cartridge rdonly or O_RDONLY */ -int zft_header_read = 0; -int zft_offline = 0; -unsigned int zft_unit = 0; -int zft_resid = 0; -int zft_mt_compression = 0; +int zft_write_protected; /* this is when cartridge rdonly or O_RDONLY */ +int zft_header_read; +int zft_offline; +unsigned int zft_unit; +int zft_resid; +int zft_mt_compression; /* Local vars. */ -static int going_offline = 0; +static int going_offline; typedef int (mt_fun)(int *argptr); typedef int (*mt_funp)(int *argptr); diff --git a/drivers/char/ftape/zftape/zftape-read.c b/drivers/char/ftape/zftape/zftape-read.c index 91ed51423..756ee3239 100644 --- a/drivers/char/ftape/zftape/zftape-read.c +++ b/drivers/char/ftape/zftape/zftape-read.c @@ -45,11 +45,11 @@ /* Global vars. */ -int zft_just_before_eof = 0; +int zft_just_before_eof; /* Local vars. */ -static int buf_len_rd = 0; +static int buf_len_rd; void zft_zap_read_buffers(void) { @@ -194,7 +194,7 @@ static int check_read_access(int *req_len, int *req_clipped, const zft_position *pos) { - static __s64 remaining = 0; + static __s64 remaining; static int eod; TRACE_FUN(ft_t_flow); diff --git a/drivers/char/ftape/zftape/zftape-rw.c b/drivers/char/ftape/zftape/zftape-rw.c index 784068096..9e599530c 100644 --- a/drivers/char/ftape/zftape/zftape-rw.c +++ b/drivers/char/ftape/zftape/zftape-rw.c @@ -41,14 +41,14 @@ /* Global vars. */ -__u8 *zft_deblock_buf = NULL; -__u8 *zft_hseg_buf = NULL; +__u8 *zft_deblock_buf; +__u8 *zft_hseg_buf; int zft_deblock_segment = -1; zft_status_enum zft_io_state = zft_idle; -int zft_header_changed = 0; -int zft_bad_sector_map_changed = 0; -int zft_qic113 = 0; /* conform to old specs. and old zftape */ -int zft_use_compression = 0; +int zft_header_changed; +int zft_bad_sector_map_changed; +int zft_qic113; /* conform to old specs. and old zftape */ +int zft_use_compression; zft_position zft_pos = { -1, /* seg_pos */ 0, /* seg_byte_pos */ @@ -56,10 +56,10 @@ zft_position zft_pos = { 0 /* volume_pos */ }; unsigned int zft_blk_sz = CONFIG_ZFT_DFLT_BLK_SZ; -__s64 zft_capacity = 0; +__s64 zft_capacity; -unsigned int zft_written_segments = 0; -int zft_label_changed = 0; +unsigned int zft_written_segments; +int zft_label_changed; /* Local vars. */ @@ -165,8 +165,8 @@ int zft_calc_seg_byte_coord(int *seg_byte_pos, __s64 tape_pos) * Also, it might be in the future that the bad sector map gets * changed. -> reset the cache */ -static int seg_pos = 0; -static __s64 tape_pos = 0; +static int seg_pos; +static __s64 tape_pos; __s64 zft_get_capacity(void) { diff --git a/drivers/char/ftape/zftape/zftape-vtbl.c b/drivers/char/ftape/zftape/zftape-vtbl.c index cf0ef2325..e4804ea2e 100644 --- a/drivers/char/ftape/zftape/zftape-vtbl.c +++ b/drivers/char/ftape/zftape/zftape-vtbl.c @@ -48,8 +48,8 @@ * global variables */ int zft_qic_mode = 1; /* use the vtbl */ -int zft_old_ftape = 0; /* prevents old ftaped tapes to be overwritten */ -int zft_volume_table_changed = 0; /* for write_header_segments() */ +int zft_old_ftape; /* prevents old ftaped tapes to be overwritten */ +int zft_volume_table_changed; /* for write_header_segments() */ /* * private variables (only exported for inline functions) @@ -59,9 +59,9 @@ LIST_HEAD(zft_vtbl); /* We could also allocate these dynamically when extracting the volume table * sizeof(zft_volinfo) is about 32 or something close to that */ -static zft_volinfo tape_vtbl = { {NULL, NULL}, 0, }; -static zft_volinfo eot_vtbl = { {NULL, NULL}, 0, }; -static zft_volinfo *cur_vtbl = NULL; +static zft_volinfo tape_vtbl; +static zft_volinfo eot_vtbl; +static zft_volinfo *cur_vtbl; inline void zft_new_vtbl_entry(void) { diff --git a/drivers/char/ftape/zftape/zftape-write.c b/drivers/char/ftape/zftape/zftape-write.c index 03b126f49..8608c4dcc 100644 --- a/drivers/char/ftape/zftape/zftape-write.c +++ b/drivers/char/ftape/zftape/zftape-write.c @@ -48,8 +48,8 @@ /* Local vars. */ -static int last_write_failed = 0; -static int need_flush = 0; +static int last_write_failed; +static int need_flush; void zft_prevent_flush(void) { diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 6ceb5a152..78617055e 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c @@ -33,7 +33,7 @@ static char * tmp_buf; static DECLARE_MUTEX(tmp_buf_sem); -int gs_debug = 0; +int gs_debug; #ifdef DEBUG diff --git a/drivers/char/i810_rng.c b/drivers/char/i810_rng.c index 18e198f51..422054ece 100644 --- a/drivers/char/i810_rng.c +++ b/drivers/char/i810_rng.c @@ -2,6 +2,7 @@ Hardware driver for Intel i810 Random Number Generator (RNG) Copyright 2000 Jeff Garzik <jgarzik@mandrakesoft.com> + Copyright 2000 Philipp Rumpf <prumpf@tux.org> Driver Web site: http://gtf.org/garzik/drivers/i810_rng/ @@ -131,6 +132,9 @@ This will slow things down but guarantee that bad data is never passed upstream. + * FIXME: module unload is racy. To fix this, struct ctl_table + needs an owner member a la struct file_operations. + * Since the RNG is accessed from a timer as well as normal kernel code, but not from interrupts, we use spin_lock_bh in regular code, and spin_lock in the timer function, to @@ -164,6 +168,17 @@ * Convert numeric globals to unsigned * Module unload cleanup + Version 0.9.1: + * Support i815 chipsets too (Matt Sottek) + * Fix reference counting when statically compiled (prumpf) + * Rewrite rng_dev_read (prumpf) + * Make module races less likely (prumpf) + * Small miscellaneous bug fixes (prumpf) + * Use pci table for PCI id list + + Version 0.9.2: + * Simplify open blocking logic + */ @@ -187,7 +202,7 @@ /* * core module and version information */ -#define RNG_VERSION "0.9.0" +#define RNG_VERSION "0.9.2" #define RNG_MODULE_NAME "i810_rng" #define RNG_DRIVER_NAME RNG_MODULE_NAME " hardware driver " RNG_VERSION #define PFX RNG_MODULE_NAME ": " @@ -218,11 +233,6 @@ /* - * misc helper macros - */ -#define arraysize(x) (sizeof(x)/sizeof(*(x))) - -/* * prototypes */ static void rng_fips_test_store (int rng_data); @@ -281,8 +291,6 @@ static spinlock_t rng_lock = SPIN_LOCK_UNLOCKED; /* hardware lock */ static struct timer_list rng_timer; /* kernel timer for RNG hardware reads and tests */ static struct pci_dev *rng_pdev; /* Firmware Hub PCI device found during PCI probe */ static struct semaphore rng_open_sem; /* Semaphore for serializing rng_open/release */ -static wait_queue_head_t rng_open_wait; /* Wait queue for serializing open/release */ -static int rng_open_mode; /* Open mode (we only allow reads) */ /* @@ -363,7 +371,7 @@ static void rng_timer_tick (unsigned long data) /* - * rng_enable - enable or disable the RNG and internal timer + * rng_enable - enable or disable the RNG hardware */ static int rng_enable (int enable) { @@ -377,15 +385,13 @@ static int rng_enable (int enable) hw_status = rng_hwstatus (); if (enable) { - rng_hw_enabled = 1; + rng_hw_enabled++; MOD_INC_USE_COUNT; } else { -#ifndef __alpha__ - if (GET_USE_COUNT (THIS_MODULE) > 0) + if (rng_hw_enabled) { + rng_hw_enabled--; MOD_DEC_USE_COUNT; - if (GET_USE_COUNT (THIS_MODULE) == 0) - rng_hw_enabled = 0; -#endif + } } if (rng_hw_enabled && ((hw_status & RNG_ENABLED) == 0)) { @@ -407,7 +413,8 @@ static int rng_enable (int enable) else if (action == 2) printk (KERN_INFO PFX "RNG h/w disabled\n"); - if ((!!enable) != (!!(new_status & RNG_ENABLED))) { + /* too bad C doesn't have ^^ */ + if ((!enable) != (!(new_status & RNG_ENABLED))) { printk (KERN_ERR PFX "Unable to %sable the RNG\n", enable ? "en" : "dis"); rc = -EIO; @@ -429,6 +436,7 @@ static int rng_handle_sysctl_enable (ctl_table * table, int write, struct file * DPRINTK ("ENTER\n"); + MOD_INC_USE_COUNT; spin_lock_bh (&rng_lock); rng_enabled_sysctl = enabled_save = rng_timer_enabled; spin_unlock_bh (&rng_lock); @@ -456,6 +464,9 @@ static int rng_handle_sysctl_enable (ctl_table * table, int write, struct file * spin_unlock_bh (&rng_lock); } + /* This needs to be in a higher layer */ + MOD_DEC_USE_COUNT; + DPRINTK ("EXIT, returning 0\n"); return 0; } @@ -614,22 +625,17 @@ static int rng_dev_open (struct inode *inode, struct file *filp) int rc = -EINVAL; if ((filp->f_mode & FMODE_READ) == 0) - goto err_out_ret; + return rc; if (filp->f_mode & FMODE_WRITE) - goto err_out_ret; + return rc; /* wait for device to become free */ - down (&rng_open_sem); - while (rng_open_mode & filp->f_mode) { - if (filp->f_flags & O_NONBLOCK) { - up (&rng_open_sem); - return -EWOULDBLOCK; - } - up (&rng_open_sem); - interruptible_sleep_on (&rng_open_wait); - if (signal_pending (current)) + if (filp->f_flags & O_NONBLOCK) { + if (down_trylock (&rng_open_sem)) + return -EAGAIN; + } else { + if (down_interruptible (&rng_open_sem)) return -ERESTARTSYS; - down (&rng_open_sem); } if (rng_enable (1)) { @@ -637,87 +643,60 @@ static int rng_dev_open (struct inode *inode, struct file *filp) goto err_out; } - rng_open_mode |= filp->f_mode & (FMODE_READ | FMODE_WRITE); - up (&rng_open_sem); return 0; err_out: up (&rng_open_sem); -err_out_ret: return rc; } static int rng_dev_release (struct inode *inode, struct file *filp) { - down(&rng_open_sem); - rng_enable(0); - rng_open_mode &= (~filp->f_mode) & (FMODE_READ|FMODE_WRITE); - up (&rng_open_sem); - wake_up (&rng_open_wait); return 0; } -static ssize_t rng_dev_read (struct file *filp, char * buf, size_t size, - loff_t *offp) +static ssize_t rng_dev_read (struct file *filp, char *buf, size_t size, + loff_t * offp) { - int have_data, copied = 0; - u8 data=0; - u8 *page; - - if (size < 1) - return 0; - - page = (unsigned char *) get_free_page (GFP_KERNEL); - if (!page) - return -ENOMEM; - -read_loop: - /* using the fact that read() can return >0 but - * less than the requested amount, we simply - * read up to PAGE_SIZE or buffer size, whichever - * is smaller, and return that data. - */ - if ((copied == size) || (copied == PAGE_SIZE)) { - size_t tmpsize = (copied == size) ? size : PAGE_SIZE; - int rc = copy_to_user (buf, page, tmpsize); - free_page ((long)page); - if (rc) return rc; - return tmpsize; - } + int have_data; + u8 data = 0; + ssize_t ret = 0; - spin_lock_bh (&rng_lock); + while (size) { + spin_lock_bh (&rng_lock); - have_data = 0; - if (rng_data_present ()) { - data = rng_data_read (); - have_data = 1; - } + have_data = 0; + if (rng_data_present ()) { + data = rng_data_read (); + have_data = 1; + } - spin_unlock_bh (&rng_lock); + spin_unlock_bh (&rng_lock); - if (have_data) { - page[copied] = data; - copied++; - } else { - if (filp->f_flags & O_NONBLOCK) { - free_page ((long)page); - return -EAGAIN; + if (have_data) { + if (put_user (data, buf++)) { + ret = ret ? : -EFAULT; + break; + } + size--; + ret++; } - } - if (current->need_resched) - schedule (); + if (current->need_resched) + schedule (); + + if (signal_pending (current)) + return ret ? : -ERESTARTSYS; - if (signal_pending (current)) { - free_page ((long)page); - return -ERESTARTSYS; + if (filp->f_flags & O_NONBLOCK) + return ret ? : -EAGAIN; } - goto read_loop; + return ret; } @@ -793,8 +772,9 @@ err_out_free_res: * want to register another driver on the same PCI id. */ const static struct pci_device_id rng_pci_tbl[] __initdata = { - { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, }, - { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, }, + { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, }, + { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, }, + { 0x8086, 0x1130, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, }; MODULE_DEVICE_TABLE (pci, rng_pci_tbl); @@ -832,14 +812,16 @@ static int __init rng_init (void) DPRINTK ("ENTER\n"); init_MUTEX (&rng_open_sem); - init_waitqueue_head (&rng_open_wait); - pdev = pci_find_device (0x8086, 0x2418, NULL); - if (!pdev) - pdev = pci_find_device (0x8086, 0x2428, NULL); - if (!pdev) - return -ENODEV; + pci_for_each_dev(pdev) { + if (pci_match_device (rng_pci_tbl, pdev) != NULL) + goto match; + } + + DPRINTK ("EXIT, returning -ENODEV\n"); + return -ENODEV; +match: rc = rng_init_one (pdev); if (rc) return rc; @@ -894,7 +876,7 @@ module_exit (rng_cleanup); * 4.11.1 (http://csrc.nist.gov/fips/fips1401.htm) * The Monobit, Poker, Runs, and Long Runs tests are implemented below. * This test is run at periodic intervals to verify -* data is sufficently random. If the tests are failed the RNG module +* data is sufficiently random. If the tests are failed the RNG module * will no longer submit data to the entropy pool, but the tests will * continue to run at the given interval. If at a later time the RNG * passes all tests it will be re-enabled for the next period. @@ -905,7 +887,7 @@ module_exit (rng_cleanup); * disable the RNG, we will just leave it disabled for the period of * time until the tests are rerun and passed. * -* For argument sake I tested /proc/urandom with these tests and it +* For argument sake I tested /dev/urandom with these tests and it * took 142,095 tries before I got a failure, and urandom isn't as * random as random :) */ @@ -923,7 +905,7 @@ static void rng_fips_test_store (int rng_data) int j; static int last_bit = 0; - DPRINTK ("ENTER, rng_data = %d\n", rng_data & 0xFF); + DPRINTK ("ENTER, rng_data = %d\n", rng_data); poker[rng_data >> 4]++; poker[rng_data & 15]++; @@ -1010,8 +992,8 @@ static void rng_run_fips_test (void) rng_trusted = rng_test; /* finally, clear out FIPS variables for start of next run */ - memset (&poker, 0, sizeof (poker)); - memset (&runs, 0, sizeof (runs)); + memset (poker, 0, sizeof (poker)); + memset (runs, 0, sizeof (runs)); ones = 0; rlength = -1; current_bit = 0; @@ -1019,4 +1001,3 @@ static void rng_run_fips_test (void) DPRINTK ("EXIT\n"); } - diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c index 95af0a0f1..896396bad 100644 --- a/drivers/char/ip2/i2ellis.c +++ b/drivers/char/ip2/i2ellis.c @@ -51,9 +51,9 @@ static void ii2Nop(void); //* Static Data * //*************** -static int ii2Safe = 0; // Safe I/O address for delay routine +static int ii2Safe; // Safe I/O address for delay routine -static int iiDelayed = 0; // Set when the iiResetDelay function is +static int iiDelayed; // Set when the iiResetDelay function is // called. Cleared when ANY board is reset. static struct timer_list * pDelayTimer; // Used by iiDelayTimer static wait_queue_head_t pDelayWait; // Used by iiDelayTimer diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index 6fbfe22df..a5e3adca6 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c @@ -295,13 +295,13 @@ static int ref_count; /* Here, then is a table of board pointers which the interrupt routine should * scan through to determine who it must service. */ -static unsigned short i2nBoards = 0; // Number of boards here +static unsigned short i2nBoards; // Number of boards here static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS]; static i2ChanStrPtr DevTable[IP2_MAX_PORTS]; //DevTableMem just used to save addresses for kfree -static void *DevTableMem[IP2_MAX_BOARDS] = {NULL,NULL,NULL,NULL}; +static void *DevTableMem[IP2_MAX_BOARDS]; static struct tty_struct * TtyTable[IP2_MAX_PORTS]; static struct termios * Termios[IP2_MAX_PORTS]; @@ -318,8 +318,8 @@ static struct file_operations ip2_ipl = { open: ip2_ipl_open, }; -static long irq_counter = 0; -static long bh_counter = 0; +static long irq_counter; +static long bh_counter; // Use immediate queue to service interrupts //#define USE_IQI // PCI&2.2 needs work @@ -330,15 +330,15 @@ static long bh_counter = 0; */ #define POLL_TIMEOUT (jiffies + 1) static struct timer_list PollTimer = { function: ip2_poll }; -static char TimerOn = 0; +static char TimerOn; #ifdef IP2DEBUG_TRACE /* Trace (debug) buffer data */ #define TRACEMAX 1000 static unsigned long tracebuf[TRACEMAX]; -static int tracestuff = 0; -static int tracestrip = 0; -static int tracewrap = 0; +static int tracestuff; +static int tracestrip; +static int tracewrap; #endif /**********/ @@ -372,13 +372,13 @@ static int tracewrap = 0; # endif /* LINUX_VERSION */ #endif /* MODULE */ -static int poll_only = 0; +static int poll_only; -static int Eisa_irq = 0; -static int Eisa_slot = 0; +static int Eisa_irq; +static int Eisa_slot; -static int iindx = 0; -static char rirqs[IP2_MAX_BOARDS] = {0,}; +static int iindx; +static char rirqs[IP2_MAX_BOARDS]; static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; /******************************************************************************/ @@ -584,13 +584,13 @@ int __init old_ip2_init(void) { #ifdef CONFIG_DEVFS_FS - static devfs_handle_t devfs_handle = NULL; + static devfs_handle_t devfs_handle; int j, box; #endif int i; int err; int status = 0; - static int loaded = 0; + static int loaded; i2eBordStrPtr pB = NULL; int rc = -1; diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 71dd53691..0bcc63a43 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -142,7 +142,7 @@ static int stli_nrbrds = sizeof(stli_brdconf) / sizeof(stlconf_t); */ #define STLI_EISAPROBE 0 -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; /*****************************************************************************/ @@ -189,7 +189,7 @@ static int stli_refcount; * swapping!). All ports will share one buffer - since if the system * is already swapping a shared buffer won't make things any worse. */ -static char *stli_tmpwritebuf = (char *) NULL; +static char *stli_tmpwritebuf; static DECLARE_MUTEX(stli_tmpwritesem); #define STLI_TXBUFSIZE 4096 @@ -201,10 +201,10 @@ static DECLARE_MUTEX(stli_tmpwritesem); * with a large memcpy. Just use 1 buffer for all ports, since its * use it is only need for short periods of time by each port. */ -static char *stli_txcookbuf = (char *) NULL; -static int stli_txcooksize = 0; -static int stli_txcookrealsize = 0; -static struct tty_struct *stli_txcooktty = (struct tty_struct *) NULL; +static char *stli_txcookbuf; +static int stli_txcooksize; +static int stli_txcookrealsize; +static struct tty_struct *stli_txcooktty; /* * Define a local default termios struct. All ports will be created @@ -234,7 +234,7 @@ static stliport_t stli_dummyport; static stlibrd_t *stli_brds[STL_MAXBRDS]; -static int stli_shared = 0; +static int stli_shared; /* * Per board state flags. Used with the state field of the board struct. @@ -796,7 +796,7 @@ static struct timer_list stli_timerlist = { function: stli_poll }; -static int stli_timeron = 0; +static int stli_timeron; /* * Define the calculation for the timeout routine. diff --git a/drivers/char/joystick/gameport.c b/drivers/char/joystick/gameport.c index 5a5e1219b..15ef908a6 100644 --- a/drivers/char/joystick/gameport.c +++ b/drivers/char/joystick/gameport.c @@ -51,9 +51,9 @@ EXPORT_SYMBOL(gameport_close); EXPORT_SYMBOL(gameport_rescan); EXPORT_SYMBOL(gameport_cooked_read); -static struct gameport *gameport_list = NULL; -static struct gameport_dev *gameport_dev = NULL; -static int gameport_number = 0; +static struct gameport *gameport_list; +static struct gameport_dev *gameport_dev; +static int gameport_number; /* * gameport_measure_speed() measures the gameport i/o speed. diff --git a/drivers/char/joystick/ns558.c b/drivers/char/joystick/ns558.c index 9ea833113..573eac51b 100644 --- a/drivers/char/joystick/ns558.c +++ b/drivers/char/joystick/ns558.c @@ -57,7 +57,8 @@ struct ns558 { struct gameport gameport; }; -static struct ns558 *ns558 = NULL; +static struct ns558 *ns558; +static int have_pci_devices; /* * ns558_isa_probe() tries to find an isa gameport at the @@ -311,6 +312,15 @@ int __init ns558_init(void) #endif /* + * Probe for PCI ports. Always probe for PCI first, + * it is the least-invasive probe. + */ + + i = pci_module_init(&ns558_pci_driver); + if (i == 0) + have_pci_devices = 1; + +/* * Probe for ISA ports. */ @@ -329,14 +339,7 @@ int __init ns558_init(void) } #endif -/* - * Probe for PCI ports. - */ - - if (!ns558 && pci_module_init(&ns558_pci_driver)) - return -ENODEV; - - return 0; + return ns558 ? 0 : -ENODEV; } void __exit ns558_exit(void) @@ -365,7 +368,8 @@ void __exit ns558_exit(void) port = port->next; } - pci_unregister_driver(&ns558_pci_driver); + if (have_pci_devices) + pci_unregister_driver(&ns558_pci_driver); } module_init(ns558_init); diff --git a/drivers/char/joystick/serio.c b/drivers/char/joystick/serio.c index 9595f0a6c..7dc5cd5a1 100644 --- a/drivers/char/joystick/serio.c +++ b/drivers/char/joystick/serio.c @@ -44,9 +44,9 @@ EXPORT_SYMBOL(serio_open); EXPORT_SYMBOL(serio_close); EXPORT_SYMBOL(serio_rescan); -static struct serio *serio_list = NULL; -static struct serio_dev *serio_dev = NULL; -static int serio_number = 0; +static struct serio *serio_list; +static struct serio_dev *serio_dev; +static int serio_number; static void serio_find_dev(struct serio *serio) { diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index f889378a3..a2f157c56 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -61,7 +61,7 @@ #define KBD_DEFLOCK 0 #endif -void (*kbd_ledfunc)(unsigned int led) = NULL; +void (*kbd_ledfunc)(unsigned int led); EXPORT_SYMBOL(handle_scancode); EXPORT_SYMBOL(kbd_ledfunc); @@ -83,24 +83,24 @@ int keyboard_wait_for_keypress(struct console *co) */ /* shift state counters.. */ -static unsigned char k_down[NR_SHIFT] = {0, }; +static unsigned char k_down[NR_SHIFT]; /* keyboard key bitmap */ -static unsigned long key_down[256/BITS_PER_LONG] = { 0, }; +static unsigned long key_down[256/BITS_PER_LONG]; -static int dead_key_next = 0; +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 * return the value. I chose the former way. */ -int shift_state = 0; +int shift_state; static int npadch = -1; /* -1 or number assembled on pad */ -static unsigned char diacr = 0; -static char rep = 0; /* flag telling character repeat */ +static unsigned char diacr; +static char rep; /* flag telling character repeat */ struct kbd_struct kbd_table[MAX_NR_CONSOLES]; static struct tty_struct **ttytab; static struct kbd_struct * kbd = kbd_table; -static struct tty_struct * tty = NULL; +static struct tty_struct * tty; void compute_shiftstate(void); @@ -160,7 +160,7 @@ struct pt_regs * kbd_pt_regs; static int sysrq_pressed; #endif -static struct pm_dev *pm_kbd = NULL; +static struct pm_dev *pm_kbd; /* * Many other routines do put_queue, but I think either diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 2e9e170c4..97f99de1c 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -603,17 +603,10 @@ static kdev_t lp_console_device (struct console *c) } static struct console lpcons = { - "lp", - lp_console_write, - NULL, - lp_console_device, - NULL, - NULL, - NULL, - CON_PRINTBUFFER, - 0, - 0, - NULL + name: "lp", + write: lp_console_write, + device: lp_console_device, + flags: CON_PRINTBUFFER, }; #endif /* console on line printer */ diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 71e03fed5..1b49e6e1b 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -28,9 +28,6 @@ #ifdef CONFIG_I2C extern int i2c_init_all(void); #endif -#ifdef CONFIG_SPARCAUDIO -extern int sparcaudio_init(void); -#endif #ifdef CONFIG_ISDN int isdn_init(void); #endif diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 95dbdaab2..5a869954b 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -174,7 +174,7 @@ static struct file_operations misc_fops = { int misc_register(struct miscdevice * misc) { - static devfs_handle_t devfs_handle = NULL; + static devfs_handle_t devfs_handle; if (misc->next || misc->prev) return -EBUSY; diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index fbbec0fb1..1681ac603 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -170,10 +170,10 @@ static mxser_pciinfo mxser_pcibrds[] = {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C104, MXSER_BOARD_C104_PCI}, }; -static int ioaddr[MXSER_BOARDS] = {0, 0, 0, 0}; +static int ioaddr[MXSER_BOARDS]; static int ttymajor = MXSERMAJOR; static int calloutmajor = MXSERCUMAJOR; -static int verbose = 0; +static int verbose; /* Variables for insmod */ @@ -274,7 +274,7 @@ static int mxvar_diagflag; * buffer across all the serial ports, since it significantly saves * memory if large numbers of serial ports are open. */ -static unsigned char *mxvar_tmp_buf = 0; +static unsigned char *mxvar_tmp_buf; static struct semaphore mxvar_tmp_buf_sem; /* diff --git a/drivers/char/pc110pad.c b/drivers/char/pc110pad.c index 556d8630e..862994025 100644 --- a/drivers/char/pc110pad.c +++ b/drivers/char/pc110pad.c @@ -68,7 +68,7 @@ static struct pc110pad_params current_params; /* driver/filesystem interface management */ static wait_queue_head_t queue; static struct fasync_struct *asyncptr; -static int active=0; /* number of concurrent open()s */ +static int active; /* number of concurrent open()s */ static struct semaphore reader_lock; /** @@ -111,10 +111,10 @@ static void wake_readers(void) * up/down mouse events to be created by incrementing synthesize_tap. */ -static int button_pending=0; -static int recent_transition=0; -static int transition_count=0; -static int synthesize_tap=0; +static int button_pending; +static int recent_transition; +static int transition_count; +static int synthesize_tap; static void tap_timeout(unsigned long data); static struct timer_list tap_timer = { function: tap_timeout }; @@ -218,13 +218,13 @@ static void read_button(int *b) */ static int raw_data[3]; -static int raw_data_count=0; -static int raw_x=0, raw_y=0; /* most recent absolute co-ords read */ -static int raw_down=0; /* raw up/down state */ -static int debounced_down=0; /* up/down state after debounce processing */ +static int raw_data_count; +static int raw_x, raw_y; /* most recent absolute co-ords read */ +static int raw_down; /* raw up/down state */ +static int debounced_down; /* up/down state after debounce processing */ static enum { NO_BOUNCE, JUST_GONE_UP, JUST_GONE_DOWN } bounce=NO_BOUNCE; /* set just after an up/down transition */ -static int xy_pending=0; /* set if new data have not yet been read */ +static int xy_pending; /* set if new data have not yet been read */ /* * Timer goes off a short while after an up/down transition and copies @@ -425,7 +425,7 @@ static void read_raw_pad(int *down, int *debounced, int *x, int *y) * will make much sense in that case. */ static int read_bytes[3]; -static int read_byte_count=0; +static int read_byte_count; /** * sample_raw: diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c index d9276b753..4a7758325 100644 --- a/drivers/char/pc_keyb.c +++ b/drivers/char/pc_keyb.c @@ -65,13 +65,13 @@ static void aux_write_ack(int val); static void __aux_write_ack(int val); #endif -spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; static unsigned char handle_kbd_event(void); /* used only by send_data - set by keyboard_interrupt */ -static volatile unsigned char reply_expected = 0; -static volatile unsigned char acknowledge = 0; -static volatile unsigned char resend = 0; +static volatile unsigned char reply_expected; +static volatile unsigned char acknowledge; +static volatile unsigned char resend; #if defined CONFIG_PSMOUSE @@ -84,9 +84,9 @@ static int __init psaux_init(void); #define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */ static struct aux_queue *queue; /* Mouse data buffer. */ -static int aux_count = 0; +static int aux_count; /* used when we send commands to the mouse that expect an ACK. */ -static unsigned char mouse_reply_expected = 0; +static unsigned char mouse_reply_expected; #define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT) #define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT) @@ -291,7 +291,7 @@ static int do_acknowledge(unsigned char scancode) int pckbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode) { - static int prev_scancode = 0; + static int prev_scancode; /* special prefix scancodes.. */ if (scancode == 0xe0 || scancode == 0xe1) { @@ -448,7 +448,7 @@ static unsigned char handle_kbd_event(void) unsigned char status = kbd_read_status(); unsigned int work = 10000; - while (status & KBD_STAT_OBF) { + while ((--work > 0) && (status & KBD_STAT_OBF)) { unsigned char scancode; scancode = kbd_read_input(); @@ -467,13 +467,10 @@ static unsigned char handle_kbd_event(void) } status = kbd_read_status(); - - if (!--work) { - printk(KERN_ERR "pc_keyb: controller jammed (0x%02X).\n", - status); - break; - } } + + if (!work) + printk(KERN_ERR "pc_keyb: controller jammed (0x%02X).\n", status); return status; } @@ -481,14 +478,13 @@ static unsigned char handle_kbd_event(void) static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - unsigned long flags; - #ifdef CONFIG_VT kbd_pt_regs = regs; #endif - spin_lock_irqsave(&kbd_controller_lock, flags); + + spin_lock_irq(&kbd_controller_lock); handle_kbd_event(); - spin_unlock_irqrestore(&kbd_controller_lock, flags); + spin_unlock_irq(&kbd_controller_lock); } /* diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 9b85db1d6..544d79e73 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -595,7 +595,7 @@ static struct file_operations pp_fops = { release: pp_release, }; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static int __init ppdev_init (void) { diff --git a/drivers/char/q40_keyb.c b/drivers/char/q40_keyb.c index 7ee9818ef..a0e41b189 100644 --- a/drivers/char/q40_keyb.c +++ b/drivers/char/q40_keyb.c @@ -94,7 +94,7 @@ static unsigned char q40ecl[]= }; -spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; /* @@ -340,11 +340,10 @@ static int qprev=0; static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - unsigned long flags; unsigned char status; disable_keyboard(); - spin_lock_irqsave(&kbd_controller_lock, flags); + spin_lock(&kbd_controller_lock); kbd_pt_regs = regs; status = IRQ_KEYB_MASK & master_inb(INTERRUPT_REG); @@ -386,7 +385,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) keyup=1; } exit: - spin_unlock_irqrestore(&kbd_controller_lock, flags); + spin_unlock(&kbd_controller_lock); master_outb(-1,KEYBOARD_UNLOCK_REG); /* keyb ints reenabled herewith */ enable_keyboard(); } diff --git a/drivers/char/qpmouse.c b/drivers/char/qpmouse.c index bba9ddd31..922f56a0c 100644 --- a/drivers/char/qpmouse.c +++ b/drivers/char/qpmouse.c @@ -110,8 +110,8 @@ static int fasync_qp(int fd, struct file *filp, int on) #define QP_IRQ 12 -static int qp_present = 0; -static int qp_count = 0; +static int qp_present; +static int qp_count; static int qp_data = QP_DATA; static int qp_status = QP_STATUS; diff --git a/drivers/char/random.c b/drivers/char/random.c index 228c609da..bf1242e35 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -763,7 +763,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) void add_keyboard_randomness(unsigned char scancode) { - static unsigned char last_scancode = 0; + static unsigned char last_scancode; /* ignore autorepeat (multiple key down w/o key up) */ if (scancode != last_scancode) { last_scancode = scancode; @@ -1998,8 +1998,8 @@ static __u32 twothirdsMD4Transform (__u32 const buf[4], __u32 const in[12]) __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr, __u16 sport, __u16 dport) { - static __u32 rekey_time = 0; - static __u32 count = 0; + static __u32 rekey_time; + static __u32 count; static __u32 secret[12]; struct timeval tv; __u32 seq; @@ -2027,7 +2027,7 @@ __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr, __u32 secure_ipv6_id(__u32 *daddr) { - static time_t rekey_time = 0; + static time_t rekey_time; static __u32 secret[12]; time_t t; @@ -2050,8 +2050,8 @@ __u32 secure_ipv6_id(__u32 *daddr) __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport) { - static __u32 rekey_time = 0; - static __u32 count = 0; + static __u32 rekey_time; + static __u32 count; static __u32 secret[12]; struct timeval tv; __u32 seq; @@ -2105,7 +2105,7 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, */ __u32 secure_ip_id(__u32 daddr) { - static time_t rekey_time = 0; + static time_t rekey_time; static __u32 secret[12]; time_t t; @@ -2144,7 +2144,7 @@ __u32 secure_ip_id(__u32 daddr) #define COOKIEBITS 24 /* Upper bits store count */ #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) -static int syncookie_init = 0; +static int syncookie_init; static __u32 syncookie_secret[2][16-3+HASH_BUFFER_SIZE]; __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport, diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 93d1e1c46..7ff56f84f 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c @@ -211,7 +211,7 @@ void my_hd (void *addr, int len); static struct tty_driver rio_driver, rio_callout_driver; static struct tty_driver rio_driver2, rio_callout_driver2; -static struct tty_struct * rio_table[RIO_NPORTS] = { NULL, }; +static struct tty_struct * rio_table[RIO_NPORTS]; static struct termios ** rio_termios; static struct termios ** rio_termios_locked; @@ -223,9 +223,9 @@ struct rio_info *p; struct rio_port *rio_ports; int rio_refcount; -int rio_initialized = 0; -int rio_nports = 0; -int rio_debug = 0; +int rio_initialized; +int rio_nports; +int rio_debug; /* You can have the driver poll your card. diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 34e1dd51c..d00e3c4fe 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -82,13 +82,13 @@ DECLARE_TASK_QUEUE(tq_riscom); #define RISCOM_TYPE_NORMAL 1 #define RISCOM_TYPE_CALLOUT 2 -static struct riscom_board * IRQ_to_board[16] = { NULL, } ; +static struct riscom_board * IRQ_to_board[16]; static struct tty_driver riscom_driver, riscom_callout_driver; -static int riscom_refcount = 0; -static struct tty_struct * riscom_table[RC_NBOARD * RC_NPORT] = { NULL, }; -static struct termios * riscom_termios[RC_NBOARD * RC_NPORT] = { NULL, }; -static struct termios * riscom_termios_locked[RC_NBOARD * RC_NPORT] = { NULL, }; -static unsigned char * tmp_buf = NULL; +static int riscom_refcount; +static struct tty_struct * riscom_table[RC_NBOARD * RC_NPORT]; +static struct termios * riscom_termios[RC_NBOARD * RC_NPORT]; +static struct termios * riscom_termios_locked[RC_NBOARD * RC_NPORT]; +static unsigned char * tmp_buf; static DECLARE_MUTEX(tmp_buf_sem); static unsigned long baud_table[] = { @@ -103,9 +103,7 @@ static struct riscom_board rc_board[RC_NBOARD] = { { 0, RC_IOBASE4, 0, }, }; -static struct riscom_port rc_port[RC_NBOARD * RC_NPORT] = { - { 0, }, -}; +static struct riscom_port rc_port[RC_NBOARD * RC_NPORT]; /* RISCom/8 I/O ports addresses (without address translation) */ static unsigned short rc_ioport[] = { diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 3d754212e..5cecdde40 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c @@ -154,26 +154,26 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout); static void rp_flush_buffer(struct tty_struct *tty); static struct tty_driver rocket_driver, callout_driver; -static int rocket_refcount = 0; +static int rocket_refcount; -static int rp_num_ports_open = 0; +static int rp_num_ports_open; static struct timer_list rocket_timer; -unsigned long board1 = 0; -unsigned long board2 = 0; -unsigned long board3 = 0; -unsigned long board4 = 0; -unsigned long controller = 0; -unsigned long support_low_speed = 0; +unsigned long board1; +unsigned long board2; +unsigned long board3; +unsigned long board4; +unsigned long controller; +unsigned long support_low_speed; int rp_baud_base = 460800; static unsigned long rcktpt_io_addr[NUM_BOARDS]; static int max_board; #ifdef TIME_STAT -static unsigned long long time_stat = 0; -static unsigned long time_stat_short = 0; -static unsigned long time_stat_long = 0; -static unsigned long time_counter = 0; +static unsigned long long time_stat; +static unsigned long time_stat_short; +static unsigned long time_stat_long; +static unsigned long time_counter; #endif #if ((LINUX_VERSION_CODE > 0x020111) && defined(MODULE)) diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index bd5b20acb..d916a6aba 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -39,10 +39,11 @@ * 1.10a Andrea Arcangeli: Alpha updates * 1.10b Andrew Morton: SMP lock fix * 1.10c Cesar Barros: SMP locking fixes and cleanup - * 1.10d Maciej W. Rozycki: Handle DECstation's year weirdness. + * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit + * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness. */ -#define RTC_VERSION "1.10d" +#define RTC_VERSION "1.10e" #define RTC_IO_EXTENT 0x10 /* Only really two ports, but... */ @@ -743,18 +744,6 @@ found: static void __exit rtc_exit (void) { - /* interrupts and maybe timer disabled at this point by rtc_release */ - /* FIXME: Maybe??? */ - - if (rtc_status & RTC_TIMER_ON) { - spin_lock_irq (&rtc_lock); - rtc_status &= ~RTC_TIMER_ON; - del_timer(&rtc_irq_timer); - spin_unlock_irq (&rtc_lock); - - printk(KERN_WARNING "rtc_exit(), and timer still running.\n"); - } - remove_proc_entry ("driver/rtc", NULL); misc_deregister(&rtc_dev); diff --git a/drivers/char/sbc60xxwdt.c b/drivers/char/sbc60xxwdt.c index 9eb56403e..0c3deed84 100644 --- a/drivers/char/sbc60xxwdt.c +++ b/drivers/char/sbc60xxwdt.c @@ -104,9 +104,9 @@ static void wdt_timer_ping(unsigned long); static struct timer_list timer; -static unsigned long next_heartbeat = 0; -static int wdt_is_open = 0; -static int wdt_expect_close = 0; +static unsigned long next_heartbeat; +static int wdt_is_open; +static int wdt_expect_close; /* * Whack the dog diff --git a/drivers/char/selection.c b/drivers/char/selection.c index f0f67c0cf..b804a61e1 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c @@ -36,11 +36,11 @@ extern void poke_blanked_console(void); /* Variables for selection control. */ /* Use a dynamic buffer, instead of static (Dec 1994) */ - int sel_cons = 0; /* must not be disallocated */ + int sel_cons; /* must not be disallocated */ static volatile int sel_start = -1; /* cleared by clear_selection */ static int sel_end; -static int sel_buffer_lth = 0; -static char *sel_buffer = NULL; +static int sel_buffer_lth; +static char *sel_buffer; /* clear_selection, highlight and highlight_pointer can be called from interrupt (via scrollback/front) */ diff --git a/drivers/char/serial.c b/drivers/char/serial.c index b5492def3..85da92470 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -267,7 +267,7 @@ static struct rs_multiport_struct rs_multiport[NR_IRQS]; static int IRQ_timeout[NR_IRQS]; #ifdef CONFIG_SERIAL_CONSOLE static struct console sercons; -static int lsr_break_flag = 0; +static int lsr_break_flag; #endif #if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) static unsigned long break_pressed; /* break, really ... */ @@ -325,7 +325,7 @@ static struct serial_state rs_table[RS_TABLE_SIZE] = { #define NR_PCI_BOARDS 8 static struct pci_board_inst serial_pci_board[NR_PCI_BOARDS]; -static int serial_pci_board_idx = 0; +static int serial_pci_board_idx; #ifndef IS_PCI_REGION_IOPORT #define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \ @@ -1060,7 +1060,7 @@ static void do_softint(void *private_) */ static void rs_timer(unsigned long dummy) { - static unsigned long last_strobe = 0; + static unsigned long last_strobe; struct async_struct *info; unsigned int i; unsigned long flags; @@ -5666,17 +5666,13 @@ static int __init serial_console_setup(struct console *co, char *options) } static struct console sercons = { - "ttyS", - serial_console_write, - NULL, - serial_console_device, - serial_console_wait_key, - NULL, - serial_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 35b480a1c..3496229c6 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c @@ -2858,17 +2858,13 @@ static int __init serial167_console_setup(struct console *co, char *options) static struct console sercons = { - "ttyS", - serial167_console_write, - NULL, - serial167_console_device, - serial167_console_wait_key, - NULL, - serial167_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: serial167_console_write, + device: serial167_console_device, + wait_key: serial167_console_wait_key, + setup: serial167_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; diff --git a/drivers/char/serial_21285.c b/drivers/char/serial_21285.c index 575cf0bc0..16ad022bd 100644 --- a/drivers/char/serial_21285.c +++ b/drivers/char/serial_21285.c @@ -490,17 +490,13 @@ static int __init rs285_console_setup(struct console *co, char *options) static struct console rs285_cons = { - SERIAL_21285_NAME, - rs285_console_write, - NULL, - rs285_console_device, - rs285_console_wait_key, - NULL, - rs285_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: SERIAL_21285_NAME, + write: rs285_console_write, + device: rs285_console_device, + wait_key: rs285_console_wait_key, + setup: rs285_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; void __init rs285_console_init(void) diff --git a/drivers/char/serial_amba.c b/drivers/char/serial_amba.c index 580427f6b..eaab7d34e 100644 --- a/drivers/char/serial_amba.c +++ b/drivers/char/serial_amba.c @@ -2016,7 +2016,6 @@ static struct console ambauart_cons = #endif device: ambauart_console_device, wait_key: ambauart_console_wait_key, - unblank: NULL, setup: ambauart_console_setup, flags: CON_PRINTBUFFER, index: -1, diff --git a/drivers/char/sh-sci.c b/drivers/char/sh-sci.c index 8f0178d9b..01812ecb0 100644 --- a/drivers/char/sh-sci.c +++ b/drivers/char/sh-sci.c @@ -1247,17 +1247,13 @@ static int __init serial_console_setup(struct console *co, char *options) } static struct console sercons = { - "ttySC", - serial_console_write, - NULL, - serial_console_device, - serial_console_wait_key, - NULL, - serial_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttySC", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/drivers/char/softdog.c b/drivers/char/softdog.c index cb508cbe2..e3f68ba30 100644 --- a/drivers/char/softdog.c +++ b/drivers/char/softdog.c @@ -58,7 +58,7 @@ static void watchdog_fire(unsigned long); static struct timer_list watchdog_ticktock = { function: watchdog_fire, }; -static int timer_alive = 0; +static int timer_alive; /* diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index eab300d5f..6e3c6a99c 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -181,11 +181,11 @@ DECLARE_TASK_QUEUE(tq_specialix); #define SPECIALIX_TYPE_CALLOUT 2 static struct tty_driver specialix_driver, specialix_callout_driver; -static int specialix_refcount = 0; -static struct tty_struct * specialix_table[SX_NBOARD * SX_NPORT] = { NULL, }; -static struct termios * specialix_termios[SX_NBOARD * SX_NPORT] = { NULL, }; -static struct termios * specialix_termios_locked[SX_NBOARD * SX_NPORT] = { NULL, }; -static unsigned char * tmp_buf = NULL; +static int specialix_refcount; +static struct tty_struct * specialix_table[SX_NBOARD * SX_NPORT]; +static struct termios * specialix_termios[SX_NBOARD * SX_NPORT]; +static struct termios * specialix_termios_locked[SX_NBOARD * SX_NPORT]; +static unsigned char * tmp_buf; static DECLARE_MUTEX(tmp_buf_sem); static unsigned long baud_table[] = { @@ -200,9 +200,7 @@ static struct specialix_board sx_board[SX_NBOARD] = { { 0, SX_IOBASE4, 15, }, }; -static struct specialix_port sx_port[SX_NBOARD * SX_NPORT] = { - { 0, }, -}; +static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; #ifdef SPECIALIX_TIMER @@ -1013,7 +1011,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p long tmp; unsigned char cor1 = 0, cor3 = 0; unsigned char mcor1 = 0, mcor2 = 0; - static int again=0; + static int again; if (!(tty = port->tty) || !tty->termios) return; diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index a0faeada4..8907fdeab 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -146,7 +146,7 @@ static struct tty_driver stl_callout; static struct tty_struct *stl_ttys[STL_MAXDEVS]; static struct termios *stl_termios[STL_MAXDEVS]; static struct termios *stl_termioslocked[STL_MAXDEVS]; -static int stl_refcount = 0; +static int stl_refcount; /* * We will need to allocate a temporary write buffer for chars that @@ -192,7 +192,7 @@ static char stl_unwanted[SC26198_RXFIFOSIZE]; * shared with another Stallion board. */ static int stl_gotintrs[STL_MAXBRDS]; -static int stl_numintrs = 0; +static int stl_numintrs; /*****************************************************************************/ @@ -748,7 +748,7 @@ static struct file_operations stl_fsiomem = { /*****************************************************************************/ -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; #ifdef MODULE diff --git a/drivers/char/sx.c b/drivers/char/sx.c index e6336fc03..3dd5811d9 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -309,16 +309,16 @@ static int sx_init_drivers(void); static struct tty_driver sx_driver, sx_callout_driver; -static struct tty_struct * sx_table[SX_NPORTS] = { NULL, }; +static struct tty_struct * sx_table[SX_NPORTS]; static struct termios ** sx_termios; static struct termios ** sx_termios_locked; struct sx_board boards[SX_NBOARDS]; struct sx_port *sx_ports; int sx_refcount; -int sx_initialized = 0; -int sx_nports = 0; -int sx_debug = 0; +int sx_initialized; +int sx_nports; +int sx_debug; /* You can have the driver poll your card. @@ -330,7 +330,7 @@ int sx_debug = 0; everything will continue to work.... */ int sx_poll = 1; -int sx_slowpoll = 0; +int sx_slowpoll; /* The card limits the number of interrupts per second. At 115k2 "100" should be sufficient. @@ -2077,7 +2077,7 @@ static int sx_init_board (struct sx_board *board) void printheader(void) { - static int header_printed = 0; + static int header_printed; if (!header_printed) { printk (KERN_INFO "Specialix SX driver " diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 6419b4a8f..6da32381e 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -3354,7 +3354,6 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) } } - set_current_state(TASK_RUNNING); exit: if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgsl_wait_until_sent(%s) exit\n", diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 9650457c0..3c05aa042 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -34,7 +34,7 @@ extern struct list_head super_blocks; int sysrq_enabled = 1; /* Machine specific power off function */ -void (*sysrq_power_off)(void) = NULL; +void (*sysrq_power_off)(void); EXPORT_SYMBOL(sysrq_power_off); diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c index 14a42682d..cf521edfe 100644 --- a/drivers/char/tpqic02.c +++ b/drivers/char/tpqic02.c @@ -116,7 +116,7 @@ static struct mtconfiginfo qic02_tape_dynconf = /* user settable */ { 0, 0, BOGUS_IRQ, 0, 0, TPQD_DEFAULT_FLAGS, }; -static struct qic02_ccb qic02_tape_ccb = { 0, }; /* private stuff */ +static struct qic02_ccb qic02_tape_ccb; /* private stuff */ #else @@ -127,7 +127,7 @@ unsigned long qic02_tape_debug = TPQD_DEFAULT_FLAGS; # endif #endif /* CONFIG_QIC02_DYNCONF */ -static volatile int ctlbits = 0; /* control reg bits for tape interface */ +static volatile int ctlbits; /* control reg bits for tape interface */ static wait_queue_head_t qic02_tape_transfer; /* sync rw with interrupts */ @@ -149,10 +149,10 @@ static flag status_zombie = YES; /* it's `zombie' until irq/dma allocated */ static volatile flag status_bytes_wr = NO; /* write FM at close or not */ static volatile flag status_bytes_rd = NO; /* (rd|wr) used for rewinding */ -static volatile unsigned long status_cmd_pending = 0; /* cmd in progress */ +static volatile unsigned long status_cmd_pending; /* cmd in progress */ static volatile flag status_expect_int = NO; /* ready for interrupts */ static volatile flag status_timer_on = NO; /* using time-out */ -static volatile int status_error = 0; /* int handler may detect error */ +static volatile int status_error; /* int handler may detect error */ static volatile flag status_eof_detected = NO; /* end of file */ static volatile flag status_eom_detected = NO; /* end of recorded media */ static volatile flag status_eot_detected = NO; /* end of tape */ @@ -161,7 +161,7 @@ static volatile flag doing_write = NO; static volatile unsigned long dma_bytes_todo; static volatile unsigned long dma_bytes_done; -static volatile unsigned dma_mode = 0; /* !=0 also means DMA in use */ +static volatile unsigned dma_mode; /* !=0 also means DMA in use */ static flag need_rewind = YES; static kdev_t current_tape_dev; @@ -208,7 +208,7 @@ static void qic02_release_resources(void); * must ensure that a large enough buffer is passed to the kernel, in order * to reduce tape repositioning wear and tear. */ -static unsigned long buffaddr = 0; /* physical address of buffer */ +static unsigned long buffaddr; /* physical address of buffer */ /* This translates minor numbers to the corresponding recording format: */ static const char *format_names[] = { diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 76d2df295..50e03a103 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1414,7 +1414,7 @@ init_dev_done: if ((tty->driver.type == TTY_DRIVER_TYPE_SERIAL) && (tty->driver.subtype == SERIAL_TYPE_CALLOUT) && (tty->count == 1)) { - static int nr_warns = 0; + static int nr_warns; if (nr_warns < 5) { printk(KERN_WARNING "tty_io.c: " "process %d (%s) used obsolete /dev/%s - " diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 920873d9e..e6032c24d 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c @@ -459,7 +459,7 @@ static struct file_operations vcs_fops = { open: vcs_open, }; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; void vcs_make_devfs (unsigned int index, int unregister) { diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index b6b2263a0..ecf7cf05e 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c @@ -1111,17 +1111,13 @@ static int __init scc_console_setup(struct console *co, char *options) static struct console sercons = { - "ttyS", - scc_console_write, - NULL, - scc_console_device, - scc_console_wait_key, - NULL, - scc_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: scc_console_write, + device: scc_console_device, + wait_key: scc_console_wait_key, + setup: scc_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 90d01c4a4..4328bbaeb 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -36,7 +36,7 @@ #include <asm/vc_ioctl.h> #endif /* CONFIG_FB_COMPAT_XPMAC */ -char vt_dont_switch = 0; +char vt_dont_switch; extern struct tty_driver console_driver; #define VT_IS_IN_USE(i) (console_driver.table[i] && console_driver.table[i]->count) diff --git a/drivers/char/wdt285.c b/drivers/char/wdt285.c index bbfb5d992..4993e6cbe 100644 --- a/drivers/char/wdt285.c +++ b/drivers/char/wdt285.c @@ -43,7 +43,7 @@ #define FCLK (50*1000*1000) /* 50MHz */ static int soft_margin = TIMER_MARGIN; /* in seconds */ -static int timer_alive = 0; +static int timer_alive; #ifdef ONLY_TESTING /* diff --git a/drivers/char/wdt977.c b/drivers/char/wdt977.c index d9ea545a7..1767fbf3b 100644 --- a/drivers/char/wdt977.c +++ b/drivers/char/wdt977.c @@ -29,8 +29,8 @@ #define WATCHDOG_MINOR 130 static int timeout = 3; -static int timer_alive = 0; -static int testmode = 0; +static int timer_alive; +static int testmode; /* * Allow only one person to hold it open diff --git a/drivers/i2o/i2o_core.c b/drivers/i2o/i2o_core.c index d39e32529..87871fa15 100644 --- a/drivers/i2o/i2o_core.c +++ b/drivers/i2o/i2o_core.c @@ -183,7 +183,7 @@ static struct reply_info events[I2O_EVT_Q_LEN]; static int evt_in = 0; static int evt_out = 0; static int evt_q_len = 0; -#define MODINC(x,y) (x = x++ % y) +#define MODINC(x,y) ((x) = ((x) + 1) % (y)) /* * I2O configuration spinlock. This isnt a big deal for contention diff --git a/drivers/i2o/i2o_scsi.c b/drivers/i2o/i2o_scsi.c index 3c147cf9f..1985d68ea 100644 --- a/drivers/i2o/i2o_scsi.c +++ b/drivers/i2o/i2o_scsi.c @@ -437,6 +437,8 @@ int i2o_scsi_detect(Scsi_Host_Template * tpnt) continue; shpnt = scsi_register(tpnt, sizeof(struct i2o_scsi_host)); + if(shpnt==NULL) + continue; save_flags(flags); cli(); shpnt->unique_id = (u32)d; @@ -902,12 +904,8 @@ int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip) return 0; } -/* Loadable module support */ -#ifdef MODULE - MODULE_AUTHOR("Red Hat Software"); -Scsi_Host_Template driver_template = I2OSCSI; +static Scsi_Host_Template driver_template = I2OSCSI; #include "../scsi/scsi_module.c" -#endif diff --git a/drivers/ide/Config.in b/drivers/ide/Config.in index d4687f703..4db04ef96 100644 --- a/drivers/ide/Config.in +++ b/drivers/ide/Config.in @@ -68,7 +68,9 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then dep_bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL dep_bool ' PROMISE PDC20246/PDC20262/PDC20267 support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX + dep_bool ' ServerWorks OSB4 chipset support' CONFIG_BLK_DEV_OSB4 $CONFIG_BLK_DEV_OSB4 dep_bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 + dep_bool ' SLC90E66 chipset support' CONFIG_BLK_DEV_SLC90E66 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 dep_bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' VIA82CXXX chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI fi @@ -154,9 +156,11 @@ if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ "$CONFIG_BLK_DEV_HPT366" = "y" -o \ "$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \ "$CONFIG_BLK_DEV_OPTI621" = "y" -o \ + "$CONFIG_BLK_DEV_OSB4" = "y" -o \ "$CONFIG_BLK_DEV_PDC202XX" = "y" -o \ "$CONFIG_BLK_DEV_PIIX" = "y" -o \ "$CONFIG_BLK_DEV_SIS5513" = "y" -o \ + "$CONFIG_BLK_DEV_SLC90E66" = "y" -o \ "$CONFIG_BLK_DEV_SL82C105" = "y" -o \ "$CONFIG_BLK_DEV_VIA82CXXX" = "y" ]; then define_bool CONFIG_BLK_DEV_IDE_MODES y diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index cc8d4e870..d5b4b637e 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -1,14 +1,8 @@ # # Makefile for the kernel ata, atapi, and ide block device drivers. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definition is now inherited from the -# parent makefile. -# - +# 12 September 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> +# Rewritten to use lists instead of if-statements. # # Note : at this point, these files are compiled on all systems. # In the future, some of these should be built conditionally. @@ -19,219 +13,85 @@ MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) O_TARGET := idedriver.o -O_OBJS := ide-geometry.o -M_OBJS := -OX_OBJS := -MX_OBJS := - -ifeq ($(CONFIG_BLK_DEV_AEC62XX),y) -IDE_OBJS += aec62xx.o -endif - -ifeq ($(CONFIG_BLK_DEV_ALI14XX),y) -IDE_OBJS += ali14xx.o -endif - -ifeq ($(CONFIG_BLK_DEV_ALI15X3),y) -IDE_OBJS += alim15x3.o -endif - -ifeq ($(CONFIG_BLK_DEV_AMD7409),y) -IDE_OBJS += amd7409.o -endif - -ifeq ($(CONFIG_BLK_DEV_BUDDHA),y) -IDE_OBJS += buddha.o -endif - -ifeq ($(CONFIG_BLK_DEV_CMD640),y) -IDE_OBJS += cmd640.o -endif - -ifeq ($(CONFIG_BLK_DEV_CMD64X),y) -IDE_OBJS += cmd64x.o -endif - -ifeq ($(CONFIG_BLK_DEV_CS5530),y) -IDE_OBJS += cs5530.o -endif - -ifeq ($(CONFIG_BLK_DEV_CY82C693),y) -IDE_OBJS += cy82c693.o -endif - -ifeq ($(CONFIG_BLK_DEV_DTC2278),y) -IDE_OBJS += dtc2278.o -endif - -ifeq ($(CONFIG_BLK_DEV_FALCON_IDE),y) -IDE_OBJS += falconide.o -endif - -ifeq ($(CONFIG_BLK_DEV_GAYLE),y) -IDE_OBJS += gayle.o -endif - -ifeq ($(CONFIG_BLK_DEV_Q40IDE),y) -IDE_OBJS += q40ide.o -endif - -ifeq ($(CONFIG_BLK_DEV_HD),y) -O_OBJS += hd.o -endif - -ifeq ($(CONFIG_BLK_DEV_HPT34X),y) -IDE_OBJS += hpt34x.o -endif - -ifeq ($(CONFIG_BLK_DEV_HPT366),y) -IDE_OBJS += hpt366.o -endif - -ifeq ($(CONFIG_BLK_DEV_HT6560B),y) -IDE_OBJS += ht6560b.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDE_ICSIDE),y) -IDE_OBJS += icside.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDEDMA),y) -IDE_OBJS += ide-dma.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDEPCI),y) -IDE_OBJS += ide-pci.o -endif - -ifeq ($(CONFIG_BLK_DEV_ISAPNP),y) -IDE_OBJS += ide-pnp.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDE_PMAC),y) -IDE_OBJS += ide-pmac.o -endif - -ifeq ($(CONFIG_BLK_DEV_MAC_IDE),y) -IDE_OBJS += macide.o -endif - -ifeq ($(CONFIG_BLK_DEV_NS87415),y) -IDE_OBJS += ns87415.o -endif - -ifeq ($(CONFIG_BLK_DEV_OPTI621),y) -IDE_OBJS += opti621.o -endif - -ifeq ($(CONFIG_BLK_DEV_PDC202XX),y) -IDE_OBJS += pdc202xx.o -endif - -ifeq ($(CONFIG_BLK_DEV_PDC4030),y) -IDE_OBJS += pdc4030.o -endif - -ifeq ($(CONFIG_BLK_DEV_PIIX),y) -IDE_OBJS += piix.o -endif - -ifeq ($(CONFIG_BLK_DEV_QD6580),y) -IDE_OBJS += qd6580.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDE_RAPIDE),y) -IDE_OBJS += rapide.o -endif - -ifeq ($(CONFIG_BLK_DEV_RZ1000),y) -IDE_OBJS += rz1000.o -endif - -ifeq ($(CONFIG_BLK_DEV_SIS5513),y) -IDE_OBJS += sis5513.o -endif - -ifeq ($(CONFIG_BLK_DEV_SL82C105),y) -IDE_OBJS += sl82c105.o -endif - -ifeq ($(CONFIG_BLK_DEV_TRM290),y) -IDE_OBJS += trm290.o -endif - -ifeq ($(CONFIG_BLK_DEV_UMC8672),y) -IDE_OBJS += umc8672.o -endif - -ifeq ($(CONFIG_BLK_DEV_VIA82CXXX),y) -IDE_OBJS += via82cxxx.o -endif - -### if CONFIG_BLK_DEV_IDE is n, IDE_OBJS will be ignored - -ifeq ($(CONFIG_PROC_FS),y) -IDE_OBJS += ide-proc.o -endif - -###Collect - -ifeq ($(CONFIG_BLK_DEV_IDE),y) - OX_OBJS += ide.o ide-features.o - O_OBJS += ide-probe.o $(IDE_OBJS) -else - ifeq ($(CONFIG_BLK_DEV_IDE),m) - MIX_OBJS += ide.o ide-features.o $(IDE_OBJS) - M_OBJS += ide-mod.o ide-probe-mod.o - endif -endif - -############ - -ifeq ($(CONFIG_BLK_DEV_IDECS),y) -O_OBJS += ide-cs.o -else - ifeq ($(CONFIG_BLK_DEV_IDECS),m) - M_OBJS += ide-cs.o - endif -endif - -ifeq ($(CONFIG_BLK_DEV_IDEDISK),y) -O_OBJS += ide-disk.o -else - ifeq ($(CONFIG_BLK_DEV_IDEDISK),m) - M_OBJS += ide-disk.o - endif -endif - -ifeq ($(CONFIG_BLK_DEV_IDECD),y) -O_OBJS += ide-cd.o -else - ifeq ($(CONFIG_BLK_DEV_IDECD),m) - M_OBJS += ide-cd.o - endif -endif - -ifeq ($(CONFIG_BLK_DEV_IDETAPE),y) -O_OBJS += ide-tape.o -else - ifeq ($(CONFIG_BLK_DEV_IDETAPE),m) - M_OBJS += ide-tape.o - endif -endif -ifeq ($(CONFIG_BLK_DEV_IDEFLOPPY),y) -O_OBJS += ide-floppy.o -else - ifeq ($(CONFIG_BLK_DEV_IDEFLOPPY),m) - M_OBJS += ide-floppy.o - endif -endif +obj-y := +obj-m := +ide-obj-y := + +ide-obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o +ide-obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o +ide-obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o +ide-obj-$(CONFIG_BLK_DEV_AMD7409) += amd7409.o +ide-obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o +ide-obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o +ide-obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o +ide-obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o +ide-obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o +ide-obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o +ide-obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o +ide-obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o +ide-obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o +ide-obj-$(CONFIG_BLK_DEV_HD) += hd.o +ide-obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o +ide-obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o +ide-obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o +ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o +ide-obj-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o +ide-obj-$(CONFIG_BLK_DEV_IDEPCI) += ide-pci.o +ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o +ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC) += ide-pmac.o +ide-obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o +ide-obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o +ide-obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o +ide-obj-$(CONFIG_BLK_DEV_OSB4) += osb4.o +ide-obj-$(CONFIG_BLK_DEV_PDC202XX) += pdc202xx.o +ide-obj-$(CONFIG_BLK_DEV_PDC4030) += pdc4030.o +ide-obj-$(CONFIG_BLK_DEV_PIIX) += piix.o +ide-obj-$(CONFIG_BLK_DEV_QD6580) += qd6580.o +ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o +ide-obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o +ide-obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o +ide-obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o +ide-obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o +ide-obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o +ide-obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o +ide-obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o + +ide-obj-$(CONFIG_PROC_FS) += ide-proc.o + +export-objs := ide.o ide-features.o +list-multi := ide-mod.o ide-probe-mod.o +ide-mod-objs := $(export-objs) $(ide-obj-y) +ide-probe-mod-objs := ide-probe.o ide-geometry.o + +obj-$(CONFIG_BLK_DEV_IDE) += ide-mod.o ide-probe-mod.o +obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.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 + +# Extract lists of the multi-part drivers. +# The 'int-*' lists are the intermediate files used to build the multi's. +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) + +# Take multi-part drivers out of obj-y and put components in. +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) + +# Translate to Rules.make lists. +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) +MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) include $(TOPDIR)/Rules.make -ide-mod.o: ide.o ide-features.o $(IDE_OBJS) - $(LD) $(LD_RFLAG) -r -o $@ ide.o ide-features.o $(IDE_OBJS) +ide-mod.o: $(ide-mod-objs) + $(LD) -r -o $@ $(ide-mod-objs) -ide-probe-mod.o: ide-probe.o ide-geometry.o - $(LD) $(LD_RFLAG) -r -o $@ ide-probe.o ide-geometry.o +ide-probe-mod.o: $(ide-probe-mod-objs) + $(LD) -r -o $@ $(ide-probe-mod-objs) diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 41768bb90..813aecd3b 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -171,11 +171,11 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count) ((reg5yh & 0x30)>>4) + 12 ); } } else { - p += sprintf(p, q, - (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4, - (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4, - (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4, - (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4 ); + int t1 = (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4; + int t2 = (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4; + int t3 = (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4; + int t4 = (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4; + p += sprintf(p, q, t1, t2, t3, t4); } #if 0 diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c index 710b6654d..7ef6f645a 100644 --- a/drivers/ide/buddha.c +++ b/drivers/ide/buddha.c @@ -117,19 +117,15 @@ static int __init find_buddha(void) buddha_num_hwifs = 0; while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { unsigned long board; - const char *name; - if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { + if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) buddha_num_hwifs = BUDDHA_NUM_HWIFS; - name = "Buddha IDE Interface"; - } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) { + else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) buddha_num_hwifs = CATWEASEL_NUM_HWIFS; - name = "Catweasel IDE Interface and Floppy Controller"; - } else + else continue; board = z->resource.start; if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE")) continue; - strcpy(z->name, name); buddha_board = ZTWO_VADDR(board); /* write to BUDDHA_IRQ_MR to enable the board IRQ */ *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index ae9f62768..9d0fc8e74 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -64,8 +64,8 @@ static void idedisk_bswap_data (void *buffer, int wcount) u16 *p = buffer; while (wcount--) { - *p++ = *p << 8 | *p >> 8; - *p++ = *p << 8 | *p >> 8; + *p = *p << 8 | *p >> 8; p++; + *p = *p << 8 | *p >> 8; p++; } } diff --git a/drivers/ide/ide-features.c b/drivers/ide/ide-features.c index fa765d76f..2dfef8bee 100644 --- a/drivers/ide/ide-features.c +++ b/drivers/ide/ide-features.c @@ -224,7 +224,8 @@ int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature) #ifndef CONFIG_IDEDMA_IVB if ((drive->id->hw_config & 0x6000) == 0) { #else /* !CONFIG_IDEDMA_IVB */ - if ((drive->id->hw_config & 0x2000) == 0) { + if (((drive->id->hw_config & 0x2000) == 0) || + ((drive->id->hw_config & 0x4000) == 0)) { #endif /* CONFIG_IDEDMA_IVB */ printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name); return 1; @@ -260,7 +261,7 @@ byte eighty_ninty_three (ide_drive_t *drive) #ifndef CONFIG_IDEDMA_IVB (drive->id->hw_config & 0x4000) && #endif /* CONFIG_IDEDMA_IVB */ - (drive->id->hw_config & 0x2000)) ? 1 : 0); + (drive->id->hw_config & 0x6000)) ? 1 : 0); } /* diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c index 561b1c3cf..f1304a4a0 100644 --- a/drivers/ide/ide-pci.c +++ b/drivers/ide/ide-pci.c @@ -72,6 +72,8 @@ #define DEVID_CS5530 ((ide_pci_devid_t){PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE}) #define DEVID_AMD7403 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7403}) #define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409}) +#define DEVID_SLC90E66 ((ide_pci_devid_t){PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1}) +#define DEVID_OSB4 ((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE}) #define IDE_IGNORE ((void *)-1) @@ -205,6 +207,19 @@ extern void ide_init_opti621(ide_hwif_t *); #define INIT_OPTI621 NULL #endif +#ifdef CONFIG_BLK_DEV_OSB4 +extern unsigned int pci_init_osb4(struct pci_dev *, const char *); +extern unsigned int ata66_osb4(ide_hwif_t *); +extern void ide_init_osb4(ide_hwif_t *); +#define PCI_OSB4 &pci_init_osb4 +#define ATA66_OSB4 &ata66_osb4 +#define INIT_OSB4 &ide_init_osb4 +#else +#define PCI_OSB4 NULL +#define ATA66_OSB4 NULL +#define INIT_OSB4 NULL +#endif + #ifdef CONFIG_BLK_DEV_PDC202XX extern unsigned int pci_init_pdc202xx(struct pci_dev *, const char *); extern unsigned int ata66_pdc202xx(ide_hwif_t *); @@ -253,6 +268,19 @@ extern void ide_init_sis5513(ide_hwif_t *); #define INIT_SIS5513 NULL #endif +#ifdef CONFIG_BLK_DEV_SLC90E66 +extern unsigned int pci_init_slc90e66(struct pci_dev *, const char *); +extern unsigned int ata66_slc90e66(ide_hwif_t *); +extern void ide_init_slc90e66(ide_hwif_t *); +#define PCI_SLC90E66 &pci_init_slc90e66 +#define ATA66_SLC90E66 &ata66_slc90e66 +#define INIT_SLC90E66 &ide_init_slc90e66 +#else +#define PCI_SLC90E66 NULL +#define ATA66_SLC90E66 NULL +#define INIT_SLC90E66 NULL +#endif + #ifdef CONFIG_BLK_DEV_SL82C105 extern void ide_init_sl82c105(ide_hwif_t *); extern void ide_dmacapable_sl82c105(ide_hwif_t *, unsigned long); @@ -351,6 +379,8 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_CS5530, "CS5530", PCI_CS5530, NULL, INIT_CS5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AMD7403, "AMD7403", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AMD7409, "AMD7409", PCI_AMD7409, ATA66_AMD7409, INIT_AMD7409, DMA_AMD7409, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, + {DEVID_SLC90E66,"SLC90E66", PCI_SLC90E66, ATA66_SLC90E66, INIT_SLC90E66, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_OSB4, "ServerWorks OSB4", PCI_OSB4, ATA66_OSB4, INIT_OSB4, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; /* @@ -466,7 +496,7 @@ static int __init ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) */ for (reg = 0; reg < 4; reg++) { struct resource *res = dev->resource + reg; - if (!(res->flags & PCI_BASE_ADDRESS_SPACE_IO)) + if ((res->flags & IORESOURCE_IO) == 0) continue; if (!res->start) { printk("%s: Missing I/O address #%d\n", name, reg); @@ -493,11 +523,16 @@ static void __init ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t * byte tmp = 0; ide_hwif_t *hwif, *mate = NULL; unsigned int class_rev; - int pci_class_ide; #ifdef CONFIG_IDEDMA_AUTO autodma = 1; #endif + +#if 1 /* what do do with this useful tool ??? */ + if (pci_enable_device(dev)) + return; +#endif + check_if_enabled: if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) { printk("%s: error accessing PCI regs\n", d->name); @@ -539,8 +574,7 @@ check_if_enabled: * Can we trust the reported IRQ? */ pciirq = dev->irq; - pci_class_ide = ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE); - if (!pci_class_ide) { + if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) { printk("%s: not 100%% native mode: will probe irqs later\n", d->name); /* * This allows offboard ide-pci cards the enable a BIOS, @@ -550,17 +584,11 @@ check_if_enabled: */ pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : ide_special_settings(dev, d->name); } else if (tried_config) { - printk(KERN_INFO "%s: will probe irqs later\n", d->name); + printk("%s: will probe irqs later\n", d->name); pciirq = 0; } else if (!pciirq) { - if (pci_class_ide) { - /* this is the normal path for most IDE devices */ - if (d->init_chipset) - pciirq = d->init_chipset(dev, d->name); - else - printk(KERN_INFO "%s standard IDE storage device detected\n", d->name); - } else - printk(KERN_WARNING "%s: bad irq (0): will probe later\n", d->name); + printk("%s: bad irq (%d): will probe later\n", d->name, pciirq); + pciirq = 0; } else { if (d->init_chipset) (void) d->init_chipset(dev, d->name); @@ -656,6 +684,7 @@ check_if_enabled: IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD648) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD649) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_OSB4) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name); if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 4bb181241..56e8a9593 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -101,6 +101,10 @@ int (*hpt34x_display_info)(char *, char **, off_t, int) = NULL; extern byte hpt366_proc; int (*hpt366_display_info)(char *, char **, off_t, int) = NULL; #endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_OSB4 +extern byte osb4_proc; +int (*osb4_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_OSB4 */ #ifdef CONFIG_BLK_DEV_PDC202XX extern byte pdc202xx_proc; int (*pdc202xx_display_info)(char *, char **, off_t, int) = NULL; @@ -113,6 +117,10 @@ int (*piix_display_info)(char *, char **, off_t, int) = NULL; extern byte sis_proc; int (*sis_display_info)(char *, char **, off_t, int) = NULL; #endif /* CONFIG_BLK_DEV_SIS5513 */ +#ifdef CONFIG_BLK_DEV_SLC90E66 +extern byte slc90e66_proc; +int (*slc90e66_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_SLC90E66 */ #ifdef CONFIG_BLK_DEV_VIA82CXXX extern byte via_proc; int (*via_display_info)(char *, char **, off_t, int) = NULL; @@ -829,6 +837,10 @@ void proc_ide_create(void) if ((hpt366_display_info) && (hpt366_proc)) create_proc_info_entry("hpt366", 0, proc_ide_root, hpt366_display_info); #endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_OSB4 + if ((osb4_display_info) && (osb4_proc)) + create_proc_info_entry("osb4", 0, proc_ide_root, osb4_display_info); +#endif /* CONFIG_BLK_DEV_OSB4 */ #ifdef CONFIG_BLK_DEV_PDC202XX if ((pdc202xx_display_info) && (pdc202xx_proc)) create_proc_info_entry("pdc202xx", 0, proc_ide_root, pdc202xx_display_info); @@ -841,6 +853,10 @@ void proc_ide_create(void) if ((sis_display_info) && (sis_proc)) create_proc_info_entry("sis", 0, proc_ide_root, sis_display_info); #endif /* CONFIG_BLK_DEV_SIS5513 */ +#ifdef CONFIG_BLK_DEV_SLC90E66 + if ((slc90e66_display_info) && (slc90e66_proc)) + create_proc_info_entry("slc90e66", 0, proc_ide_root, slc90e66_display_info); +#endif /* CONFIG_BLK_DEV_SLC90E66 */ #ifdef CONFIG_BLK_DEV_VIA82CXXX if ((via_display_info) && (via_proc)) create_proc_info_entry("via", 0, proc_ide_root, via_display_info); @@ -881,6 +897,10 @@ void proc_ide_destroy(void) if ((hpt366_display_info) && (hpt366_proc)) remove_proc_entry("ide/hpt366",0); #endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_OSB4 + if ((osb4_display_info) && (osb4_proc)) + remove_proc_entry("ide/osb4",0); +#endif /* CONFIG_BLK_DEV_OSB4 */ #ifdef CONFIG_BLK_DEV_PDC202XX if ((pdc202xx_display_info) && (pdc202xx_proc)) remove_proc_entry("ide/pdc202xx",0); @@ -893,6 +913,10 @@ void proc_ide_destroy(void) if ((sis_display_info) && (sis_proc)) remove_proc_entry("ide/sis", 0); #endif /* CONFIG_BLK_DEV_SIS5513 */ +#ifdef CONFIG_BLK_DEV_SLC90E66 + if ((slc90e66_display_info) && (slc90e66_proc)) + remove_proc_entry("ide/slc90e66",0); +#endif /* CONFIG_BLK_DEV_SLC90E66 */ #ifdef CONFIG_BLK_DEV_VIA82CXXX if ((via_display_info) && (via_proc)) remove_proc_entry("ide/via",0); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index f36dbd8ff..079353425 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -3126,8 +3126,11 @@ static void idetape_create_load_unload_cmd (ide_drive_t *drive, idetape_pc_t *pc idetape_init_pc (pc); pc->c[0] = IDETAPE_LOAD_UNLOAD_CMD; pc->c[4] = cmd; - if (tape->onstream) + if (tape->onstream) { pc->c[1] = 1; + if (cmd == !IDETAPE_LU_LOAD_MASK) + pc->c[4] = 4; + } set_bit (PC_WAIT_FOR_DSC, &pc->flags); pc->callback = &idetape_pc_callback; } @@ -3239,12 +3242,18 @@ static void idetape_create_locate_cmd (ide_drive_t *drive, idetape_pc_t *pc, uns pc->callback = &idetape_pc_callback; } -static void idetape_create_prevent_cmd (ide_drive_t *drive, idetape_pc_t *pc, int prevent) +static int idetape_create_prevent_cmd (ide_drive_t *drive, idetape_pc_t *pc, int prevent) { + idetape_tape_t *tape = drive->driver_data; + + if (!tape->capabilities.lock) + return 0; + idetape_init_pc(pc); pc->c[0] = IDETAPE_PREVENT_CMD; pc->c[4] = prevent; pc->callback = &idetape_pc_callback; + return 1; } static int __idetape_discard_read_pipeline (ide_drive_t *drive) @@ -5017,13 +5026,15 @@ static int idetape_mtioctop (ide_drive_t *drive,short mt_op,int mt_count) } } case MTLOCK: - idetape_create_prevent_cmd(drive, &pc, 1); + if (!idetape_create_prevent_cmd(drive, &pc, 1)) + return 0; retval = idetape_queue_pc_tail (drive,&pc); if (retval) return retval; tape->door_locked = DOOR_EXPLICITLY_LOCKED; return 0; case MTUNLOCK: - idetape_create_prevent_cmd(drive, &pc, 0); + if (!idetape_create_prevent_cmd(drive, &pc, 0)) + return 0; retval = idetape_queue_pc_tail (drive,&pc); if (retval) return retval; tape->door_locked = DOOR_UNLOCKED; @@ -5262,10 +5273,11 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp) clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags); if (tape->chrdev_direction == idetape_direction_none) { - idetape_create_prevent_cmd(drive, &pc, 1); - if (!idetape_queue_pc_tail (drive,&pc)) { - if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) - tape->door_locked = DOOR_LOCKED; + if (idetape_create_prevent_cmd(drive, &pc, 1)) { + if (!idetape_queue_pc_tail (drive,&pc)) { + if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) + tape->door_locked = DOOR_LOCKED; + } } idetape_analyze_headers(drive); } @@ -5320,9 +5332,9 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp) (void) idetape_rewind_tape (drive); if (tape->chrdev_direction == idetape_direction_none) { if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) { - idetape_create_prevent_cmd(drive, &pc, 0); - if (!idetape_queue_pc_tail (drive,&pc)) - tape->door_locked = DOOR_UNLOCKED; + if (idetape_create_prevent_cmd(drive, &pc, 0)) + if (!idetape_queue_pc_tail (drive,&pc)) + tape->door_locked = DOOR_UNLOCKED; } } clear_bit (IDETAPE_BUSY, &tape->flags); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 5d00083c3..32205cccc 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -163,12 +163,12 @@ static const byte ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR }; -static int idebus_parameter = 0; /* holds the "idebus=" parameter */ -static int system_bus_speed = 0; /* holds what we think is VESA/PCI bus speed */ +static int idebus_parameter; /* holds the "idebus=" parameter */ +static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ static int initializing; /* set while initializing built-in drivers */ #ifdef CONFIG_BLK_DEV_IDEPCI -static int ide_scan_direction = 0; /* THIS was formerly 2.2.x pci=reverse */ +static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ #endif /* CONFIG_BLK_DEV_IDEPCI */ #if defined(__mc68000__) || defined(CONFIG_APUS) @@ -176,14 +176,14 @@ static int ide_scan_direction = 0; /* THIS was formerly 2.2.x pci=reverse */ * ide_lock is used by the Atari code to obtain access to the IDE interrupt, * which is shared between several drivers. */ -static int ide_lock = 0; +static int ide_lock; #endif /* __mc68000__ || CONFIG_APUS */ /* * ide_modules keeps track of the available IDE chipset/probe/driver modules. */ -ide_module_t *ide_modules = NULL; -ide_module_t *ide_probe = NULL; +ide_module_t *ide_modules; +ide_module_t *ide_probe; /* * This is declared extern in ide.h, for access by other IDE modules: @@ -1509,7 +1509,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); if (!OK_STAT(stat, READY_STAT, BAD_STAT)) { /* Try to not flood the console with msgs */ - static unsigned long last_msgtime = 0, count = 0; + static unsigned long last_msgtime, count; ++count; if (0 < (signed long)(jiffies - (last_msgtime + HZ))) { last_msgtime = jiffies; @@ -3499,7 +3499,7 @@ EXPORT_SYMBOL(ide_spin_wait_hwgroup); /* * Probe module */ -devfs_handle_t ide_devfs_handle = NULL; +devfs_handle_t ide_devfs_handle; EXPORT_SYMBOL(ide_probe); EXPORT_SYMBOL(drive_is_flashcard); @@ -3561,7 +3561,7 @@ EXPORT_SYMBOL(system_bus_clock); */ int __init ide_init (void) { - static char banner_printed = 0; + static char banner_printed; int i; if (!banner_printed) { diff --git a/drivers/ide/osb4.c b/drivers/ide/osb4.c new file mode 100644 index 000000000..85b6cda9d --- /dev/null +++ b/drivers/ide/osb4.c @@ -0,0 +1,322 @@ +/* + * linux/drivers/block/osb4.c Version 0.2 17 Oct 2000 + * + * Copyright (C) 2000 Cobalt Networks, Inc. <asun@cobalt.com> + * May be copied or modified under the terms of the GNU General Public License + * + * interface borrowed from alim15x3.c: + * Copyright (C) 1998-2000 Michel Aubry, Maintainer + * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer + * + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> + * + * IDE support for the ServerWorks OSB4 IDE chipset + * + * here's the default lspci: + * + * 00:0f.1 IDE interface: ServerWorks: Unknown device 0211 (prog-if 8a [Master SecP PriP]) + * Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- + * Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- + * Latency: 255 + * Region 4: I/O ports at c200 + * 00: 66 11 11 02 05 01 00 02 00 8a 01 01 00 ff 80 00 + * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 20: 01 c2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 40: 99 99 99 99 ff ff ff ff 0c 0c 00 00 00 00 00 00 + * 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/ioport.h> +#include <linux/pci.h> +#include <linux/hdreg.h> +#include <linux/ide.h> +#include <linux/init.h> + +#include <asm/delay.h> +#include <asm/io.h> + +#include "ide_modes.h" + +#define OSB4_DEBUG_DRIVE_INFO 0 + +#define DISPLAY_OSB4_TIMINGS + +#if defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static byte osb4_revision = 0; +static struct pci_dev *bmide_dev; + +static int osb4_get_info(char *, char **, off_t, int, int); +extern int (*osb4_display_info)(char *, char **, off_t, int, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); + +static int osb4_get_info (char *buffer, char **addr, off_t offset, int count, int dummy) +{ + char *p = buffer; + u32 bibma = pci_resource_start(bmide_dev, 4); + u16 reg56; + u8 c0 = 0, c1 = 0, reg54; + + pci_read_config_byte(bmide_dev, 0x54, ®54); + pci_read_config_word(bmide_dev, 0x56, ®56); + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + p += sprintf(p, "\n ServerWorks OSB4 Chipset.\n"); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); + p += sprintf(p, "DMA enabled: %s %s %s %s\n", + (c0&0x20) ? "yes" : "no ", + (c0&0x40) ? "yes" : "no ", + (c1&0x20) ? "yes" : "no ", + (c1&0x40) ? "yes" : "no " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + (reg54 & 0x01) ? "yes" : "no ", + (reg54 & 0x02) ? "yes" : "no ", + (reg54 & 0x04) ? "yes" : "no ", + (reg54 & 0x08) ? "yes" : "no " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + (reg56 & 0x0002) ? "2" : ((reg56 & 0x0001) ? "1" : + ((reg56 & 0x000f) ? "X" : "0")), + (reg56 & 0x0020) ? "2" : ((reg56 & 0x0010) ? "1" : + ((reg56 & 0x00f0) ? "X" : "0")), + (reg56 & 0x0200) ? "2" : ((reg56 & 0x0100) ? "1" : + ((reg56 & 0x0f00) ? "X" : "0")), + (reg56 & 0x2000) ? "2" : ((reg56 & 0x1000) ? "1" : + ((reg56 & 0xf000) ? "X" : "0"))); + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte osb4_proc = 0; + +extern char *ide_xfer_verbose (byte xfer_rate); + +static void osb4_tune_drive (ide_drive_t *drive, byte pio) +{ + /* command/recover widths */ + byte timings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; + int port = HWIF(drive)->index ? 0x42 : 0x40; + + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + if (&HWIF(drive)->drives[0] == drive) /* master drive */ + port++; + pci_write_config_byte(HWIF(drive)->pci_dev, port, timings[pio]); +} + +#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_BLK_DEV_OSB4) +static int osb4_tune_chipset (ide_drive_t *drive, byte speed) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + byte is_slave = (&HWIF(drive)->drives[1] == drive) ? 1 : 0; + byte bit8, enable; + int err; + + /* clear udma register if we don't want udma */ + if (speed < XFER_UDMA_0) { + enable = 0x1 << (is_slave + (hwif->channel ? 2 : 0)); + pci_read_config_byte(dev, 0x54, &bit8); + pci_write_config_byte(dev, 0x54, bit8 & ~enable); + } + +#ifdef CONFIG_BLK_DEV_IDEDMA + if (speed >= XFER_MW_DMA_0) { + byte channel = hwif->channel ? 0x46 : 0x44; + if (!is_slave) + channel++; + + switch (speed) { + case XFER_MW_DMA_0: + bit8 = 0x77; + break; + case XFER_MW_DMA_1: + bit8 = 0x21; + break; + case XFER_MW_DMA_2: + default: + bit8 = 0x20; + break; + } + pci_write_config_byte(dev, channel, bit8); + } + + if (speed >= XFER_UDMA_0) { + byte channel = hwif->channel ? 0x57 : 0x56; + int slave = is_slave ? 4 : 0; + + pci_read_config_byte(dev, channel, &bit8); + bit8 &= ~(0xf << slave); + switch (speed) { + case XFER_UDMA_0: + break; + case XFER_UDMA_1: + bit8 |= 0x1 << slave; + break; + case XFER_UDMA_2: + default: + bit8 |= 0x2 << slave; + break; + } + pci_write_config_byte(dev, channel, bit8); + + enable = 0x1 << (is_slave + (hwif->channel ? 2 : 0)); + pci_read_config_byte(dev, 0x54, &bit8); + pci_write_config_byte(dev, 0x54, bit8 | enable); + } +#endif + +#if OSB4_DEBUG_DRIVE_INFO + printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn); +#endif /* OSB4_DEBUG_DRIVE_INFO */ + if (!drive->init_speed) + drive->init_speed = speed; + err = ide_config_drive_speed(drive, speed); + drive->current_speed = speed; + return err; +} + +static int osb4_config_drive_for_dma (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + byte speed; + + byte udma_66 = eighty_ninty_three(drive); + /* need specs to figure out if osb4 is capable of ata/66/100 */ + int ultra100 = 0; + int ultra66 = 0; + int ultra = 1; + + if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (ultra)) { + speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0008) && (ultra)) { + speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0004) && (ultra)) { + speed = XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0002) && (ultra)) { + speed = XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0001) && (ultra)) { + speed = XFER_UDMA_0; + } else if (id->dma_mword & 0x0004) { + speed = XFER_MW_DMA_2; + } else if (id->dma_mword & 0x0002) { + speed = XFER_MW_DMA_1; + } else if (id->dma_1word & 0x0004) { + speed = XFER_SW_DMA_2; + } else { + speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + } + + (void) osb4_tune_chipset(drive, speed); + + return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : + ((id->dma_ultra >> 8) & 7) ? ide_dma_on : + ((id->dma_mword >> 8) & 7) ? ide_dma_on : + ((id->dma_1word >> 8) & 7) ? ide_dma_on : + ide_dma_off_quietly); +} + +static int osb4_dmaproc(ide_dma_action_t func, ide_drive_t *drive) +{ + switch (func) { + case ide_dma_check: + return ide_dmaproc((ide_dma_action_t) osb4_config_drive_for_dma(drive), drive); + default : + break; + } + /* Other cases are done by generic IDE-DMA code. */ + return ide_dmaproc(func, drive); +} +#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_BLK_DEV_OSB4) */ + +unsigned int __init pci_init_osb4 (struct pci_dev *dev, const char *name) +{ + u16 word; + byte bit8; + + pci_read_config_byte(dev, PCI_REVISION_ID, &osb4_revision); + + /* setup command register. just make sure that bus master and + * i/o ports are on. */ + pci_read_config_word(dev, PCI_COMMAND, &word); + if ((word & (PCI_COMMAND_MASTER | PCI_COMMAND_IO)) != + (PCI_COMMAND_MASTER | PCI_COMMAND_IO)) + pci_write_config_word(dev, PCI_COMMAND, word | + PCI_COMMAND_MASTER | PCI_COMMAND_IO); + + /* make sure that we're in pci native mode for both the primary + * and secondary channel. */ + pci_read_config_byte(dev, PCI_CLASS_PROG, &bit8); + if ((bit8 & 0x5) != 0x5) + pci_write_config_byte(dev, PCI_CLASS_PROG, bit8 | 0x5); + + /* setup up our latency. the default is 255 which is a bit large. + * set it to 64 instead. */ + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &bit8); + if (bit8 != 0x40) + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); + +#if defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS) + if (!osb4_proc) { + osb4_proc = 1; + bmide_dev = dev; + osb4_display_info = &osb4_get_info; + } +#endif /* DISPLAY_OSB4_TIMINGS && CONFIG_PROC_FS */ + return 0; +} + +unsigned int __init ata66_osb4 (ide_hwif_t *hwif) +{ + return 0; +} + +void __init ide_init_osb4 (ide_hwif_t *hwif) +{ + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; + + hwif->tuneproc = &osb4_tune_drive; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + + if (!hwif->dma_base) + return; + +#ifndef CONFIG_BLK_DEV_IDEDMA + hwif->autodma = 0; +#else /* CONFIG_BLK_DEV_IDEDMA */ +#ifdef CONFIG_BLK_DEV_OSB4 + hwif->autodma = 1; + hwif->dmaproc = &osb4_dmaproc; + hwif->speedproc = &osb4_tune_chipset; +#endif /* CONFIG_BLK_DEV_OSB4 */ +#endif /* !CONFIG_BLK_DEV_IDEDMA */ +} diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c new file mode 100644 index 000000000..f8e6be4d0 --- /dev/null +++ b/drivers/ide/slc90e66.c @@ -0,0 +1,382 @@ +/* + * linux/drivers/ide/slc90e66.c Version 0.10 October 4, 2000 + * + * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> + * May be copied or modified under the terms of the GNU General Public License + * + * 00:07.1 IDE interface: EFAR Microsystems: + * Unknown device 9130 (prog-if 8a [Master SecP PriP]) + * Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- + * VGASnoop- ParErr- Stepping- SERR- FastB2B- + * Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium + * >TAbort- <TAbort- <MAbort- >SERR- <PERR- + * Latency: 64 + * Interrupt: pin A routed to IRQ 255 + * Region 4: I/O ports at 1050 + * + * 00: 55 10 30 91 05 00 00 02 00 8a 01 01 00 40 00 00 + * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 20: 51 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 30: 00 00 00 00 00 00 00 00 00 00 00 00 ff 01 00 00 + * 40: 37 e3 33 e3 b9 55 01 00 0d 00 04 22 00 00 00 00 + * 50: 00 00 ff a0 00 00 00 08 40 00 00 00 00 00 00 00 + * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * + * This a look-a-like variation of the ICH0 PIIX4 Ultra-66, + * but this keeps the ISA-Bridge and slots alive. + * + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/ioport.h> +#include <linux/pci.h> +#include <linux/hdreg.h> +#include <linux/ide.h> +#include <linux/delay.h> +#include <linux/init.h> + +#include <asm/io.h> + +#include "ide_modes.h" + +#define SLC90E66_DEBUG_DRIVE_INFO 0 + +#define DISPLAY_SLC90E66_TIMINGS + +#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int slc90e66_get_info(char *, char **, off_t, int); +extern int (*slc90e66_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + u32 bibma = pci_resource_start(bmide_dev, 4); + u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0; + u8 c0 = 0, c1 = 0; + u8 reg44 = 0, reg47 = 0, reg48 = 0, reg4a = 0, reg4b = 0; + + pci_read_config_word(bmide_dev, 0x40, ®40); + pci_read_config_word(bmide_dev, 0x42, ®42); + pci_read_config_byte(bmide_dev, 0x44, ®44); + pci_read_config_byte(bmide_dev, 0x47, ®47); + pci_read_config_byte(bmide_dev, 0x48, ®48); + pci_read_config_byte(bmide_dev, 0x4a, ®4a); + pci_read_config_byte(bmide_dev, 0x4b, ®4b); + + psitre = (reg40 & 0x4000) ? 1 : 0; + ssitre = (reg42 & 0x4000) ? 1 : 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + p += sprintf(p, " SLC90E66 Chipset.\n"); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); + p += sprintf(p, "DMA enabled: %s %s %s %s\n", + (c0&0x20) ? "yes" : "no ", + (c0&0x40) ? "yes" : "no ", + (c1&0x20) ? "yes" : "no ", + (c1&0x40) ? "yes" : "no " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + (reg48&0x01) ? "yes" : "no ", + (reg48&0x02) ? "yes" : "no ", + (reg48&0x04) ? "yes" : "no ", + (reg48&0x08) ? "yes" : "no " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + ((reg4a&0x04)==0x04) ? "4" : + ((reg4a&0x03)==0x03) ? "3" : + (reg4a&0x02) ? "2" : + (reg4a&0x01) ? "1" : + (reg4a&0x00) ? "0" : "X", + ((reg4a&0x40)==0x40) ? "4" : + ((reg4a&0x30)==0x30) ? "3" : + (reg4a&0x20) ? "2" : + (reg4a&0x10) ? "1" : + (reg4a&0x00) ? "0" : "X", + ((reg4b&0x04)==0x04) ? "4" : + ((reg4b&0x03)==0x03) ? "3" : + (reg4b&0x02) ? "2" : + (reg4b&0x01) ? "1" : + (reg4b&0x00) ? "0" : "X", + ((reg4b&0x40)==0x40) ? "4" : + ((reg4b&0x30)==0x30) ? "3" : + (reg4b&0x20) ? "2" : + (reg4b&0x10) ? "1" : + (reg4b&0x00) ? "0" : "X"); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + +/* + * FIXME.... Add configuration junk data....blah blah...... + */ + + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) */ + +/* + * Used to set Fifo configuration via kernel command line: + */ + +byte slc90e66_proc = 0; + +extern char *ide_xfer_verbose (byte xfer_rate); + +#ifdef CONFIG_BLK_DEV_IDEDMA +/* + * + */ +static byte slc90e66_dma_2_pio (byte xfer_rate) { + switch(xfer_rate) { + case XFER_UDMA_4: + case XFER_UDMA_3: + case XFER_UDMA_2: + case XFER_UDMA_1: + case XFER_UDMA_0: + case XFER_MW_DMA_2: + case XFER_PIO_4: + return 4; + case XFER_MW_DMA_1: + case XFER_PIO_3: + return 3; + case XFER_SW_DMA_2: + case XFER_PIO_2: + return 2; + case XFER_MW_DMA_0: + case XFER_SW_DMA_1: + case XFER_SW_DMA_0: + case XFER_PIO_1: + case XFER_PIO_0: + case XFER_PIO_SLOW: + default: + return 0; + } +} +#endif /* CONFIG_BLK_DEV_IDEDMA */ + +/* + * Based on settings done by AMI BIOS + * (might be usefull if drive is not registered in CMOS for any reason). + */ +static void slc90e66_tune_drive (ide_drive_t *drive, byte pio) +{ + unsigned long flags; + u16 master_data; + byte slave_data; + int is_slave = (&HWIF(drive)->drives[1] == drive); + int master_port = HWIF(drive)->index ? 0x42 : 0x40; + int slave_port = 0x44; + /* ISP RTC */ + byte timings[][2] = { { 0, 0 }, + { 0, 0 }, + { 1, 0 }, + { 2, 1 }, + { 2, 3 }, }; + + pio = ide_get_best_pio_mode(drive, pio, 5, NULL); + pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data); + if (is_slave) { + master_data = master_data | 0x4000; + if (pio > 1) + /* enable PPE, IE and TIME */ + master_data = master_data | 0x0070; + pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data); + slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0); + slave_data = slave_data | ((timings[pio][0] << 2) | (timings[pio][1] + << (HWIF(drive)->index ? 4 : 0))); + } else { + master_data = master_data & 0xccf8; + if (pio > 1) + /* enable PPE, IE and TIME */ + master_data = master_data | 0x0007; + master_data = master_data | (timings[pio][0] << 12) | + (timings[pio][1] << 8); + } + save_flags(flags); + cli(); + pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data); + if (is_slave) + pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data); + restore_flags(flags); +} + +#ifdef CONFIG_BLK_DEV_IDEDMA +static int slc90e66_tune_chipset (ide_drive_t *drive, byte speed) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + byte maslave = hwif->channel ? 0x42 : 0x40; + int a_speed = 7 << (drive->dn * 4); + int u_flag = 1 << drive->dn; + int u_speed = 0; + int err = 0; + int sitre; + short reg4042, reg44, reg48, reg4a; + + pci_read_config_word(dev, maslave, ®4042); + sitre = (reg4042 & 0x4000) ? 1 : 0; + pci_read_config_word(dev, 0x44, ®44); + pci_read_config_word(dev, 0x48, ®48); + pci_read_config_word(dev, 0x4a, ®4a); + + switch(speed) { + case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; + case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; + case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; + case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; + case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; + case XFER_MW_DMA_2: + case XFER_MW_DMA_1: + case XFER_SW_DMA_2: break; + default: return -1; + } + + if (speed >= XFER_UDMA_0) { + if (!(reg48 & u_flag)) + pci_write_config_word(dev, 0x48, reg48|u_flag); + if ((reg4a & u_speed) != u_speed) { + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + pci_read_config_word(dev, 0x4a, ®4a); + pci_write_config_word(dev, 0x4a, reg4a|u_speed); + } + } + if (speed < XFER_UDMA_0) { + if (reg48 & u_flag) + pci_write_config_word(dev, 0x48, reg48 & ~u_flag); + if (reg4a & a_speed) + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + } + + slc90e66_tune_drive(drive, slc90e66_dma_2_pio(speed)); + +#if SLC90E66_DEBUG_DRIVE_INFO + printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn); +#endif /* SLC90E66_DEBUG_DRIVE_INFO */ + if (!drive->init_speed) + drive->init_speed = speed; + err = ide_config_drive_speed(drive, speed); + drive->current_speed = speed; + return err; +} + +static int slc90e66_config_drive_for_dma (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + int ultra = 1; + byte speed = 0; + byte udma_66 = eighty_ninty_three(drive); + + if ((id->dma_ultra & 0x0010) && (ultra)) { + speed = (udma_66) ? XFER_UDMA_4 : XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0008) && (ultra)) { + speed = (udma_66) ? XFER_UDMA_3 : XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0004) && (ultra)) { + speed = XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0002) && (ultra)) { + speed = XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0001) && (ultra)) { + speed = XFER_UDMA_0; + } else if (id->dma_mword & 0x0004) { + speed = XFER_MW_DMA_2; + } else if (id->dma_mword & 0x0002) { + speed = XFER_MW_DMA_1; + } else if (id->dma_1word & 0x0004) { + speed = XFER_SW_DMA_2; + } else { + speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + } + + (void) slc90e66_tune_chipset(drive, speed); + + return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : + ((id->dma_ultra >> 8) & 7) ? ide_dma_on : + ((id->dma_mword >> 8) & 7) ? ide_dma_on : + ((id->dma_1word >> 8) & 7) ? ide_dma_on : + ide_dma_off_quietly); +} + +static int slc90e66_dmaproc(ide_dma_action_t func, ide_drive_t *drive) +{ + switch (func) { + case ide_dma_check: + return ide_dmaproc((ide_dma_action_t) slc90e66_config_drive_for_dma(drive), drive); + default : + break; + } + /* Other cases are done by generic IDE-DMA code. */ + return ide_dmaproc(func, drive); +} +#endif /* CONFIG_BLK_DEV_IDEDMA */ + +unsigned int __init pci_init_slc90e66 (struct pci_dev *dev, const char *name) +{ +#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) + if (!slc90e66_proc) { + slc90e66_proc = 1; + bmide_dev = dev; + slc90e66_display_info = &slc90e66_get_info; + } +#endif /* DISPLAY_SLC90E66_TIMINGS && CONFIG_PROC_FS */ + return 0; +} + +unsigned int __init ata66_slc90e66 (ide_hwif_t *hwif) +{ +#if 1 + byte reg47 = 0, ata66 = 0; + byte mask = hwif->channel ? 0x02 : 0x01; + + pci_read_config_byte(hwif->pci_dev, 0x47, ®47); + + ata66 = (reg47 & mask) ? 1 : 0; +#else + byte ata66 = 0; +#endif + return ata66; +} + +void __init ide_init_slc90e66 (ide_hwif_t *hwif) +{ + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; + + hwif->tuneproc = &slc90e66_tune_drive; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + + if (!hwif->dma_base) + return; + +#ifndef CONFIG_BLK_DEV_IDEDMA + hwif->autodma = 0; +#else /* CONFIG_BLK_DEV_IDEDMA */ + hwif->autodma = 1; + hwif->dmaproc = &slc90e66_dmaproc; + hwif->speedproc = &slc90e66_tune_chipset; +#endif /* !CONFIG_BLK_DEV_IDEDMA */ +} diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 1c1b68ff2..566dcc4d5 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -1,5 +1,5 @@ /* - * $Id: via82cxxx.c,v 2.1d 2000/10/01 10:01:00 vojtech Exp $ + * $Id: via82cxxx.c,v 2.1e 2000/10/03 10:01:00 vojtech Exp $ * * Copyright (c) 2000 Vojtech Pavlik * @@ -192,7 +192,7 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count) via_print("----------VIA BusMastering IDE Configuration----------------"); - via_print("Driver Version: 2.1d"); + via_print("Driver Version: 2.1e"); pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t); via_print("South Bridge: VIA %s rev %#x", via_isa_bridges[via_config].name, t); @@ -334,8 +334,8 @@ static int via_set_speed(ide_drive_t *drive, byte speed) */ switch(via_isa_bridges[via_config].speed) { - case XFER_UDMA_2: t = via_timing[i].udma ? (0xe0 | (FIT(via_timing[i].udma, 2, 5) - 2)) : 0x03; break; - case XFER_UDMA_4: t = via_timing[i].udma ? (0xe8 | (FIT(via_timing[i].udma, 2, 9) - 2)) : 0x0f; break; + case XFER_UDMA_2: t = via_timing[i].udma ? (0xe0 | (FIT(ENOUGH(via_timing[i].udma, T), 2, 5) - 2)) : 0x03; break; + case XFER_UDMA_4: t = via_timing[i].udma ? (0xe8 | (FIT(ENOUGH(via_timing[i].udma, T/2), 2, 9) - 2)) : 0x0f; break; } if (via_isa_bridges[via_config].speed != XFER_MW_DMA_2) diff --git a/drivers/ieee1394/Config.in b/drivers/ieee1394/Config.in index bdb3002d2..a0c340ba2 100644 --- a/drivers/ieee1394/Config.in +++ b/drivers/ieee1394/Config.in @@ -14,7 +14,8 @@ if [ "$CONFIG_PCI" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then bool ' Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS fi - dep_tristate 'Adaptec AIC-5800 (AHA-89xx) support' CONFIG_IEEE1394_AIC5800 $CONFIG_IEEE1394 +# this driver is unsupported now: +# dep_tristate 'Adaptec AIC-5800 (AHA-89xx) support' CONFIG_IEEE1394_AIC5800 $CONFIG_IEEE1394 dep_tristate 'OHCI (Open Host Controller Interface) support' CONFIG_IEEE1394_OHCI1394 $CONFIG_IEEE1394 dep_tristate 'Video1394 support' CONFIG_IEEE1394_VIDEO1394 $CONFIG_IEEE1394_OHCI1394 diff --git a/drivers/ieee1394/aic5800.c b/drivers/ieee1394/aic5800.c index 2748c21b6..1b649de5e 100644 --- a/drivers/ieee1394/aic5800.c +++ b/drivers/ieee1394/aic5800.c @@ -1,4 +1,6 @@ /* + * +++ THIS DRIVER IS ORPHANED AND UNSUPPORTED +++ + * * aic5800.c - Adaptec AIC-5800 PCI-IEEE1394 chip driver * Copyright (C)1999 Emanuel Pirker <epirker@edu.uni-klu.ac.at> * diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index d10353855..8b4aa7244 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -42,13 +42,13 @@ #endif -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; LIST_HEAD(host_info_list); -static int host_count = 0; +static int host_count; spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED; -static struct hpsb_highlevel *hl_handle = NULL; +static struct hpsb_highlevel *hl_handle; static atomic_t iso_buffer_size; static const int iso_buffer_max = 4 * 1024 * 1024; /* 4 MB */ diff --git a/drivers/input/input.c b/drivers/input/input.c index f3701965e..e121192a6 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -49,12 +49,12 @@ EXPORT_SYMBOL(input_event); #define INPUT_MAJOR 13 #define INPUT_DEVICES 256 -static struct input_dev *input_dev = NULL; -static struct input_handler *input_handler = NULL; -static struct input_handler *input_table[8] = { NULL, /* ... */ }; -static devfs_handle_t input_devfs_handle = NULL; -static int input_number = 0; -static long input_devices[NBITS(INPUT_DEVICES)] = { 0, /* ... */ }; +static struct input_dev *input_dev; +static struct input_handler *input_handler; +static struct input_handler *input_table[8]; +static devfs_handle_t input_devfs_handle; +static int input_number; +static long input_devices[NBITS(INPUT_DEVICES)]; void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { diff --git a/drivers/isdn/avmb1/capifs.c b/drivers/isdn/avmb1/capifs.c index 64ef8436c..d4956c45b 100644 --- a/drivers/isdn/avmb1/capifs.c +++ b/drivers/isdn/avmb1/capifs.c @@ -1,11 +1,14 @@ /* - * $Id: capifs.c,v 1.9 2000/08/20 07:30:13 keil Exp $ + * $Id: capifs.c,v 1.10 2000/10/12 10:12:35 calle Exp $ * * (c) Copyright 2000 by Carsten Paeth (calle@calle.de) * * Heavily based on devpts filesystem from H. Peter Anvin * * $Log: capifs.c,v $ + * Revision 1.10 2000/10/12 10:12:35 calle + * Bugfix: second iput(inode) on umount, destroies a foreign inode. + * * Revision 1.9 2000/08/20 07:30:13 keil * changes for 2.4 * @@ -69,7 +72,7 @@ MODULE_AUTHOR("Carsten Paeth <calle@calle.de>"); -static char *revision = "$Revision: 1.9 $"; +static char *revision = "$Revision: 1.10 $"; struct capifs_ncci { struct inode *inode; @@ -552,6 +555,7 @@ void capifs_free_ncci(char type, unsigned int num) continue; if (np->inode) { inode = np->inode; + np->inode = 0; np->used = 0; inode->i_nlink--; iput(inode); diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c index 54849eab1..471ec549e 100644 --- a/drivers/isdn/hysdn/boardergo.c +++ b/drivers/isdn/hysdn/boardergo.c @@ -459,7 +459,7 @@ ergo_inithardware(hysdn_card * card) request_region(card->iobase + PCI9050_USER_IO, 1, "HYSDN"); ergo_stopcard(card); /* disable interrupts */ if (request_irq(card->irq, ergo_interrupt, SA_SHIRQ, "HYSDN", card)) { - ergo_releasehardware(card); /* return the aquired hardware */ + ergo_releasehardware(card); /* return the acquired hardware */ return (-1); } /* success, now setup the function pointers */ diff --git a/drivers/isdn/isdn_common.c b/drivers/isdn/isdn_common.c index 5dffb2770..ba2c41eb5 100644 --- a/drivers/isdn/isdn_common.c +++ b/drivers/isdn/isdn_common.c @@ -46,7 +46,7 @@ /* Debugflags */ #undef ISDN_DEBUG_STATCALLB -isdn_dev *dev = (isdn_dev *) 0; +isdn_dev *dev; static char *isdn_revision = "$Revision: 1.111 $"; @@ -65,7 +65,7 @@ static char *isdn_audio_revision = ": none $"; extern char *isdn_v110_revision; #ifdef CONFIG_ISDN_DIVERSION -isdn_divert_if *divert_if = NULL; /* interface to diversion module */ +isdn_divert_if *divert_if; /* interface to diversion module */ #endif CONFIG_ISDN_DIVERSION @@ -2260,7 +2260,7 @@ isdn_getrev(const char *revision) #ifdef CONFIG_DEVFS_FS -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static void isdn_register_devfs(int k) { diff --git a/drivers/isdn/sc/debug.c b/drivers/isdn/sc/debug.c index c5312cd83..b1bdf57af 100644 --- a/drivers/isdn/sc/debug.c +++ b/drivers/isdn/sc/debug.c @@ -70,6 +70,6 @@ inline void pullphone(char *dn, char *str) int i = 0; while(dn[i] != ',') - str[i] = dn[i++]; + str[i] = dn[i], i++; str[i] = 0x0; } diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c index e455c074e..e379ae442 100644 --- a/drivers/isdn/sc/init.c +++ b/drivers/isdn/sc/init.c @@ -302,7 +302,7 @@ int init_sc(void) /* * No interrupt could be used */ - pr_debug("Failed to aquire an IRQ line\n"); + pr_debug("Failed to acquire an IRQ line\n"); continue; } diff --git a/drivers/macintosh/macserial.c b/drivers/macintosh/macserial.c index 55cf255b9..6ed94158d 100644 --- a/drivers/macintosh/macserial.c +++ b/drivers/macintosh/macserial.c @@ -2890,17 +2890,13 @@ static int __init serial_console_setup(struct console *co, char *options) } static struct console sercons = { - "ttyS", - serial_console_write, - NULL, - serial_console_device, - serial_console_wait_key, - NULL, - serial_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/drivers/md/md.c b/drivers/md/md.c index 4e82a5814..c89314c78 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -60,7 +60,7 @@ extern asmlinkage long sys_setsid(void); # define dprintk(x...) do { } while(0) #endif -static mdk_personality_t *pers[MAX_PERSONALITY] = {NULL, }; +static mdk_personality_t *pers[MAX_PERSONALITY]; /* * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit' @@ -105,12 +105,12 @@ struct hd_struct md_hd_struct[MAX_MD_DEVS]; static int md_blocksizes[MAX_MD_DEVS]; static int md_hardsect_sizes[MAX_MD_DEVS]; static int md_maxreadahead[MAX_MD_DEVS]; -static mdk_thread_t *md_recovery_thread = NULL; +static mdk_thread_t *md_recovery_thread; -int md_size[MAX_MD_DEVS] = {0, }; +int md_size[MAX_MD_DEVS]; extern struct block_device_operations md_fops; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static struct gendisk md_gendisk= { @@ -136,7 +136,7 @@ static MD_LIST_HEAD(all_mddevs); * one! Eg. HSM uses several sub-devices to implement Logical * Volumes. All these sub-devices map to the same mddev. */ -dev_mapping_t mddev_map [MAX_MD_DEVS] = { {NULL, 0}, }; +dev_mapping_t mddev_map[MAX_MD_DEVS]; void add_mddev_mapping (mddev_t * mddev, kdev_t dev, void *data) { @@ -2032,7 +2032,7 @@ void md_setup_drive(void) md__init; * at boot time. */ #ifdef CONFIG_AUTODETECT_RAID -static int detected_devices[128] md__initdata; +static int detected_devices[128] md__initdata = { 0, }; static int dev_cnt=0; void md_autodetect_dev(kdev_t dev) { @@ -3640,7 +3640,7 @@ struct { int pers[MAX_MD_BOOT_DEVS]; int chunk[MAX_MD_BOOT_DEVS]; kdev_t devices[MAX_MD_BOOT_DEVS][MAX_REAL]; -} md_setup_args md__initdata; +} md_setup_args md__initdata = { 0, }; /* * Parse the command-line parameters given our kernel, but do not diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 488091310..6b8c9063f 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -25,6 +25,10 @@ * Added I2C_DRIVERID_TDA7432 * added loudness insmod control * Revision: 0.1 - initial version + * + * Changes: + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/14/2000 + * - resource allocation fixes in tda7432_attach */ #include <linux/module.h> @@ -320,8 +324,10 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, client->addr = addr; client->data = t = kmalloc(sizeof *t,GFP_KERNEL); - if (!t) + if (!t) { + kfree(client); return -ENOMEM; + } memset(t,0,sizeof *t); do_tda7432_init(client); MOD_INC_USE_COUNT; diff --git a/drivers/media/video/tda8425.c b/drivers/media/video/tda8425.c index a1dec22eb..54f1935b6 100644 --- a/drivers/media/video/tda8425.c +++ b/drivers/media/video/tda8425.c @@ -13,6 +13,10 @@ * two stereo inputs, so if someone has this card, could they tell me if the * second one can be used for anything (i.e., does it have an external input * that you can't hear even if you set input to composite?) + * + * Changes: + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/14/2000 + * - resource allocation fixes in tda8425_attach */ #include <linux/module.h> @@ -148,8 +152,10 @@ static int tda8425_attach(struct i2c_adapter *adap, int addr, client->addr = addr; client->data = tda = kmalloc(sizeof *tda,GFP_KERNEL); - if (!tda) + if (!tda) { + kfree(client); return -ENOMEM; + } memset(tda,0,sizeof *tda); do_tda8425_init(client); MOD_INC_USE_COUNT; diff --git a/drivers/media/video/tda985x.c b/drivers/media/video/tda985x.c index 73fb9bd52..2bf161827 100644 --- a/drivers/media/video/tda985x.c +++ b/drivers/media/video/tda985x.c @@ -11,6 +11,9 @@ * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) * Which was based on tda8425.c by Greg Alexander (c) 1998 * + * Contributors: + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> + * * OPTIONS: * debug - set to 1 if you'd like to see debug messages * - set to 2 if you'd like to be flooded with debug messages @@ -22,6 +25,7 @@ * Fine tune sound * Get rest of capabilities into video_audio struct... * + * Revision 0.6 - resource allocation fixes in tda985x_attach (08/14/2000) * Revision 0.5 - cleaned up debugging messages, added debug level=2 * Revision: 0.4 - check for correct chip= insmod value * also cleaned up comments a bit @@ -350,8 +354,10 @@ static int tda985x_attach(struct i2c_adapter *adap, int addr, client->addr = addr; client->data = t = kmalloc(sizeof *t,GFP_KERNEL); - if (!t) + if (!t) { + kfree(client); return -ENOMEM; + } memset(t,0,sizeof *t); do_tda985x_init(client); MOD_INC_USE_COUNT; diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 9f6ecd332..7bfc319a6 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -11,9 +11,13 @@ * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) * Which was based on tda8425.c by Greg Alexander (c) 1998 * + * Contributors: + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.2) + * * OPTIONS: * debug - set to 1 if you'd like to see debug messages * + * Revision 0.2 - resource allocation fixes in tda9875_attach (08/14/2000) * Revision: 0.1 - original version */ @@ -232,8 +236,10 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, client->addr = addr; client->data = t = kmalloc(sizeof *t,GFP_KERNEL); - if (!t) + if (!t) { + kfree(client); return -ENOMEM; + } memset(t,0,sizeof *t); do_tda9875_init(client); MOD_INC_USE_COUNT; diff --git a/drivers/media/video/tea6300.c b/drivers/media/video/tea6300.c index f5949c94f..9dc13e610 100644 --- a/drivers/media/video/tea6300.c +++ b/drivers/media/video/tea6300.c @@ -15,6 +15,10 @@ * balance (different left,right values) and, if someone ever finds a card * with the support (or if you're careful with a soldering iron), fade * (front/back). + * + * Changes: + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/14/2000 + * - resource allocation fixes in tea6300_attach */ #include <linux/module.h> @@ -170,8 +174,10 @@ static int tea6300_attach(struct i2c_adapter *adap, int addr, client->addr = addr; client->data = tea = kmalloc(sizeof *tea,GFP_KERNEL); - if (!tea) + if (!tea) { + kfree(client); return -ENOMEM; + } memset(tea,0,sizeof *tea); do_tea6300_init(client); diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index ad9178ab9..76602ac54 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -218,10 +218,6 @@ struct net_local * The boilerplate probe code. */ -#ifdef HAVE_DEVLIST -struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist}; -#else - /** * el1_probe: * @dev: The device structure passed in to probe. @@ -246,17 +242,11 @@ int __init el1_probe(struct net_device *dev) return -ENXIO; for (i = 0; netcard_portlist[i]; i++) - { - int ioaddr = netcard_portlist[i]; - if (check_region(ioaddr, EL1_IO_EXTENT)) - continue; - if (el1_probe1(dev, ioaddr) == 0) + if (el1_probe1(dev, netcard_portlist[i]) == 0) return 0; - } return -ENODEV; } -#endif /** * el1_probe: diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index 3aa8cc8f8..06745646c 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -62,15 +62,6 @@ static unsigned int netcard_portlist[] __initdata = #define EL2_IO_EXTENT 16 -#ifdef HAVE_DEVLIST -/* The 3c503 uses two entries, one for the safe memory-mapped probe and - the other for the typical I/O probe. */ -struct netdev_entry el2_drv = -{"3c503", el2_probe, EL1_IO_EXTENT, 0}; -struct netdev_entry el2pio_drv = -{"3c503pio", el2_pioprobe1, EL1_IO_EXTENT, netcard_portlist}; -#endif - static int el2_open(struct net_device *dev); static int el2_close(struct net_device *dev); static void el2_reset_8390(struct net_device *dev); @@ -115,14 +106,13 @@ el2_probe(struct net_device *dev) if (el2_probe1(dev, netcard_portlist[i]) == 0) return 0; } -#if ! defined(no_probe_nonshared_memory) && ! defined (HAVE_DEVLIST) +#if ! defined(no_probe_nonshared_memory) return el2_pio_probe(dev); #else return -ENODEV; #endif } -#ifndef HAVE_DEVLIST /* Try all of the locations that aren't obviously empty. This touches a lot of locations, and is much riskier than the code above. */ int __init @@ -146,7 +136,6 @@ el2_pio_probe(struct net_device *dev) return -ENODEV; } -#endif /* Probe for the Etherlink II card at I/O port base IOADDR, returning non-zero on success. If found, set the station @@ -186,15 +175,6 @@ el2_probe1(struct net_device *dev, int ioaddr) return -ENODEV; } - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("3c503.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - - if (!dev) - return -ENOMEM; - } - if (ei_debug && version_printed++ == 0) printk(version); diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index ba6d5839a..22485f1d8 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -1302,8 +1302,8 @@ static int __init elp_sense(struct net_device *dev) long flags; byte orig_HSR; - if (check_region(addr, 0xf)) - return -1; + if (!request_region(addr, ELP_IO_EXTENT, "3c505")) + return -ENODEV; orig_HSR = inb_status(addr); @@ -1313,7 +1313,7 @@ static int __init elp_sense(struct net_device *dev) if (orig_HSR == 0xff) { if (elp_debug > 0) printk(notfound_msg, 1); - return -1; + goto out; } /* Enable interrupts - we need timers! */ save_flags(flags); @@ -1332,7 +1332,7 @@ static int __init elp_sense(struct net_device *dev) if (inb_status(addr) & DIR) { if (elp_debug > 0) printk(notfound_msg, 2); - return -1; + goto out; } } else { /* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */ @@ -1343,7 +1343,7 @@ static int __init elp_sense(struct net_device *dev) if (!(inb_status(addr) & DIR)) { if (elp_debug > 0) printk(notfound_msg, 3); - return -1; + goto out; } } /* @@ -1353,6 +1353,9 @@ static int __init elp_sense(struct net_device *dev) printk(found_msg); return 0; +out: + release_region(addr, ELP_IO_EXTENT); + return -ENODEV; } /************************************************************* @@ -1503,6 +1506,7 @@ int __init elplus_probe(struct net_device *dev) outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev); } printk("%s: failed to initialise 3c505\n", dev->name); + release_region(dev->base_addr, ELP_IO_EXTENT); return -ENODEV; okay: @@ -1593,10 +1597,6 @@ int __init elplus_probe(struct net_device *dev) if (adapter->rx_pcb.data.configure) { printk("%s: adapter configuration failed\n", dev->name); } - /* - * and reserve the address region - */ - request_region(dev->base_addr, ELP_IO_EXTENT, "3c505"); /* * initialise the device diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index e549336fa..b792c4dd1 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -295,11 +295,6 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length static void init_82586_mem(struct net_device *dev); -#ifdef HAVE_DEVLIST -struct netdev_entry netcard_drv = -{"3c507", el16_probe1, EL16_IO_EXTENT, netcard_portlist}; -#endif - /* Check for a network adaptor of this type, and return '0' iff one exists. If dev->base_addr == 0, probe all likely locations. If dev->base_addr == 1, always return failure. @@ -317,13 +312,9 @@ int __init el16_probe(struct net_device *dev) else if (base_addr != 0) return -ENXIO; /* Don't probe at all. */ - for (i = 0; netcard_portlist[i]; i++) { - int ioaddr = netcard_portlist[i]; - if (check_region(ioaddr, EL16_IO_EXTENT)) - continue; - if (el16_probe1(dev, ioaddr) == 0) + for (i = 0; netcard_portlist[i]; i++) + if (el16_probe1(dev, netcard_portlist[i]) == 0) return 0; - } return -ENODEV; } @@ -331,7 +322,7 @@ int __init el16_probe(struct net_device *dev) static int __init el16_probe1(struct net_device *dev, int ioaddr) { static unsigned char init_ID_done = 0, version_printed = 0; - int i, irq, irqval; + int i, irq, irqval, retval; struct net_local *lp; if (init_ID_done == 0) { @@ -348,15 +339,14 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) init_ID_done = 1; } - if (inb(ioaddr) == '*' && inb(ioaddr+1) == '3' - && inb(ioaddr+2) == 'C' && inb(ioaddr+3) == 'O') - ; - else + if (!request_region(ioaddr, EL16_IO_EXTENT, "3c507")) return -ENODEV; - /* Allocate a new 'dev' if needed. */ - if (dev == NULL) - dev = init_etherdev(0, 0); + if ((inb(ioaddr) != '*') || (inb(ioaddr + 1) != '3') || + (inb(ioaddr + 2) != 'C') || (inb(ioaddr + 3) != 'O')) { + retval = -ENODEV; + goto out; + } if (net_debug && version_printed++ == 0) printk(version); @@ -371,11 +361,11 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) irqval = request_irq(irq, &el16_interrupt, 0, "3c507", dev); if (irqval) { printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval); - return -EAGAIN; + retval = -EAGAIN; + goto out; } /* We've committed to using the board, and can start filling in *dev. */ - request_region(ioaddr, EL16_IO_EXTENT, "3c507"); dev->base_addr = ioaddr; outb(0x01, ioaddr + MISC_CTRL); @@ -419,8 +409,10 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) /* Initialize the device structure. */ lp = dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; + if (dev->priv == NULL) { + retval = -ENOMEM; + goto out; + } memset(dev->priv, 0, sizeof(struct net_local)); spin_lock_init(&lp->lock); @@ -436,6 +428,9 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) dev->flags&=~IFF_MULTICAST; /* Multicast doesn't work */ return 0; +out: + release_region(ioaddr, EL16_IO_EXTENT); + return retval; } static int el16_open(struct net_device *dev) @@ -862,12 +857,7 @@ static void el16_rx(struct net_device *dev) lp->rx_tail = rx_tail; } #ifdef MODULE -static struct net_device dev_3c507 = { - "", /* device name is inserted by linux/drivers/net/net_init.c */ - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, el16_probe -}; +static struct net_device dev_3c507 = { init: el16_probe }; static int io = 0x300; static int irq = 0; diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 0e91f92d0..ae3523a7c 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -173,7 +173,7 @@ struct el3_isapnp_adapters_struct { unsigned short vendor, function; char *name; }; -struct el3_isapnp_adapters_struct el3_isapnp_adapters[] = { +static struct el3_isapnp_adapters_struct el3_isapnp_adapters[] = { {ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090), "3Com Etherlink III (TP)"}, {ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5091), "3Com Etherlink III"}, {ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5094), "3Com Etherlink III (combo)"}, @@ -182,13 +182,10 @@ struct el3_isapnp_adapters_struct el3_isapnp_adapters[] = { {ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f8), "3Com Etherlink III compatible"}, {0, } }; -u16 el3_isapnp_phys_addr[8][3] = { - {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, - {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} -}; +static u16 el3_isapnp_phys_addr[8][3]; #endif /* CONFIG_ISAPNP */ #ifdef __ISAPNP__ -static int nopnp = 0; +static int nopnp; #endif int el3_probe(struct net_device *dev) @@ -437,13 +434,6 @@ no_pnp: /* Free the interrupt so that some other card can use it. */ outw(0x0f00, ioaddr + WN0_IRQ); found: - if (dev == NULL) { - dev = init_etherdev(dev, sizeof(struct el3_private)); - if (dev == NULL) { - release_region(ioaddr, EL3_IO_EXTENT); - return -ENOMEM; - } - } memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); dev->base_addr = ioaddr; dev->irq = irq; diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 32e15dd44..da7d27ac5 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -90,7 +90,7 @@ MODULE_PARM(max_interrupt_work, "i"); #define DRIVER_DEBUG 1 /* Some values here only for performance evaluation and path-coverage debugging. */ -static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0; +static int rx_nocopy, rx_copy, queued_packet; /* Number of times to check to see if the Tx FIFO has space, used in some limited cases. */ @@ -364,7 +364,7 @@ int corkscrew_isapnp_phys_addr[3] = { 0, 0, 0 }; -static int nopnp = 0; +static int nopnp; #endif static int corkscrew_scan(struct net_device *dev); diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index d065c3273..2a8f82e83 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -272,19 +272,6 @@ static int __init mc32_probe1(struct net_device *dev, int slot) return -ENODEV; } - /* - * Don't allocate the private data here, it is done later - * This makes it easier to free the memory when this driver - * is used as a module. - */ - - if(dev==NULL) - { - dev = init_etherdev(0, 0); - if (dev == NULL) - return -ENOMEM; - } - /* Fill in the 'dev' fields. */ dev->base_addr = mca_io_bases[(POS>>1)&7]; dev->mem_start = mca_mem_bases[(POS>>4)&7]; @@ -1457,11 +1444,7 @@ static void mc32_reset_multicast_list(struct net_device *dev) #ifdef MODULE -static struct net_device this_device = { - "", /* will be inserted by linux/drivers/net/mc32_init.c */ - 0, 0, 0, 0, - 0, 0, /* I/O address, IRQ */ - 0, 0, 0, NULL, mc32_probe }; +static struct net_device this_device = { init: mc32_probe }; /** diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index c62617f55..1eefdfb71 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -222,7 +222,7 @@ MODULE_PARM(watchdog, "i"); /* Set iff a MII transceiver on any interface requires mdio preamble. This only set with the original DP83840 on older 3c905 boards, so the extra code size of a per-interface flag is not worthwhile. */ -static char mii_preamble_required = 0; +static char mii_preamble_required; #define PFX "3c59x: " @@ -740,12 +740,12 @@ static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* #define dev_alloc_skb dev_alloc_skb_debug */ /* A list of all installed Vortex EISA devices, for removing the driver module. */ -static struct net_device *root_vortex_eisa_dev = NULL; +static struct net_device *root_vortex_eisa_dev; /* Variables to work-around the Compaq PCI BIOS32 problem. */ -static int compaq_ioaddr = 0, compaq_irq = 0, compaq_device_id = 0x5900; +static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900; -static int vortex_cards_found = 0; +static int vortex_cards_found; static void vortex_suspend (struct pci_dev *pdev) { @@ -853,7 +853,7 @@ static int __devinit vortex_probe1(struct pci_dev *pdev, unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */ int i; struct net_device *dev; - static int printed_version = 0; + static int printed_version; int retval; struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx]; @@ -1616,7 +1616,7 @@ vortex_error(struct net_device *dev, int status) outw(AckIntr | RxEarly, ioaddr + EL3_CMD); } if (status & StatsFull) { /* Empty statistics. */ - static int DoneDidThat = 0; + static int DoneDidThat; if (vortex_debug > 4) printk(KERN_DEBUG "%s: Updating stats.\n", dev->name); update_stats(ioaddr, dev); @@ -2573,8 +2573,8 @@ static struct pci_driver vortex_driver = { }; -static int vortex_have_pci = 0; -static int vortex_have_eisa = 0; +static int vortex_have_pci; +static int vortex_have_eisa; static int __init vortex_init (void) diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index bbd2f0fac..f47ee2462 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -70,6 +70,10 @@ Martin Dennett - incredibly helpful insight on undocumented features of the 8139 chips + Jean-Jacques Michel - bug fix + + Tobias - Rx interrupt status checking suggestion + Submitting bug reports: "rtl8139-diag -mmmaaavvveefN" output @@ -141,7 +145,7 @@ an MMIO register read. #include <asm/io.h> -#define RTL8139_VERSION "0.9.10" +#define RTL8139_VERSION "0.9.11" #define RTL8139_MODULE_NAME "8139too" #define RTL8139_DRIVER_NAME RTL8139_MODULE_NAME " Fast Ethernet driver " RTL8139_VERSION #define PFX RTL8139_MODULE_NAME ": " @@ -174,8 +178,6 @@ an MMIO register read. } #endif -#define arraysize(x) (sizeof(x)/sizeof(*(x))) - /* A few user-configurable values. */ /* media options */ @@ -198,8 +200,11 @@ static int multicast_filter_limit = 32; /* Number of Tx descriptor registers. */ #define NUM_TX_DESC 4 +/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/ +#define MAX_ETH_FRAME_SIZE 1536 + /* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */ -#define TX_BUF_SIZE 1536 +#define TX_BUF_SIZE MAX_ETH_FRAME_SIZE #define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC) /* PCI Tuning Parameters @@ -552,7 +557,7 @@ static void rtl8139_hw_start (struct net_device *dev); #define RTL_R8(reg) inb (((unsigned long)ioaddr) + (reg)) #define RTL_R16(reg) inw (((unsigned long)ioaddr) + (reg)) -#define RTL_R32(reg) inl (((unsigned long)ioaddr) + (reg)) +#define RTL_R32(reg) ((unsigned long) inl (((unsigned long)ioaddr) + (reg))) #define RTL_W8(reg, val8) outb ((val8), ((unsigned long)ioaddr) + (reg)) #define RTL_W16(reg, val16) outw ((val16), ((unsigned long)ioaddr) + (reg)) #define RTL_W32(reg, val32) outl ((val32), ((unsigned long)ioaddr) + (reg)) @@ -600,7 +605,7 @@ static void rtl8139_hw_start (struct net_device *dev); /* read MMIO register */ #define RTL_R8(reg) readb (ioaddr + (reg)) #define RTL_R16(reg) readw (ioaddr + (reg)) -#define RTL_R32(reg) readl (ioaddr + (reg)) +#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) #endif /* USE_IO_OPS */ @@ -677,8 +682,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, } /* check for weird/broken PCI region reporting */ - if ((pio_len != mmio_len) || - (pio_len < RTL_MIN_IO_SIZE) || + if ((pio_len < RTL_MIN_IO_SIZE) || (mmio_len < RTL_MIN_IO_SIZE)) { printk (KERN_ERR PFX "Invalid PCI region size(s), aborting\n"); rc = -ENODEV; @@ -761,7 +765,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, /* identify chip attached to board */ tmp = RTL_R8 (ChipVersion); - for (i = arraysize (rtl_chip_info) - 1; i >= 0; i--) + for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--) if (tmp == rtl_chip_info[i].version) { tp->chipset = i; goto match; @@ -770,7 +774,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, /* if unknown chip, assume array element #0, original RTL-8139 in this case */ printk (KERN_DEBUG PFX "PCI device %s: unknown chip version, assuming RTL-8139\n", pdev->slot_name); - printk (KERN_DEBUG PFX "PCI device %s: TxConfig = 0x%x\n", pdev->slot_name, RTL_R32 (TxConfig)); + printk (KERN_DEBUG PFX "PCI device %s: TxConfig = 0x%lx\n", pdev->slot_name, RTL_R32 (TxConfig)); tp->chipset = 0; match: @@ -1464,11 +1468,36 @@ static void rtl8139_timer (unsigned long data) } +static void rtl8139_tx_clear (struct rtl8139_private *tp) +{ + int i; + + atomic_set (&tp->cur_tx, 0); + atomic_set (&tp->dirty_tx, 0); + + /* Dump the unsent Tx packets. */ + for (i = 0; i < NUM_TX_DESC; i++) { + struct ring_info *rp = &tp->tx_info[i]; + if (rp->mapping != 0) { + pci_unmap_single (tp->pci_dev, rp->mapping, + rp->skb->len, PCI_DMA_TODEVICE); + rp->mapping = 0; + } + if (rp->skb) { + dev_kfree_skb (rp->skb); + rp->skb = NULL; + tp->stats.tx_dropped++; + } + } +} + + static void rtl8139_tx_timeout (struct net_device *dev) { struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv; void *ioaddr = tp->mmio_addr; int i; + u8 tmp8; unsigned long flags; DPRINTK ("%s: Transmit timeout, status %2.2x %4.4x " @@ -1477,6 +1506,11 @@ static void rtl8139_tx_timeout (struct net_device *dev) RTL_R16 (IntrStatus), RTL_R8 (MediaStatus)); + /* disable Tx ASAP, if not already */ + tmp8 = RTL_R8 (ChipCmd); + if (tmp8 & CmdTxEnb) + RTL_W8 (ChipCmd, tmp8 & ~CmdTxEnb); + /* Disable interrupts by clearing the interrupt mask. */ RTL_W16 (IntrMask, 0x0000); @@ -1485,31 +1519,15 @@ static void rtl8139_tx_timeout (struct net_device *dev) dev->name, atomic_read (&tp->cur_tx), atomic_read (&tp->dirty_tx)); for (i = 0; i < NUM_TX_DESC; i++) - printk (KERN_DEBUG "%s: Tx descriptor %d is %8.8x.%s\n", + printk (KERN_DEBUG "%s: Tx descriptor %d is %8.8lx.%s\n", dev->name, i, RTL_R32 (TxStatus0 + (i * 4)), i == atomic_read (&tp->dirty_tx) % NUM_TX_DESC ? " (queue head)" : ""); - spin_lock_irqsave (&tp->lock, flags); - /* Stop a shared interrupt from scavenging while we are. */ - atomic_set (&tp->cur_tx, 0); - atomic_set (&tp->dirty_tx, 0); - - /* Dump the unsent Tx packets. */ - for (i = 0; i < NUM_TX_DESC; i++) { - struct ring_info *rp = &tp->tx_info[i]; - if (rp->mapping != 0) { - pci_unmap_single (tp->pci_dev, rp->mapping, - rp->skb->len, PCI_DMA_TODEVICE); - rp->mapping = 0; - } - if (rp->skb) { - dev_kfree_skb (rp->skb); - rp->skb = NULL; - tp->stats.tx_dropped++; - } - } + spin_lock_irqsave (&tp->lock, flags); + + rtl8139_tx_clear (tp); spin_unlock_irqrestore (&tp->lock, flags); @@ -1551,11 +1569,11 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) } -static inline void rtl8139_tx_interrupt (struct net_device *dev, - struct rtl8139_private *tp, - void *ioaddr) +static void rtl8139_tx_interrupt (struct net_device *dev, + struct rtl8139_private *tp, + void *ioaddr) { - unsigned int dirty_tx; + int cur_tx, dirty_tx, tx_left; assert (dev != NULL); assert (tp != NULL); @@ -1563,7 +1581,9 @@ static inline void rtl8139_tx_interrupt (struct net_device *dev, dirty_tx = atomic_read (&tp->dirty_tx); - while ((atomic_read (&tp->cur_tx) - dirty_tx) > 0) { + cur_tx = atomic_read (&tp->cur_tx); + tx_left = cur_tx - dirty_tx; + while (tx_left > 0) { int entry = dirty_tx % NUM_TX_DESC; int txstatus; @@ -1609,12 +1629,20 @@ static inline void rtl8139_tx_interrupt (struct net_device *dev, tp->tx_info[entry].skb->len, PCI_DMA_TODEVICE); tp->tx_info[entry].mapping = 0; - } dev_kfree_skb_irq (tp->tx_info[entry].skb); + } + dev_kfree_skb_irq (tp->tx_info[entry].skb); tp->tx_info[entry].skb = NULL; dirty_tx++; - if (netif_queue_stopped (dev) && - (atomic_read (&tp->cur_tx) - dirty_tx < NUM_TX_DESC)) + if (dirty_tx < 0) { /* handle signed int overflow */ + atomic_sub (cur_tx, &tp->cur_tx); /* XXX racy? */ + dirty_tx = cur_tx - tx_left + 1; + } + if (netif_queue_stopped (dev)) netif_wake_queue (dev); + + cur_tx = atomic_read (&tp->cur_tx); + tx_left = cur_tx - dirty_tx; + } #ifndef RTL8139_NDEBUG @@ -1702,10 +1730,15 @@ static void rtl8139_rx_interrupt (struct net_device *dev, while ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0) { int ring_offset = cur_rx % RX_BUF_LEN; - u32 rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset)); - int rx_size = rx_status >> 16; + u32 rx_status; + unsigned int rx_size; + unsigned int pkt_size; struct sk_buff *skb; - int pkt_size = rx_size - 4; + + /* read size+status of next frame from DMA ring buffer */ + rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset)); + 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, @@ -1733,11 +1766,13 @@ static void rtl8139_rx_interrupt (struct net_device *dev, if (rx_size == 0xfff0) break; - /* if Rx err received, Rx process gets reset, so - * we abort any further Rx processing + /* If Rx err or invalid rx_size/rx_status received + * (which happens if we get lost in the ring), + * Rx process gets reset, so we abort any further + * Rx processing. */ - if (rx_status & - (RxBadSymbol | RxRunt | RxTooLong | RxCRCErr | RxBadAlign)) { + if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) || + (!(rx_status & RxStatusOK))) { rtl8139_rx_err (rx_status, dev, tp, ioaddr); return; } @@ -1752,23 +1787,23 @@ static void rtl8139_rx_interrupt (struct net_device *dev, */ skb = dev_alloc_skb (pkt_size + 2); - if (skb == NULL) { + if (skb) { + skb->dev = dev; + skb_reserve (skb, 2); /* 16 byte align the IP fields. */ + + eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0); + skb_put (skb, pkt_size); + + skb->protocol = eth_type_trans (skb, dev); + netif_rx (skb); + tp->stats.rx_bytes += pkt_size; + tp->stats.rx_packets++; + } else { printk (KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); tp->stats.rx_dropped++; - break; } - skb->dev = dev; - skb_reserve (skb, 2); /* 16 byte align the IP fields. */ - - eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0); - skb_put (skb, pkt_size); - - skb->protocol = eth_type_trans (skb, dev); - netif_rx (skb); - tp->stats.rx_bytes += pkt_size; - tp->stats.rx_packets++; cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; RTL_W16_F (RxBufPtr, cur_rx - 16); @@ -1809,9 +1844,12 @@ static void rtl8139_weird_interrupt (struct net_device *dev, tp->full_duplex = duplex; RTL_W8 (Cfg9346, Cfg9346_Unlock); RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20); + RTL_W8 (Cfg9346, Cfg9346_Lock); } status &= ~RxUnderrun; } + + /* XXX along with rtl8139_rx_err, are we double-counting errors? */ if (status & (RxUnderrun | RxOverflow | RxErr | RxFIFOOver)) tp->stats.rx_errors++; @@ -1926,7 +1964,6 @@ static int rtl8139_close (struct net_device *dev) { struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv; void *ioaddr = tp->mmio_addr; - int i; unsigned long flags; DPRINTK ("ENTER\n"); @@ -1940,36 +1977,22 @@ static int rtl8139_close (struct net_device *dev) spin_lock_irqsave (&tp->lock, flags); - /* Disable interrupts by clearing the interrupt mask. */ - RTL_W16 (IntrMask, 0x0000); - /* Stop the chip's Tx and Rx DMA processes. */ RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear)); + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16 (IntrMask, 0x0000); + /* Update the error counts. */ tp->stats.rx_missed_errors += RTL_R32 (RxMissed); RTL_W32 (RxMissed, 0); spin_unlock_irqrestore (&tp->lock, flags); - /* snooze for a small bit */ - if (current->need_resched) - schedule (); - + synchronize_irq (); free_irq (dev->irq, dev); - for (i = 0; i < NUM_TX_DESC; i++) { - struct sk_buff *skb = tp->tx_info[i].skb; - dma_addr_t mapping = tp->tx_info[i].mapping; - - if (skb) { - if (mapping) - pci_unmap_single (tp->pci_dev, mapping, skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb (skb); - } - tp->tx_info[i].skb = NULL; - tp->tx_info[i].mapping = 0; - } + rtl8139_tx_clear (tp); pci_free_consistent(tp->pci_dev, RX_BUF_TOT_LEN, tp->rx_ring, tp->rx_ring_dma); diff --git a/drivers/net/82596.c b/drivers/net/82596.c index dfb1186ec..24cad4416 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -1488,20 +1488,8 @@ static void set_multicast_list(struct net_device *dev) } } -#ifdef HAVE_DEVLIST -static unsigned int i596_portlist[] __initdata = -{0x300, 0}; -struct netdev_entry i596_drv = -{"i82596", i82596_probe, I596_TOTAL_SIZE, i596_portlist}; -#endif - #ifdef MODULE -static struct net_device dev_82596 = -{ - "", /* device name inserted by drivers/net/net_init.c */ - 0, 0, 0, 0, - 0, 0, /* base, irq */ - 0, 0, 0, NULL, i82596_probe}; +static struct net_device dev_82596 = { init: i82596_probe }; #ifdef ENABLE_APRICOT static int io = 0x300; diff --git a/drivers/net/8390.h b/drivers/net/8390.h index 6c8a68ecc..9db9fdb3c 100644 --- a/drivers/net/8390.h +++ b/drivers/net/8390.h @@ -1,6 +1,6 @@ /* Generic NS8390 register definitions. */ /* This file is part of Donald Becker's 8390 drivers, and is distributed - under the same license. Auto-loading of 8390.o added by Paul Gortmaker. + under the same license. Auto-loading of 8390.o only in v2.2 - Paul G. Some of these names and comments originated from the Crynwr packet drivers, which are distributed under the GPL. */ @@ -12,11 +12,6 @@ #include <linux/ioport.h> #include <linux/skbuff.h> -/* With kmod, drivers can now load the 8390 module themselves! */ -#if 0 /* def CONFIG_KMOD */ -#define LOAD_8390_BY_KMOD -#endif - #define TX_2X_PAGES 12 #define TX_1X_PAGES 6 @@ -50,113 +45,16 @@ extern void autoirq_setup(int waittime); extern unsigned long autoirq_report(int waittime); #endif -#if defined(LOAD_8390_BY_KMOD) && defined(MODULE) && !defined(NS8390_CORE) - -/* Function pointers to be mapped onto the 8390 core support */ -static int (*S_ethdev_init)(struct net_device *dev); -static void (*S_NS8390_init)(struct net_device *dev, int startp); -static int (*S_ei_open)(struct net_device *dev); -static int (*S_ei_close)(struct net_device *dev); -static void (*S_ei_interrupt)(int irq, void *dev_id, struct pt_regs *regs); - -extern __inline__ void unload_8390_module(void) -{ - if (S_ethdev_init) { - put_module_symbol((unsigned long)S_ethdev_init); - S_ethdev_init = NULL; - } - if (S_NS8390_init) { - put_module_symbol((unsigned long)S_NS8390_init); - S_NS8390_init = NULL; - } - if (S_ei_open) { - put_module_symbol((unsigned long)S_ei_open); - S_ei_open = NULL; - } - if (S_ei_close) { - put_module_symbol((unsigned long)S_ei_close); - S_ei_close = NULL; - } - if (S_ei_interrupt) { - put_module_symbol((unsigned long)S_ei_interrupt); - S_ei_interrupt = NULL; - } -} - -extern __inline__ int load_8390_module(const char *driver) -{ - /* Do we actually need to handle this case? */ - if (S_ethdev_init) { - printk(KERN_DEBUG "%s: load_8390_module called when pointers already present\n", driver); - return 0; - } - - /* Attempt to get the first symbol */ - S_ethdev_init = (void *)get_module_symbol(NULL, "ethdev_init"); - - if (!S_ethdev_init) { - /* It failed. See if we have request_module() */ - int (*request_mod)(const char *module_name); - - if (get_module_symbol("", "request_module") == 0) { - printk("%s: module auto-load (kmod) support not present.\n", driver); - printk("%s: unable to auto-load required 8390 module.\n", driver); - printk("%s: try \"modprobe 8390\" as root 1st.\n", driver); - return -ENOSYS; - } - - /* OK - we have request_module() - try it */ - request_mod = (void*)get_module_symbol("", "request_module"); - if (request_mod("8390")) { - printk("%s: request to load the 8390 module failed.\n", driver); - return -ENOSYS; - } - - printk(KERN_INFO "%s: auto-loaded 8390 module.\n", driver); - - /* Retry getting ethdev_init */ - S_ethdev_init = (void *)get_module_symbol(NULL, "ethdev_init"); - } - - /* Get addresses for the other functions */ - S_NS8390_init = (void*)get_module_symbol(0, "NS8390_init"); - S_ei_open = (void*)get_module_symbol(0, "ei_open"); - S_ei_close = (void*)get_module_symbol(0, "ei_close"); - S_ei_interrupt = (void*)get_module_symbol(0, "ei_interrupt"); - - /* Check if module really loaded and is valid */ - if (!S_ethdev_init || !S_NS8390_init || !S_ei_open || !S_ei_close - || !S_ei_interrupt) { - unload_8390_module(); - printk("%s: 8390.o not found/invalid or failed to load.\n", driver); - return -ENOSYS; -} - - return 0; -} - -/* - * These are last so they only have scope over the driver - * code (wd, ne, 3c503, etc.) and not over the above code. - */ -#define ethdev_init S_ethdev_init -#define NS8390_init S_NS8390_init -#define ei_open S_ei_open -#define ei_close S_ei_close -#define ei_interrupt S_ei_interrupt - -#else /* not a module or kmod support not wanted */ - +/* Currently unused - delete in v2.5.x after purging from drivers */ #define load_8390_module(driver) 0 #define unload_8390_module() do { } while (0) + extern int ethdev_init(struct net_device *dev); extern void NS8390_init(struct net_device *dev, int startp); 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); -#endif - /* Most of these entries should be in 'struct net_device' (or most of the things in there should be here!) */ /* You have one of these per-board */ diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 7cb160fb7..2998ff93a 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -55,6 +55,9 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH fi + if [ "CONFIG_IA64_SGI_SN1" = "y" ]; then + bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH + fi if [ "$CONFIG_SUPERH" = "y" ]; then tristate ' National DP83902AV support' CONFIG_STNIC fi @@ -99,6 +102,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then tristate ' AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700 fi tristate ' DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA + tristate ' HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 bool ' Other ISA cards' CONFIG_NET_ISA if [ "$CONFIG_NET_ISA" = "y" ]; then tristate ' Cabletron E21xx support' CONFIG_E2100 @@ -112,7 +116,6 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then fi tristate ' HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS tristate ' HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN - tristate ' HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 tristate ' ICL EtherTeam 16i/32 support' CONFIG_ETH16I tristate ' NE2000/NE1000 support' CONFIG_NE2000 if [ "$CONFIG_OBSOLETE" = "y" ]; then @@ -149,7 +152,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then tristate ' Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 fi dep_tristate ' National Semiconductor DP83810 series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI - dep_tristate ' PCI NE2000 support' CONFIG_NE2K_PCI $CONFIG_PCI + dep_tristate ' PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 fi @@ -198,7 +201,7 @@ dep_tristate 'Packet Engines Hamachi GNIC-II support' CONFIG_HAMACHI $CONFIG_PCI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then dep_tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN $CONFIG_PCI fi -tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN +dep_tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN $CONFIG_PCI endmenu diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 1f4e08936..1edf73833 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -33,6 +33,7 @@ #include <linux/errno.h> #include <linux/init.h> #include <linux/netlink.h> +#include <linux/divert.h> #define NEXT_DEV NULL @@ -101,6 +102,7 @@ extern int mace68k_probe(struct net_device *dev); extern int macsonic_probe(struct net_device *dev); extern int mac8390_probe(struct net_device *dev); extern int mac89x0_probe(struct net_device *dev); +extern int mc32_probe(struct net_device *dev); /* Gigabit Ethernet adapters */ extern int yellowfin_probe(struct net_device *dev); @@ -136,14 +138,28 @@ static int __init probe_list(struct net_device *dev, struct devprobe *plist) { struct devprobe *p = plist; unsigned long base_addr = dev->base_addr; +#ifdef CONFIG_NET_DIVERT + int ret; +#endif /* CONFIG_NET_DIVERT */ while (p->probe != NULL) { - if (base_addr && p->probe(dev) == 0) /* probe given addr */ + if (base_addr && p->probe(dev) == 0) { /* probe given addr */ +#ifdef CONFIG_NET_DIVERT + ret = alloc_divert_blk(dev); + if (ret) + return ret; +#endif /* CONFIG_NET_DIVERT */ return 0; - else if (p->status == 0) { /* has autoprobe failed yet? */ + } else if (p->status == 0) { /* has autoprobe failed yet? */ p->status = p->probe(dev); /* no, try autoprobe */ - if (p->status == 0) + if (p->status == 0) { +#ifdef CONFIG_NET_DIVERT + ret = alloc_divert_blk(dev); + if (ret) + return ret; +#endif /* CONFIG_NET_DIVERT */ return 0; + } } p++; } @@ -189,6 +205,9 @@ struct devprobe mca_probes[] __initdata = { #ifdef CONFIG_ELMC /* 3c523 */ {elmc_probe, 0}, #endif +#ifdef CONFIG_ELMC_II /* 3c527 */ + {mc32_probe, 0}, +#endif #ifdef CONFIG_SKMC /* SKnet Microchannel */ {skmca_probe, 0}, #endif @@ -687,6 +706,25 @@ extern int loopback_init(struct net_device *dev); struct net_device loopback_dev = {"lo", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, loopback_init}; +/* + * The @dev_base list is protected by @dev_base_lock and the rtln + * semaphore. + * + * Pure readers hold dev_base_lock for reading. + * + * Writers must hold the rtnl semaphore while they loop through the + * dev_base list, and hold dev_base_lock for writing when they do the + * actual updates. This allows pure readers to access the list even + * while a writer is preparing to update it. + * + * To put it another way, dev_base_lock is held for writing only to + * protect against pure readers; the rtnl semaphore provides the + * protection against other writers. + * + * See, for example usages, register_netdevice() and + * unregister_netdevice(), which must be called with the rtnl + * semaphore held. + */ struct net_device *dev_base = &loopback_dev; rwlock_t dev_base_lock = RW_LOCK_UNLOCKED; diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index a89bff2b8..498bd523f 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -749,7 +749,6 @@ static int __init a2065_probe(void) sizeof(struct lance_regs)); continue; } - strcpy(z->name, "A2065 Ethernet Card"); dev = init_etherdev(NULL, sizeof(struct lance_private)); diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 8399af8c9..0e1c40bd4 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -119,14 +119,20 @@ int __init ac3200_probe(struct net_device *dev) static int __init ac_probe1(int ioaddr, struct net_device *dev) { - int i; + int i, retval; - if (inb_p(ioaddr + AC_ID_PORT) == 0xff) + if (!request_region(ioaddr, AC_IO_EXTENT, "ac3200")) return -ENODEV; - if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) - return -ENODEV; + if (inb_p(ioaddr + AC_ID_PORT) == 0xff) { + retval = -ENODEV; + goto out; + } + if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) { + retval = -ENODEV; + goto out; + } #ifndef final_version printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x," @@ -135,15 +141,6 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev) inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3)); #endif - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("ac3200.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - - if (!dev) - return -ENOMEM; - } - printk("AC3200 in EISA slot %d, node", ioaddr/0x1000); for(i = 0; i < 6; i++) printk(" %02x", dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i)); @@ -154,14 +151,16 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev) || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1 || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) { printk(", not found (invalid prefix).\n"); - return -ENODEV; + retval = -ENODEV; + goto out; } #endif /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (", unable to allocate memory for dev->priv.\n"); - return -ENOMEM; + retval = -ENOMEM; + goto out; } /* Assign and allocate the interrupt now. */ @@ -175,15 +174,12 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev) if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", dev)) { printk (" nothing! Unable to get IRQ %d.\n", dev->irq); - kfree(dev->priv); - dev->priv = NULL; - return -EAGAIN; + retval = -EAGAIN; + goto out1; } printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]); - request_region(ioaddr, AC_IO_EXTENT, "ac3200"); - dev->base_addr = ioaddr; #ifdef notyet @@ -213,20 +209,16 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev) printk(KERN_CRIT "ac3200.c: Use EISA SCU to set card memory below 1MB,\n"); printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_bus(high_memory)); printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n"); - free_irq(dev->irq, dev); - kfree(dev->priv); - dev->priv = NULL; - return -EINVAL; + retval = -EINVAL; + goto out2; } dev->mem_start = (unsigned long)ioremap(dev->mem_start, AC_STOP_PG*0x100); if (dev->mem_start == 0) { printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n"); printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n"); printk(KERN_ERR "ac3200.c: Driver NOT installed.\n"); - free_irq(dev->irq, dev); - kfree(dev->priv); - dev->priv = NULL; - return -EAGAIN; + retval = -EINVAL; + goto out2; } ei_status.reg0 = 1; /* Use as remap flag */ printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n", @@ -255,6 +247,14 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev) dev->stop = &ac_close_card; NS8390_init(dev, 0); return 0; +out2: + free_irq(dev->irq, dev); +out1: + kfree(dev->priv); + dev->priv = NULL; +out: + release_region(ioaddr, AC_IO_EXTENT); + return retval; } static int ac_open(struct net_device *dev) @@ -347,18 +347,10 @@ static int ac_close_card(struct net_device *dev) #ifdef MODULE #define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */ -static struct net_device dev_ac32[MAX_AC32_CARDS] = { - { - "", - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; - -static int io[MAX_AC32_CARDS] = { 0, }; -static int irq[MAX_AC32_CARDS] = { 0, }; -static int mem[MAX_AC32_CARDS] = { 0, }; +static struct net_device dev_ac32[MAX_AC32_CARDS]; +static int io[MAX_AC32_CARDS]; +static int irq[MAX_AC32_CARDS]; +static int mem[MAX_AC32_CARDS]; MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i"); MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i"); diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 8ccc6ebf0..844961396 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -408,7 +408,7 @@ static char version[] __initdata = static struct net_device *root_dev; -static int probed __initdata; +static int probed __initdata = 0; #ifdef NEW_NETINIT diff --git a/drivers/net/aironet4500_card.c b/drivers/net/aironet4500_card.c index d6a9c505d..11b6e2773 100644 --- a/drivers/net/aironet4500_card.c +++ b/drivers/net/aironet4500_card.c @@ -60,7 +60,7 @@ static const char *awc_version = #include <linux/pci.h> -static int reverse_probe =0 ; +static int reverse_probe; static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev, @@ -70,7 +70,7 @@ static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev, int awc4500_pci_probe(struct net_device *dev) { int cards_found = 0; - static int pci_index = 0; /* Static, for multiple probe calls. */ + static int pci_index; /* Static, for multiple probe calls. */ u8 pci_irq_line = 0; // int p; @@ -491,7 +491,7 @@ MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required"); int awc4500_isa_probe(struct net_device *dev) { // int cards_found = 0; -// static int isa_index = 0; /* Static, for multiple probe calls. */ +// static int isa_index; /* Static, for multiple probe calls. */ int isa_irq_line = 0; int isa_ioaddr = 0; // int p; diff --git a/drivers/net/aironet4500_core.c b/drivers/net/aironet4500_core.c index b937af2b3..c5def9e39 100644 --- a/drivers/net/aironet4500_core.c +++ b/drivers/net/aironet4500_core.c @@ -45,8 +45,8 @@ int bap_sleep_after_setup = 1; int sleep_before_command = 1; int bap_sleep_before_write= 1; int sleep_in_command = 1; -int both_bap_lock =0; /* activated at awc_init in this */ -int bap_setup_spinlock =0; /* file if numcpu >1 */ +int both_bap_lock; /* activated at awc_init in this */ +int bap_setup_spinlock; /* file if numcpu >1 */ EXPORT_SYMBOL(bap_sleep); EXPORT_SYMBOL(bap_sleep_after_setup); @@ -1386,7 +1386,7 @@ awc_802_11_find_copy_path(struct net_device * dev, struct awc_fid * rx_buff){ */ -int parse_not_8023= 0; +int parse_not_8023; void awc_802_11_router_rx(struct net_device * dev,struct awc_fid * rx_buff){ @@ -2539,25 +2539,25 @@ bad_end: static const char *aironet4500_core_version = "aironet4500.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n"; -struct net_device * aironet4500_devices[MAX_AWCS] = {NULL,NULL,NULL,NULL}; +struct net_device * aironet4500_devices[MAX_AWCS]; -int awc_debug = 0; // 0xffffff; -static int p802_11_send = 0; // 1 +int awc_debug; // 0xffffff; +static int p802_11_send; // 1 -static int awc_process_tx_results = 0; +static int awc_process_tx_results; int tx_queue_len = 10; -int tx_rate = 0; +int tx_rate; int channel = 5; -//static int tx_full_rate = 0; +//static int tx_full_rate; int max_mtu = 2312; -int adhoc = 0; +int adhoc; int large_buff_mem = 1700 * 10; int small_buff_no = 20; -int awc_full_stats = 0; -char SSID[33] = {0}; -int master= 0; -int slave = 0; -int awc_simple_bridge = 0; +int awc_full_stats; +char SSID[33]; +int master; +int slave; +int awc_simple_bridge; // int debug =0; #if LINUX_VERSION_CODE >= 0x20100 @@ -3029,7 +3029,7 @@ void awc_tx_timeout (struct net_device *dev) } -long long last_tx_q_hack = 0; +long long last_tx_q_hack; int direction = 1; int awc_start_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -3213,8 +3213,8 @@ awc_set_multicast_list(struct net_device *dev) { -int (* awc_proc_set_fun) (int) = NULL; -int (* awc_proc_unset_fun) (int) = NULL; +int (* awc_proc_set_fun) (int); +int (* awc_proc_unset_fun) (int); int awc_register_proc(int (*awc_proc_set_device)(int),int (*awc_proc_unset_device)(int)){ diff --git a/drivers/net/apne.c b/drivers/net/apne.c index af1e5de11..df60ad6b8 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -178,12 +178,6 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) 8, 9+GAYLE_ODD, 0xa, 0xb+GAYLE_ODD, 0xc, 0xd+GAYLE_ODD, 0xe, 0xf+GAYLE_ODD }; - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk(KERN_ERR "apne.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - if (ei_debug && version_printed++ == 0) printk(version); @@ -556,15 +550,7 @@ static void apne_interrupt(int irq, void *dev_id, struct pt_regs *regs) } #ifdef MODULE -static char devicename[9] = {0, }; - -static struct net_device apne_dev = -{ - devicename, - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, apne_probe, -}; +static struct net_device apne_dev = { init: apne_probe }; int init_module(void) { diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index f4a3835be..af06e74f6 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -168,7 +168,6 @@ static int __init ariadne_probe(void) release_mem_region(base_addr, sizeof(struct Am79C960)); continue; } - strcpy(z->name, "Ariadne Ethernet Card and Parallel Ports"); dev = init_etherdev(NULL, sizeof(struct ariadne_private)); diff --git a/drivers/net/ariadne2.c b/drivers/net/ariadne2.c index c736c0410..2197d067c 100644 --- a/drivers/net/ariadne2.c +++ b/drivers/net/ariadne2.c @@ -95,7 +95,6 @@ int __init ariadne2_probe(struct net_device *dev) release_mem_region(ioaddr, NE_IO_EXTENT*2); return err; } - strcpy(z->name, "AriadNE2 Ethernet"); return 0; } return -ENODEV; @@ -113,12 +112,6 @@ static int __init ariadne2_init(struct net_device *dev, unsigned long board) }; unsigned long ioaddr = board+ARIADNE2_BASE*2; - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk(KERN_ERR "ariadne2.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - /* Reset card. Who knows what dain-bramaged state it was left in. */ { unsigned long reset_start_time = jiffies; @@ -388,15 +381,7 @@ static void ariadne2_block_output(struct net_device *dev, int count, } #ifdef MODULE -static char devicename[9] = { 0, }; - -static struct net_device ariadne2_dev = -{ - devicename, - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, ariadne2_probe, -}; +static struct net_device ariadne2_dev = { init: ariadne2_probe }; int init_module(void) { diff --git a/drivers/net/arlan.c b/drivers/net/arlan.c index b1a4549de..dfa7c218b 100644 --- a/drivers/net/arlan.c +++ b/drivers/net/arlan.c @@ -11,7 +11,7 @@ static const char *arlan_version = "C.Jennigs 97 & Elmer.Joandi@ut.ee Oct'98, http://www.ylenurme.ee/~elmer/655/"; struct net_device *arlan_device[MAX_ARLANS]; -int last_arlan = 0; +int last_arlan; static int SID = SIDUNKNOWN; static int radioNodeId = radioNodeIdUNKNOWN; @@ -26,22 +26,22 @@ static int channelNumber = channelNumberUNKNOWN; static int channelSet = channelSetUNKNOWN; static int systemId = systemIdUNKNOWN; static int registrationMode = registrationModeUNKNOWN; -static int keyStart = 0; -static int tx_delay_ms = 0; +static int keyStart; +static int tx_delay_ms; static int retries = 5; static int async = 1; static int tx_queue_len = 1; -static int arlan_EEPROM_bad = 0; -int arlan_entry_and_exit_debug = 0; +static int arlan_EEPROM_bad; +int arlan_entry_and_exit_debug; #ifdef ARLAN_DEBUGING -static int arlan_entry_debug = 0; -static int arlan_exit_debug = 0; +static int arlan_entry_debug; +static int arlan_exit_debug; static int testMemory = testMemoryUNKNOWN; static int irq = irqUNKNOWN; static int txScrambled = 1; -static int mdebug = 0; +static int mdebug; #endif #if LINUX_VERSION_CODE > 0x20100 @@ -87,7 +87,7 @@ EXPORT_SYMBOL(last_arlan); #endif struct arlan_conf_stru arlan_conf[MAX_ARLANS]; -int arlans_found = 0; +int arlans_found; static int arlan_probe_here(struct net_device *dev, int ioaddr); static int arlan_open(struct net_device *dev); diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 6acc28597..42b4d118a 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -191,13 +191,6 @@ struct at1720_mca_adapters_struct at1720_mca_adapters[] = { (detachable devices only). */ -#ifdef HAVE_DEVLIST -/* Support for a alternate probe manager, which will eliminate the - boilerplate below. */ -struct netdev_entry at1700_drv = -{"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list}; -#else - int at1700_probe(struct net_device *dev) { int i; @@ -217,7 +210,6 @@ int at1700_probe(struct net_device *dev) } return -ENODEV; } -#endif /* The Fujitsu datasheet suggests that the NIC be probed for by checking its "signature", the default bit pattern after a reset. This *doesn't* work -- @@ -324,10 +316,6 @@ found: /* Reset the internal state machines. */ outb(0, ioaddr + RESET); - /* Allocate a new 'dev' if needed. */ - if (dev == NULL) - dev = init_etherdev(0, sizeof(struct net_local)); - if (is_at1700) irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04) | (read_eeprom(ioaddr, 0)>>14)]; @@ -878,14 +866,10 @@ set_rx_mode(struct net_device *dev) } #ifdef MODULE -static struct net_device dev_at1700 = { - "", /* device name is inserted by linux/drivers/net/net_init.c */ - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, at1700_probe }; +static struct net_device dev_at1700 = { init: at1700_probe }; static int io = 0x260; -static int irq = 0; +static int irq; MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 1b71c6e13..9577b4ffa 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -263,10 +263,7 @@ int __init cs89x0_probe(struct net_device *dev) return -ENXIO; for (i = 0; netcard_portlist[i]; i++) { - int ioaddr = netcard_portlist[i]; - if (check_region(ioaddr, NETCARD_IO_EXTENT)) - continue; - if (cs89x0_probe1(dev, ioaddr) == 0) + 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"); @@ -363,8 +360,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr) /* Initialize the device structure. */ if (dev->priv == NULL) { dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); - if (dev->priv == 0) - { + if (dev->priv == 0) { retval = -ENOMEM; goto out; } @@ -372,8 +368,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr) memset(lp, 0, sizeof(*lp)); spin_lock_init(&lp->lock); #if !defined(MODULE) && (ALLOW_DMA != 0) - if (g_cs89x0_dma) - { + if (g_cs89x0_dma) { lp->use_dma = 1; lp->dma = g_cs89x0_dma; lp->dmasize = 16; /* Could make this an option... */ @@ -382,22 +377,29 @@ cs89x0_probe1(struct net_device *dev, int ioaddr) } lp = (struct net_local *)dev->priv; + /* Grab the region so we can find another board if autoIRQ fails. */ + if (!request_region(ioaddr, NETCARD_IO_EXTENT, "cs89x0")) { + retval = -ENODEV; + goto out1; + } + /* if they give us an odd I/O address, then do ONE write to the address port, to get it back to address zero, where we expect to find the EISA signature word. An IO with a base of 0x3 will skip the test for the ADD_PORT. */ if (ioaddr & 1) { if ((ioaddr & 2) != 2) - if ((inw((ioaddr & ~3)+ ADD_PORT) & ADD_MASK) != ADD_SIG) - return -ENODEV; + if ((inw((ioaddr & ~3)+ ADD_PORT) & ADD_MASK) != ADD_SIG) { + retval = -ENODEV; + goto out2; + } ioaddr &= ~3; outw(PP_ChipID, ioaddr + ADD_PORT); } - if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) - { + if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) { retval = -ENODEV; - goto out1; + goto out2; } /* Fill in the 'dev' fields. */ @@ -574,8 +576,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr) printk(" IRQ %d", dev->irq); #if ALLOW_DMA - if (lp->use_dma) - { + if (lp->use_dma) { get_dma_channel(dev); printk(", DMA %d", dev->dma); } @@ -592,14 +593,6 @@ cs89x0_probe1(struct net_device *dev, int ioaddr) printk("%s%02x", i ? ":" : "", dev->dev_addr[i]); } - /* Grab the region so we can find another board if autoIRQ fails. */ - - /* - * FIXME: we should check this, but really the isapnp stuff should have given - * us a free region. Sort this out when the isapnp is sorted out - */ - request_region(ioaddr, NETCARD_IO_EXTENT,"cs89x0"); - dev->open = net_open; dev->stop = net_close; dev->tx_timeout = net_timeout; @@ -616,6 +609,8 @@ cs89x0_probe1(struct net_device *dev, int ioaddr) if (net_debug) printk("cs89x0_probe1() successful\n"); return 0; +out2: + release_region(ioaddr, NETCARD_IO_EXTENT); out1: kfree(dev->priv); dev->priv = 0; @@ -672,22 +667,17 @@ set_dma_cfg(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; - if (lp->use_dma) - { - if ((lp->isa_config & ANY_ISA_DMA) == 0) - { + if (lp->use_dma) { + if ((lp->isa_config & ANY_ISA_DMA) == 0) { if (net_debug > 3) printk("set_dma_cfg(): no DMA\n"); return; } - if (lp->isa_config & ISA_RxDMA) - { + if (lp->isa_config & ISA_RxDMA) { lp->curr_rx_cfg |= RX_DMA_ONLY; if (net_debug > 3) printk("set_dma_cfg(): RX_DMA_ONLY\n"); - } - else - { + } else { lp->curr_rx_cfg |= AUTO_RX_DMA; /* not that we support it... */ if (net_debug > 3) printk("set_dma_cfg(): AUTO_RX_DMA\n"); @@ -710,8 +700,7 @@ dma_busctl(struct net_device *dev) { int retval = 0; struct net_local *lp = (struct net_local *)dev->priv; - if (lp->use_dma) - { + if (lp->use_dma) { if (lp->isa_config & ANY_ISA_DMA) retval |= RESET_RX_DMA; /* Reset the DMA pointer */ if (lp->isa_config & DMA_BURST) @@ -734,8 +723,7 @@ dma_rx(struct net_device *dev) status = bp[0] + (bp[1]<<8); length = bp[2] + (bp[3]<<8); bp += 4; - if (net_debug > 5) - { + if (net_debug > 5) { printk( "%s: receiving DMA packet at %lx, status %x, length %x\n", dev->name, (unsigned long)bp, status, length); } @@ -773,8 +761,7 @@ skip_this_frame: if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024; lp->rx_dma_ptr = bp; - if (net_debug > 3) - { + if (net_debug > 3) { printk( "%s: received %d byte DMA packet of type %x\n", dev->name, length, (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]); @@ -1080,8 +1067,7 @@ net_open(struct net_device *dev) } #if ALLOW_DMA - if (lp->use_dma) - { + if (lp->use_dma) { if (lp->isa_config & ANY_ISA_DMA) { unsigned long flags; lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL, @@ -1091,8 +1077,7 @@ net_open(struct net_device *dev) printk(KERN_ERR "%s: cannot get %dK memory for DMA\n", dev->name, lp->dmasize); goto release_irq; } - if (net_debug > 1) - { + if (net_debug > 1) { printk( "%s: dma %lx %lx\n", dev->name, (unsigned long)lp->dma_buff, @@ -1268,8 +1253,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; - if (net_debug > 3) - { + 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]); @@ -1287,8 +1271,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) writeword(dev, TX_LEN_PORT, skb->len); /* Test to see if the chip has allocated memory for the packet */ - if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) - { + 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. @@ -1351,8 +1334,7 @@ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) TX_LOST_CRS | TX_SQE_ERROR | TX_LATE_COL | - TX_16_COL)) != TX_OK) - { + TX_16_COL)) != TX_OK) { 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++; @@ -1454,8 +1436,7 @@ net_rx(struct net_device *dev) if (length & 1) skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT); - if (net_debug > 3) - { + if (net_debug > 3) { printk( "%s: received %d byte packet of type %x\n", dev->name, length, (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]); @@ -1471,8 +1452,7 @@ net_rx(struct net_device *dev) #if ALLOW_DMA static void release_dma_buff(struct net_local *lp) { - if (lp->dma_buff) - { + if (lp->dma_buff) { free_pages((unsigned long)(lp->dma_buff), (lp->dmasize * 1024) / PAGE_SIZE); lp->dma_buff = 0; } @@ -1557,8 +1537,7 @@ static int set_mac_address(struct net_device *dev, void *addr) if (netif_running(dev)) return -EBUSY; - if (net_debug) - { + 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]); @@ -1649,8 +1628,7 @@ init_module(void) dev_cs89x0.init = cs89x0_probe; dev_cs89x0.priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); - if (dev_cs89x0.priv == 0) - { + if (dev_cs89x0.priv == 0) { printk(KERN_ERR "cs89x0.c: Out of memory.\n"); return -ENOMEM; } @@ -1658,8 +1636,7 @@ init_module(void) lp = (struct net_local *)dev_cs89x0.priv; #if ALLOW_DMA - if (use_dma) - { + if (use_dma) { lp->use_dma = use_dma; lp->dma = dma; lp->dmasize = dmasize; @@ -1681,7 +1658,7 @@ init_module(void) if (duplex==-1) lp->auto_neg_cnf = AUTO_NEG_ENABLE; - if (io == 0) { + if (io == 0) { printk(KERN_ERR "cs89x0.c: Module autoprobing not allowed.\n"); printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n"); return -EPERM; diff --git a/drivers/net/daynaport.c b/drivers/net/daynaport.c index f94b189fb..b7718aba5 100644 --- a/drivers/net/daynaport.c +++ b/drivers/net/daynaport.c @@ -25,7 +25,7 @@ static const char *version = "daynaport.c: v0.02 1999-05-17 Alan Cox (Alan.Cox@linux.org) and others\n"; -static int version_printed = 0; +static int version_printed; #include <linux/module.h> #include <linux/init.h> diff --git a/drivers/net/declance.c b/drivers/net/declance.c index 90c4f298b..7dab57926 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -1000,10 +1000,11 @@ static void lance_set_multicast_retry(unsigned long _opaque) static int __init dec_lance_init(struct net_device *dev, const int type) { - static unsigned version_printed = 0; + static unsigned version_printed; + struct net_device *dev; struct lance_private *lp; volatile struct lance_regs *ll; - int i; + int i, ret; unsigned long esar_base; unsigned char *esar; @@ -1016,19 +1017,11 @@ static int __init dec_lance_init(struct net_device *dev, const int type) if (dec_lance_debug && version_printed++ == 0) printk(version); - if (dev == NULL) { - dev = init_etherdev(0, sizeof(struct lance_private) + 8); - } else { - dev->priv = kmalloc(sizeof(struct lance_private) + 8, - GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - memset(dev->priv, 0, sizeof(struct lance_private) + 8); + dev = init_etherdev(0, sizeof(struct lance_private)); + if (!dev) + return -ENOMEM; - } - - /* Make certain the data structures used by the LANCE are aligned. */ - dev->priv = (void *) (((unsigned long) dev->priv + 7) & ~7); + /* init_etherdev ensures the data structures used by the LANCE are aligned. */ lp = (struct lance_private *) dev->priv; spin_lock_init(&lp->lock); @@ -1114,8 +1107,8 @@ static int __init dec_lance_init(struct net_device *dev, const int type) break; default: printk("declance_init called with unknown type\n"); - return -ENODEV; - break; + ret = -ENODEV; + goto err_out; } ll = (struct lance_regs *) dev->base_addr; @@ -1126,7 +1119,8 @@ static int __init dec_lance_init(struct net_device *dev, const int type) if (esar[0x60] != 0xff && esar[0x64] != 0x00 && esar[0x68] != 0x55 && esar[0x6c] != 0xaa) { printk("Ethernet station address prom not found!\n"); - return -ENODEV; + ret = -ENODEV; + goto err_out; } /* Check the prom contents */ for (i = 0; i < 8; i++) { @@ -1135,7 +1129,8 @@ static int __init dec_lance_init(struct net_device *dev, const int type) esar[0x3c - i * 4] != esar[0x40 + i * 4]) { printk("Something is wrong with the ethernet " "station address prom!\n"); - return -ENODEV; + ret = -ENODEV; + goto err_out; } } @@ -1199,6 +1194,11 @@ static int __init dec_lance_init(struct net_device *dev, const int type) root_lance_dev = lp; #endif return 0; + +err_out: + unregister_netdev(dev); + kfree(dev); + return ret; } diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 196c81126..448baa800 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -223,6 +223,9 @@ 0.5 14-Nov-98 Re-spin for 2.1.x kernels. 0.51 27-Jun-99 Correct received packet length for CRC from report by <worm@dkik.dk> + 0.52 16-Oct-00 Fixes for 2.3 io memory accesses + Fix show-stopper (ints left masked) in depca_interrupt + by <peterd@pnd-pc.demon.co.uk> ========================================================================= */ @@ -378,14 +381,21 @@ struct depca_private { char devname[DEPCA_STRLEN]; /* Device Product String */ char adapter_name[DEPCA_STRLEN];/* /proc/ioports string */ char adapter; /* Adapter type */ - char mca_slot; /* MCA slot, if MCA else -1 */ struct depca_rx_desc *rx_ring; /* Pointer to start of RX descriptor ring */ - struct depca_tx_desc *tx_ring; /* Pointer to start of TX descriptor ring */ + char mca_slot; /* MCA slot, if MCA else -1 */ struct depca_init init_block;/* Shadow Initialization block */ - char *rx_memcpy[NUM_RX_DESC]; /* CPU virt address of sh'd memory buffs */ - char *tx_memcpy[NUM_TX_DESC]; /* CPU virt address of sh'd memory buffs */ - u_long bus_offset; /* (E)ISA bus address offset vs LANCE */ - u_long sh_mem; /* Physical start addr of shared mem area */ - u_long dma_buffs; /* LANCE Rx and Tx buffers start address. */ +/* CPU address space fields */ + struct depca_rx_desc *rx_ring; /* Pointer to start of RX descriptor ring */ + struct depca_tx_desc *tx_ring; /* Pointer to start of TX descriptor ring */ + void *rx_buff[NUM_RX_DESC]; /* CPU virt address of sh'd memory buffs */ + void *tx_buff[NUM_TX_DESC]; /* CPU virt address of sh'd memory buffs */ + void *sh_mem; /* CPU mapped virt address of device RAM */ +/* Device address space fields */ + u_long device_ram_start; /* Start of RAM in device addr space */ +/* Offsets used in both address spaces */ + u_long rx_ring_offset; /* Offset from start of RAM to rx_ring */ + u_long tx_ring_offset; /* Offset from start of RAM to tx_ring */ + u_long buffs_offset; /* LANCE Rx and Tx buffers start address. */ +/* Kernel-only (not device) fields */ int rx_new, tx_new; /* The next free ring entry */ int rx_old, tx_old; /* The ring entries to be free()ed. */ struct net_device_stats stats; @@ -463,12 +473,12 @@ static u_char de1xx_irq[] __initdata = {2,3,4,5,7,9,0}; static u_char de2xx_irq[] __initdata = {5,9,10,11,15,0}; static u_char de422_irq[] __initdata = {5,9,10,11,0}; static u_char *depca_irq; -static int autoprobed = 0, loading_module = 0; +static int autoprobed, loading_module; #endif /* MODULE */ static char name[DEPCA_STRLEN]; -static int num_depcas = 0, num_eth = 0; -static int mem=0; /* For loadable module assignment +static int num_depcas, num_eth; +static int mem; /* For loadable module assignment use insmod mem=0x????? .... */ static char *adapter_name = '\0'; /* If no PROM when loadable module use insmod adapter_name=DE??? ... @@ -517,215 +527,228 @@ depca_probe(struct net_device *dev) static int __init depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot) { - struct depca_private *lp; - int i, j, offset, netRAM, mem_len, status=0; - s16 nicsr; - u_long mem_start=0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES; + struct depca_private *lp; + int i, j, offset, netRAM, mem_len, status=0; + s16 nicsr; + u_long mem_start=0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES; - STOP_DEPCA; + STOP_DEPCA; - nicsr = inb(DEPCA_NICSR); - nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM); - outb(nicsr, DEPCA_NICSR); - - if (inw(DEPCA_DATA) == STOP) { - do { - strcpy(name, (adapter_name ? adapter_name : "")); - mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]); - DepcaSignature(name, mem_start); - } while (!mem && mem_base[mem_chkd] && (adapter == unknown)); - - if ((adapter != unknown) && mem_start) { /* found a DEPCA device */ - dev->base_addr = ioaddr; - - if (mca_slot != -1) { - printk("%s: %s at 0x%04lx (MCA slot %d)", dev->name, name, - ioaddr, mca_slot); - } else if ((ioaddr & 0x0fff) == DEPCA_EISA_IO_PORTS) { /* EISA slot address */ - printk("%s: %s at 0x%04lx (EISA slot %d)", - dev->name, name, ioaddr, (int)((ioaddr>>12)&0x0f)); - } else { /* ISA port address */ - printk("%s: %s at 0x%04lx", dev->name, name, ioaddr); - } + nicsr = inb(DEPCA_NICSR); + nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM); + outb(nicsr, DEPCA_NICSR); - printk(", h/w address "); - status = get_hw_addr(dev); - for (i=0; i<ETH_ALEN - 1; i++) { /* get the ethernet address */ - printk("%2.2x:", dev->dev_addr[i]); - } - printk("%2.2x", dev->dev_addr[i]); + if (inw(DEPCA_DATA) != STOP) { + return -ENXIO; + } + + do { + strcpy(name, (adapter_name ? adapter_name : "")); + mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]); + DepcaSignature(name, mem_start); + } while (!mem && mem_base[mem_chkd] && (adapter == unknown)); + + if ((adapter == unknown) || !mem_start) { /* DEPCA device not found */ + return -ENXIO; + } + + dev->base_addr = ioaddr; + + if (mca_slot != -1) { + printk("%s: %s at 0x%04lx (MCA slot %d)", dev->name, name, + ioaddr, mca_slot); + } else if ((ioaddr & 0x0fff) == DEPCA_EISA_IO_PORTS) { /* EISA slot address */ + printk("%s: %s at 0x%04lx (EISA slot %d)", + dev->name, name, ioaddr, (int)((ioaddr>>12)&0x0f)); + } else { /* ISA port address */ + printk("%s: %s at 0x%04lx", dev->name, name, ioaddr); + } + + printk(", h/w address "); + status = get_hw_addr(dev); + for (i=0; i<ETH_ALEN - 1; i++) { /* get the ethernet address */ + printk("%2.2x:", dev->dev_addr[i]); + } + printk("%2.2x", dev->dev_addr[i]); + + if (status != 0) { + printk(" which has an Ethernet PROM CRC error.\n"); + return -ENXIO; + } - if (status == 0) { /* Set up the maximum amount of network RAM(kB) */ netRAM = ((adapter != DEPCA) ? 64 : 48); - if ((nicsr & _128KB) && (adapter == de422)) netRAM = 128; + if ((nicsr & _128KB) && (adapter == de422)) + netRAM = 128; offset = 0x0000; /* Shared Memory Base Address */ if (nicsr & BUF) { - offset = 0x8000; /* 32kbyte RAM offset*/ - nicsr &= ~BS; /* DEPCA RAM in top 32k */ - netRAM -= 32; + offset = 0x8000; /* 32kbyte RAM offset*/ + nicsr &= ~BS; /* DEPCA RAM in top 32k */ + netRAM -= 32; } mem_start += offset; /* (E)ISA start address */ if ((mem_len = (NUM_RX_DESC*(sizeof(struct depca_rx_desc)+RX_BUFF_SZ) + NUM_TX_DESC*(sizeof(struct depca_tx_desc)+TX_BUFF_SZ) + - sizeof(struct depca_init))) <= - (netRAM<<10)) { - printk(",\n has %dkB RAM at 0x%.5lx", netRAM, mem_start); - - /* Enable the shadow RAM. */ - if (adapter != DEPCA) { - nicsr |= SHE; - outb(nicsr, DEPCA_NICSR); - } + sizeof(struct depca_init))) + > (netRAM<<10)) { + printk(",\n requests %dkB RAM: only %dkB is available!\n", + (mem_len >> 10), netRAM); + return -ENXIO; + } + + printk(",\n has %dkB RAM at 0x%.5lx", netRAM, mem_start); + + /* Enable the shadow RAM. */ + if (adapter != DEPCA) { + nicsr |= SHE; + outb(nicsr, DEPCA_NICSR); + } - /* Define the device private memory */ - dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - lp = (struct depca_private *)dev->priv; - memset((char *)dev->priv, 0, sizeof(struct depca_private)); - lp->adapter = adapter; - lp->mca_slot = mca_slot; - lp->lock = SPIN_LOCK_UNLOCKED; - sprintf(lp->adapter_name,"%s (%s)", name, dev->name); - request_region(ioaddr, DEPCA_TOTAL_SIZE, lp->adapter_name); - - /* Initialisation Block */ - lp->sh_mem = mem_start; - mem_start += sizeof(struct depca_init); - - /* Tx & Rx descriptors (aligned to a quadword boundary) */ - mem_start = (mem_start + ALIGN) & ~ALIGN; - lp->rx_ring = (struct depca_rx_desc *)mem_start; - - mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC); - lp->tx_ring = (struct depca_tx_desc *)mem_start; - - mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC); - lp->bus_offset = mem_start & 0x00ff0000; - mem_start &= LA_MASK; /* LANCE re-mapped start address */ - - lp->dma_buffs = mem_start; - - /* Finish initialising the ring information. */ - lp->rxRingMask = NUM_RX_DESC - 1; - lp->txRingMask = NUM_TX_DESC - 1; - - /* Calculate Tx/Rx RLEN size for the descriptors. */ - for (i=0, j = lp->rxRingMask; j>0; i++) { - j >>= 1; - } - lp->rx_rlen = (s32)(i << 29); - for (i=0, j = lp->txRingMask; j>0; i++) { - j >>= 1; - } - lp->tx_rlen = (s32)(i << 29); + /* Define the device private memory */ + dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; + lp = (struct depca_private *)dev->priv; + memset((char *)dev->priv, 0, sizeof(struct depca_private)); + lp->adapter = adapter; + lp->mca_slot = mca_slot; + lp->lock = SPIN_LOCK_UNLOCKED; + sprintf(lp->adapter_name,"%s (%s)", name, dev->name); + if (!request_region(ioaddr, DEPCA_TOTAL_SIZE, lp->adapter_name)) { + printk(KERN_ERR "depca: I/O resource 0x%x @ 0x%lx busy\n", + DEPCA_TOTAL_SIZE, ioaddr); + return -EBUSY; + } + + /* Initialisation Block */ + lp->sh_mem = ioremap(mem_start, mem_len); + if (lp->sh_mem == NULL) { + printk(KERN_ERR "depca: cannot remap ISA memory, aborting\n"); + return -EIO; + } + lp->device_ram_start = mem_start & LA_MASK; + + offset = 0; + offset += sizeof(struct depca_init); + + /* Tx & Rx descriptors (aligned to a quadword boundary) */ + offset = (offset + ALIGN) & ~ALIGN; + lp->rx_ring = (struct depca_rx_desc *)(lp->sh_mem + offset); + lp->rx_ring_offset = offset; + + offset += (sizeof(struct depca_rx_desc) * NUM_RX_DESC); + lp->tx_ring = (struct depca_tx_desc *)(lp->sh_mem + offset); + lp->tx_ring_offset = offset; + + offset += (sizeof(struct depca_tx_desc) * NUM_TX_DESC); + + lp->buffs_offset = offset; - /* Load the initialisation block */ - depca_init_ring(dev); + /* Finish initialising the ring information. */ + lp->rxRingMask = NUM_RX_DESC - 1; + lp->txRingMask = NUM_TX_DESC - 1; - /* Initialise the control and status registers */ - LoadCSRs(dev); + /* Calculate Tx/Rx RLEN size for the descriptors. */ + for (i=0, j = lp->rxRingMask; j>0; i++) { + j >>= 1; + } + lp->rx_rlen = (s32)(i << 29); + for (i=0, j = lp->txRingMask; j>0; i++) { + j >>= 1; + } + lp->tx_rlen = (s32)(i << 29); + + /* Load the initialisation block */ + depca_init_ring(dev); - /* Enable DEPCA board interrupts for autoprobing */ - nicsr = ((nicsr & ~IM)|IEN); - outb(nicsr, DEPCA_NICSR); + /* Initialise the control and status registers */ + LoadCSRs(dev); - /* To auto-IRQ we enable the initialization-done and DMA err, - interrupts. For now we will always get a DMA error. */ - if (dev->irq < 2) { + /* Enable DEPCA board interrupts for autoprobing */ + nicsr = ((nicsr & ~IM)|IEN); + outb(nicsr, DEPCA_NICSR); + + /* To auto-IRQ we enable the initialization-done and DMA err, + interrupts. For now we will always get a DMA error. */ + if (dev->irq < 2) { #ifndef MODULE - unsigned char irqnum; - autoirq_setup(0); - - /* Assign the correct irq list */ - switch (lp->adapter) { - case DEPCA: - case de100: - case de101: - depca_irq = de1xx_irq; - break; - case de200: - case de201: - case de202: - case de210: - case de212: - depca_irq = de2xx_irq; - break; - case de422: - depca_irq = de422_irq; - break; - } + unsigned char irqnum; + autoirq_setup(0); + + /* Assign the correct irq list */ + switch (lp->adapter) { + case DEPCA: + case de100: + case de101: + depca_irq = de1xx_irq; + break; + case de200: + case de201: + case de202: + case de210: + case de212: + depca_irq = de2xx_irq; + break; + case de422: + depca_irq = de422_irq; + break; + } - /* Trigger an initialization just for the interrupt. */ - outw(INEA | INIT, DEPCA_DATA); + /* Trigger an initialization just for the interrupt. */ + outw(INEA | INIT, DEPCA_DATA); - irqnum = autoirq_report(1); - if (!irqnum) { - printk(" and failed to detect IRQ line.\n"); - status = -ENXIO; - } else { - for (dev->irq=0,i=0; (depca_irq[i]) && (!dev->irq); i++) { - if (irqnum == depca_irq[i]) { - dev->irq = irqnum; - printk(" and uses IRQ%d.\n", dev->irq); - } - } + irqnum = autoirq_report(1); + if (!irqnum) { + printk(" and failed to detect IRQ line.\n"); + status = -ENXIO; + } else { + for (dev->irq=0,i=0; (depca_irq[i]) && (!dev->irq); i++) { + if (irqnum == depca_irq[i]) { + dev->irq = irqnum; + printk(" and uses IRQ%d.\n", dev->irq); + } + } - if (!dev->irq) { - printk(" but incorrect IRQ line detected.\n"); - status = -ENXIO; - } - } + if (!dev->irq) { + printk(" but incorrect IRQ line detected.\n"); + status = -ENXIO; + } + } #endif /* MODULE */ - } else { - printk(" and assigned IRQ%d.\n", dev->irq); - } - if (status) release_region(ioaddr, DEPCA_TOTAL_SIZE); } else { - printk(",\n requests %dkB RAM: only %dkB is available!\n", - (mem_len>>10), netRAM); - status = -ENXIO; + printk(" and assigned IRQ%d.\n", dev->irq); } - } else { - printk(" which has an Ethernet PROM CRC error.\n"); - status = -ENXIO; - } - } else { - status = -ENXIO; - } - if (!status) { - if (depca_debug > 1) { - printk(version); - } - /* The DEPCA-specific entries in the device structure. */ - dev->open = &depca_open; - dev->hard_start_xmit = &depca_start_xmit; - dev->stop = &depca_close; - dev->get_stats = &depca_get_stats; - dev->set_multicast_list = &set_multicast_list; - dev->do_ioctl = &depca_ioctl; - dev->tx_timeout = depca_tx_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - - dev->mem_start = 0; - - /* Fill in the generic field of the device structure. */ - ether_setup(dev); - } else { /* Incorrectly initialised hardware */ - if (dev->priv) { - kfree(dev->priv); - dev->priv = NULL; - } - } - } else { - status = -ENXIO; - } + if (!status) { + if (depca_debug > 1) { + printk(version); + } - return status; + /* The DEPCA-specific entries in the device structure. */ + dev->open = &depca_open; + dev->hard_start_xmit = &depca_start_xmit; + dev->stop = &depca_close; + dev->get_stats = &depca_get_stats; + dev->set_multicast_list = &set_multicast_list; + dev->do_ioctl = &depca_ioctl; + dev->tx_timeout = depca_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + dev->mem_start = 0; + + /* Fill in the generic field of the device structure. */ + ether_setup(dev); + } else { /* Incorrectly initialised hardware */ + release_region(ioaddr, DEPCA_TOTAL_SIZE); + if (dev->priv) { + kfree(dev->priv); + dev->priv = NULL; + } + } + + return status; } @@ -741,7 +764,7 @@ depca_open(struct net_device *dev) nicsr = inb(DEPCA_NICSR); /* Make sure the shadow RAM is enabled */ - if (adapter != DEPCA) { + if (lp->adapter != DEPCA) { nicsr |= SHE; outb(nicsr, DEPCA_NICSR); } @@ -781,39 +804,43 @@ depca_open(struct net_device *dev) static void depca_init_ring(struct net_device *dev) { - struct depca_private *lp = (struct depca_private *)dev->priv; - u_int i; - u_long p; - - /* Lock out other processes whilst setting up the hardware */ - netif_stop_queue(dev); - - lp->rx_new = lp->tx_new = 0; - lp->rx_old = lp->tx_old = 0; + struct depca_private *lp = (struct depca_private *)dev->priv; + u_int i; + u_long offset; + + /* Lock out other processes whilst setting up the hardware */ + netif_stop_queue(dev); + + lp->rx_new = lp->tx_new = 0; + lp->rx_old = lp->tx_old = 0; + + /* Initialize the base address and length of each buffer in the ring */ + for (i = 0; i <= lp->rxRingMask; i++) { + offset = lp->buffs_offset + i*RX_BUFF_SZ; + writel((lp->device_ram_start + offset) | R_OWN, + &lp->rx_ring[i].base); + writew(-RX_BUFF_SZ, &lp->rx_ring[i].buf_length); + lp->rx_buff[i] = lp->sh_mem + offset; + } - /* Initialize the base addresses and length of each buffer in the ring */ - for (i = 0; i <= lp->rxRingMask; i++) { - writel((p=lp->dma_buffs+i*RX_BUFF_SZ) | R_OWN, &lp->rx_ring[i].base); - writew(-RX_BUFF_SZ, &lp->rx_ring[i].buf_length); - lp->rx_memcpy[i]=(char *)(p+lp->bus_offset); - } - for (i = 0; i <= lp->txRingMask; i++) { - writel((p=lp->dma_buffs+(i+lp->txRingMask+1)*TX_BUFF_SZ) & 0x00ffffff, - &lp->tx_ring[i].base); - lp->tx_memcpy[i]=(char *)(p+lp->bus_offset); - } + for (i = 0; i <= lp->txRingMask; i++) { + offset = lp->buffs_offset + (i + lp->rxRingMask+1)*TX_BUFF_SZ; + writel((lp->device_ram_start + offset) & 0x00ffffff, + &lp->tx_ring[i].base); + lp->tx_buff[i] = lp->sh_mem + offset; + } - /* Set up the initialization block */ - lp->init_block.rx_ring = ((u32)((u_long)lp->rx_ring)&LA_MASK) | lp->rx_rlen; - lp->init_block.tx_ring = ((u32)((u_long)lp->tx_ring)&LA_MASK) | lp->tx_rlen; + /* Set up the initialization block */ + lp->init_block.rx_ring = (lp->device_ram_start + lp->rx_ring_offset) | lp->rx_rlen; + lp->init_block.tx_ring = (lp->device_ram_start + lp->tx_ring_offset) | lp->tx_rlen; - SetMulticastFilter(dev); + SetMulticastFilter(dev); - for (i = 0; i < ETH_ALEN; i++) { - lp->init_block.phys_addr[i] = dev->dev_addr[i]; - } + for (i = 0; i < ETH_ALEN; i++) { + lp->init_block.phys_addr[i] = dev->dev_addr[i]; + } - lp->init_block.mode = 0x0000; /* Enable the Tx and Rx */ + lp->init_block.mode = 0x0000; /* Enable the Tx and Rx */ } @@ -908,12 +935,12 @@ static void depca_interrupt (int irq, void *dev_id, struct pt_regs *regs) /* Any resources available? */ if ((TX_BUFFS_AVAIL >= 0) && netif_queue_stopped(dev)) { netif_wake_queue (dev); - - /* Unmask the DEPCA board interrupts and turn off the LED */ - nicsr = (nicsr & ~IM & ~LED); - outb (nicsr, DEPCA_NICSR); } + /* Unmask the DEPCA board interrupts and turn off the LED */ + nicsr = (nicsr & ~IM & ~LED); + outb (nicsr, DEPCA_NICSR); + spin_unlock (&lp->lock); } @@ -951,10 +978,10 @@ depca_rx(struct net_device *dev) skb->dev = dev; if (entry < lp->rx_old) { /* Wrapped buffer */ len = (lp->rxRingMask - lp->rx_old + 1) * RX_BUFF_SZ; - memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], len); - memcpy_fromio(buf + len, lp->rx_memcpy[0], pkt_len-len); + memcpy_fromio(buf, lp->rx_buff[lp->rx_old], len); + memcpy_fromio(buf + len, lp->rx_buff[0], pkt_len-len); } else { /* Linear buffer */ - memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], pkt_len); + memcpy_fromio(buf, lp->rx_buff[lp->rx_old], pkt_len); } /* @@ -1103,9 +1130,9 @@ static void LoadCSRs(struct net_device *dev) u_long ioaddr = dev->base_addr; outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */ - outw((u16)(lp->sh_mem & LA_MASK), DEPCA_DATA); + outw((u16)lp->device_ram_start, DEPCA_DATA); outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */ - outw((u16)((lp->sh_mem & LA_MASK) >> 16), DEPCA_DATA); + outw((u16)(lp->device_ram_start >> 16), DEPCA_DATA); outw(CSR3, DEPCA_ADDR); /* ALE control */ outw(ACON, DEPCA_DATA); @@ -1121,7 +1148,7 @@ static int InitRestartDepca(struct net_device *dev) int i, status=0; /* Copy the shadow init_block to shared memory */ - memcpy_toio((char *)lp->sh_mem, &lp->init_block, sizeof(struct depca_init)); + memcpy_toio(lp->sh_mem, &lp->init_block, sizeof(struct depca_init)); outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */ outw(INIT, DEPCA_DATA); /* initialize DEPCA */ @@ -1134,11 +1161,11 @@ static int InitRestartDepca(struct net_device *dev) outw(IDON | INEA | STRT, DEPCA_DATA); if (depca_debug > 2) { printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n", - dev->name, i, lp->sh_mem, inw(DEPCA_DATA)); + dev->name, i, virt_to_phys(lp->sh_mem), inw(DEPCA_DATA)); } } else { printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n", - dev->name, i, lp->sh_mem, inw(DEPCA_DATA)); + dev->name, i, virt_to_phys(lp->sh_mem), inw(DEPCA_DATA)); status = -1; } @@ -1569,12 +1596,20 @@ DepcaSignature(char *name, u_long paddr) { u_int i,j,k; const char *signatures[] = DEPCA_SIGNATURE; + void *ptr; char tmpstr[16]; /* Copy the first 16 bytes of ROM */ + ptr = ioremap(paddr + 0xc000, 16); + if (ptr == NULL) { + printk(KERN_ERR "depca: I/O remap failed at %lx\n", paddr+0xc000); + adapter = unknown; + return; + } for (i=0;i<16;i++) { - tmpstr[i] = readb(paddr+0xc000+i); + tmpstr[i] = readb(ptr + i); } + iounmap(ptr); /* Check if PROM contains a valid string */ for (i=0;*signatures[i]!='\0';i++) { @@ -1716,10 +1751,10 @@ static int load_packet(struct net_device *dev, struct sk_buff *skb) */ if (end < entry) { /* wrapped buffer */ len = (lp->txRingMask - entry + 1) * TX_BUFF_SZ; - memcpy_toio(lp->tx_memcpy[entry], skb->data, len); - memcpy_toio(lp->tx_memcpy[0], skb->data + len, skb->len - len); + memcpy_toio(lp->tx_buff[entry], skb->data, len); + memcpy_toio(lp->tx_buff[0], skb->data + len, skb->len - len); } else { /* linear buffer */ - memcpy_toio(lp->tx_memcpy[entry], skb->data, skb->len); + memcpy_toio(lp->tx_buff[entry], skb->data, skb->len); } /* set up the buffer descriptors */ @@ -1795,17 +1830,17 @@ static void depca_dbg_open(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; - struct depca_init *p = (struct depca_init *)lp->sh_mem; + struct depca_init *p = &lp->init_block; int i; if (depca_debug > 1){ - /* Copy the shadow init_block to shared memory */ - memcpy_toio((char *)lp->sh_mem,&lp->init_block,sizeof(struct depca_init)); - + /* Do not copy the shadow init block into shared memory */ + /* Debugging should not affect normal operation! */ + /* The shadow init block will get copied across during InitRestartDepca */ printk("%s: depca open with irq %d\n",dev->name,dev->irq); - printk("Descriptor head addresses:\n"); - printk("\t0x%lx 0x%lx\n",(u_long)lp->rx_ring, (u_long)lp->tx_ring); - printk("Descriptor addresses:\nRX: "); + printk("Descriptor head addresses (CPU):\n"); + printk(" 0x%lx 0x%lx\n",(u_long)lp->rx_ring, (u_long)lp->tx_ring); + printk("Descriptor addresses (CPU):\nRX: "); for (i=0;i<lp->rxRingMask;i++){ if (i < 3) { printk("0x%8.8lx ", (long) &lp->rx_ring[i].base); @@ -1819,7 +1854,7 @@ static void depca_dbg_open(struct net_device *dev) } } printk("...0x%8.8lx\n", (long) &lp->tx_ring[i].base); - printk("\nDescriptor buffers:\nRX: "); + printk("\nDescriptor buffers (Device):\nRX: "); for (i=0;i<lp->rxRingMask;i++){ if (i < 3) { printk("0x%8.8x ", readl(&lp->rx_ring[i].base)); @@ -1833,21 +1868,21 @@ static void depca_dbg_open(struct net_device *dev) } } printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base)); - printk("Initialisation block at 0x%8.8lx\n",lp->sh_mem); - printk("\tmode: 0x%4.4x\n",readw(&p->mode)); - printk("\tphysical address: "); + printk("Initialisation block at 0x%8.8lx(Phys)\n",virt_to_phys(lp->sh_mem)); + printk(" mode: 0x%4.4x\n",p->mode); + printk(" physical address: "); for (i=0;i<ETH_ALEN-1;i++){ - printk("%2.2x:",(u_char)readb(&p->phys_addr[i])); + printk("%2.2x:", p->phys_addr[i]); } - printk("%2.2x\n",(u_char)readb(&p->phys_addr[i])); - printk("\tmulticast hash table: "); + printk("%2.2x\n", p->phys_addr[i]); + printk(" multicast hash table: "); for (i=0;i<(HASH_TABLE_LEN >> 3)-1;i++){ - printk("%2.2x:",(u_char)readb(&p->mcast_table[i])); + printk("%2.2x:", p->mcast_table[i]); } - printk("%2.2x\n",(u_char)readb(&p->mcast_table[i])); - printk("\trx_ring at: 0x%8.8x\n",readl(&p->rx_ring)); - printk("\ttx_ring at: 0x%8.8x\n",readl(&p->tx_ring)); - printk("dma_buffs: 0x%8.8lx\n",lp->dma_buffs); + printk("%2.2x\n", p->mcast_table[i]); + printk(" rx_ring at: 0x%8.8x\n", p->rx_ring); + printk(" tx_ring at: 0x%8.8x\n", p->tx_ring); + printk("buffers (Phys): 0x%8.8lx\n",virt_to_phys(lp->sh_mem)+lp->buffs_offset); printk("Ring size:\nRX: %d Log2(rxRingMask): 0x%8.8x\n", (int)lp->rxRingMask + 1, lp->rx_rlen); @@ -2031,6 +2066,7 @@ cleanup_module(void) { struct depca_private *lp = thisDepca.priv; if (lp) { + iounmap(lp->sh_mem); #ifdef CONFIG_MCA if(lp->mca_slot != -1) mca_mark_as_unused(lp->mca_slot); diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index ab425dfee..53ded875a 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -127,34 +127,38 @@ int __init e2100_probe(struct net_device *dev) else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; - for (port = e21_probe_list; *port; port++) { - if (check_region(*port, E21_IO_EXTENT)) - continue; + for (port = e21_probe_list; *port; port++) if (e21_probe1(dev, *port) == 0) return 0; - } return -ENODEV; } int __init e21_probe1(struct net_device *dev, int ioaddr) { - int i, status; + int i, status, retval; unsigned char *station_addr = dev->dev_addr; static unsigned version_printed = 0; + if (!request_region(ioaddr, E21_IO_EXTENT, "e2100")) + return -ENODEV; + /* First check the station address for the Ctron prefix. */ if (inb(ioaddr + E21_SAPROM + 0) != 0x00 || inb(ioaddr + E21_SAPROM + 1) != 0x00 - || inb(ioaddr + E21_SAPROM + 2) != 0x1d) - return -ENODEV; + || inb(ioaddr + E21_SAPROM + 2) != 0x1d) { + retval = -ENODEV; + goto out; + } /* Verify by making certain that there is a 8390 at there. */ outb(E8390_NODMA + E8390_STOP, ioaddr); udelay(1); /* we want to delay one I/O cycle - which is 2MHz */ status = inb(ioaddr); - if (status != 0x21 && status != 0x23) - return -ENODEV; + if (status != 0x21 && status != 0x23) { + retval = -ENODEV; + goto out; + } /* Read the station address PROM. */ for (i = 0; i < 6; i++) @@ -166,20 +170,14 @@ int __init e21_probe1(struct net_device *dev, int ioaddr) if (ei_debug && version_printed++ == 0) printk(version); - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("e2100.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - - printk("%s: E21** at %#3x,", dev->name, ioaddr); for (i = 0; i < 6; i++) printk(" %02X", station_addr[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; + retval = -ENOMEM; + goto out; } if (dev->irq < 2) { @@ -191,14 +189,14 @@ int __init e21_probe1(struct net_device *dev, int ioaddr) } if (i >= 8) { printk(" unable to get IRQ %d.\n", dev->irq); - return -EAGAIN; + kfree(dev->priv); + dev->priv = NULL; + retval = -EAGAIN; + goto out; } } else if (dev->irq == 2) /* Fixup luser bogosity: IRQ2 is really IRQ9 */ dev->irq = 9; - /* Grab the region so we can find a different board if IRQ select fails. */ - request_region(ioaddr, E21_IO_EXTENT, "e2100"); - /* The 8390 is at the base address. */ dev->base_addr = ioaddr; @@ -248,6 +246,9 @@ int __init e21_probe1(struct net_device *dev, int ioaddr) NS8390_init(dev, 0); return 0; +out: + release_region(ioaddr, E21_IO_EXTENT); + return retval; } static int @@ -373,27 +374,14 @@ e21_close(struct net_device *dev) return 0; } -#ifdef HAVE_DEVLIST -struct netdev_entry e21_drv = -{"e21", e21_probe1, E21_IO_EXTENT, e21_probe_list}; -#endif - #ifdef MODULE #define MAX_E21_CARDS 4 /* Max number of E21 cards per module */ -static struct net_device dev_e21[MAX_E21_CARDS] = { - { - "", - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; - -static int io[MAX_E21_CARDS] = { 0, }; -static int irq[MAX_E21_CARDS] = { 0, }; -static int mem[MAX_E21_CARDS] = { 0, }; -static int xcvr[MAX_E21_CARDS] = { 0, }; /* choose int. or ext. xcvr */ +static struct net_device dev_e21[MAX_E21_CARDS]; +static int io[MAX_E21_CARDS]; +static int irq[MAX_E21_CARDS]; +static int mem[MAX_E21_CARDS]; +static int xcvr[MAX_E21_CARDS]; /* choose int. or ext. xcvr */ MODULE_PARM(io, "1-" __MODULE_STRING(MAX_E21_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_E21_CARDS) "i"); diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 882ed0744..cff64211b 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -530,12 +530,6 @@ static unsigned eeprom_reg = EEPROM_REG_PRO; If dev->base_addr == 2, allocate space for the device and return success (detachable devices only). */ -#ifdef HAVE_DEVLIST -/* Support for an alternate probe manager, which will eliminate the - boilerplate below. */ -struct netdev_entry netcard_drv = -{"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist}; -#else int __init eepro_probe(struct net_device *dev) { int i; @@ -589,7 +583,6 @@ int __init eepro_probe(struct net_device *dev) return -ENODEV; } -#endif void printEEPROMInfo(short ioaddr, struct net_device *dev) { diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index af419c80e..6ba26b3b9 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -34,12 +34,12 @@ static const char *version = /* A few user-configurable values that apply to all boards. First set is undocumented and spelled per Intel recommendations. */ -static int congenb = 0; /* Enable congestion control in the DP83840. */ +static int congenb; /* Enable congestion control in the DP83840. */ static int txfifo = 8; /* Tx FIFO threshold in 4 byte units, 0-15 */ static int rxfifo = 8; /* Rx FIFO threshold, default 32 bytes. */ /* Tx/Rx DMA burst length, 0-127, 0 == no preemption, tx==128 -> disabled. */ static int txdmacount = 128; -static int rxdmacount = 0; +static int rxdmacount; /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method. Lower values use more memory, but are faster. */ @@ -611,9 +611,9 @@ static int __devinit eepro100_init_one (struct pci_dev *pdev, unsigned long ioaddr; int irq; int acpi_idle_state = 0, pm; - static int cards_found = 0; + static int cards_found; - static int did_version = 0; /* Already printed version info. */ + static int did_version; /* Already printed version info. */ if (speedo_debug > 0 && did_version++ == 0) printk(version); diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c index cabe97e14..6a825f436 100644 --- a/drivers/net/es3210.c +++ b/drivers/net/es3210.c @@ -131,31 +131,31 @@ int __init es_probe(struct net_device *dev) if (ioaddr > 0x1ff) /* Check a single specified location. */ return es_probe1(dev, ioaddr); else if (ioaddr > 0) /* Don't probe at all. */ - return ENXIO; + return -ENXIO; if (!EISA_bus) { #if ES_DEBUG & ES_D_PROBE printk("es3210.c: Not EISA bus. Not probing high ports.\n"); #endif - return ENXIO; + return -ENXIO; } /* EISA spec allows for up to 16 slots, but 8 is typical. */ - for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { - if (check_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT)) - continue; + for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) if (es_probe1(dev, ioaddr) == 0) return 0; - } - return ENODEV; + return -ENODEV; } int __init es_probe1(struct net_device *dev, int ioaddr) { - int i; + int i, retval; unsigned long eisa_id; + if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210")) + return -ENODEV; + #if ES_DEBUG & ES_D_PROBE printk("es3210.c: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + ES_ID_PORT)); printk("es3210.c: config regs: %#x %#x %#x %#x %#x %#x\n", @@ -167,7 +167,8 @@ int __init es_probe1(struct net_device *dev, int ioaddr) /* Check the EISA ID of the card. */ eisa_id = inl(ioaddr + ES_ID_PORT); if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) { - return ENODEV; + retval = -ENODEV; + goto out; } /* Check the Racal vendor ID as well. */ @@ -178,13 +179,8 @@ int __init es_probe1(struct net_device *dev, int ioaddr) for(i = 0; i < ETHER_ADDR_LEN; i++) printk(" %02x", inb(ioaddr + ES_SA_PROM + i)); printk(" (invalid prefix).\n"); - return ENODEV; - } - - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("es3210.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); + retval = -ENODEV; + goto out; } printk("es3210.c: ES3210 rev. %ld at %#x, node", eisa_id>>24, ioaddr); @@ -216,7 +212,8 @@ int __init es_probe1(struct net_device *dev, int ioaddr) if (request_irq(dev->irq, ei_interrupt, 0, "es3210", dev)) { printk (" unable to get IRQ %d.\n", dev->irq); - return EAGAIN; + retval = -EAGAIN; + goto out; } if (dev->mem_start == 0) { @@ -225,8 +222,8 @@ int __init es_probe1(struct net_device *dev, int ioaddr) if (mem_enabled != 0x80) { printk(" shared mem disabled - giving up\n"); - free_irq(dev->irq, dev); - return -ENXIO; + retval = -ENXIO; + goto out1; } dev->mem_start = 0xC0000 + mem_bits*0x4000; printk(" using "); @@ -243,8 +240,8 @@ int __init es_probe1(struct net_device *dev, int ioaddr) /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (" unable to allocate memory for dev->priv.\n"); - free_irq(dev->irq, dev); - return -ENOMEM; + retval = -ENOMEM; + goto out1; } #if ES_DEBUG & ES_D_PROBE @@ -253,8 +250,6 @@ int __init es_probe1(struct net_device *dev, int ioaddr) #endif /* Note, point at the 8390, and not the card... */ dev->base_addr = ioaddr + ES_NIC_OFFSET; - request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210"); - ei_status.name = "ES3210"; ei_status.tx_start_page = ES_START_PG; @@ -274,6 +269,11 @@ int __init es_probe1(struct net_device *dev, int ioaddr) dev->stop = &es_close; NS8390_init(dev, 0); return 0; +out1: + free_irq(dev->irq, dev); +out: + release_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT); + return retval; } /* @@ -388,9 +388,9 @@ static struct net_device dev_es3210[MAX_ES_CARDS] = { }, }; -static int io[MAX_ES_CARDS] = { 0, }; -static int irq[MAX_ES_CARDS] = { 0, }; -static int mem[MAX_ES_CARDS] = { 0, }; +static int io[MAX_ES_CARDS]; +static int irq[MAX_ES_CARDS]; +static int mem[MAX_ES_CARDS]; MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ES_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ES_CARDS) "i"); diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index d1927ff70..d6e9759bf 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -484,7 +484,6 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) */ if(ioaddr < 0x1000) { - if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] != ioaddr) return -ENODEV; @@ -509,9 +508,6 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) outb(0x00, ioaddr + RESET); /* Reset some parts of chip */ BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* Disable the data link */ - if(dev == NULL) - dev = init_etherdev(0, 0); - if( (eth16i_debug & version_printed++) == 0) printk(KERN_INFO "%s", version); @@ -1392,20 +1388,12 @@ static ushort eth16i_parse_mediatype(const char* s) #define MAX_ETH16I_CARDS 4 /* Max number of Eth16i cards per module */ -static struct net_device dev_eth16i[MAX_ETH16I_CARDS] = { - { - "", - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; - -static int io[MAX_ETH16I_CARDS] = { 0, }; +static struct net_device dev_eth16i[MAX_ETH16I_CARDS]; +static int io[MAX_ETH16I_CARDS]; #if 0 -static int irq[MAX_ETH16I_CARDS] = { 0, }; +static int irq[MAX_ETH16I_CARDS]; #endif -static char* mediatype[MAX_ETH16I_CARDS] = { 0, }; +static char* mediatype[MAX_ETH16I_CARDS]; static int debug = -1; #if (LINUX_VERSION_CODE >= 0x20115) diff --git a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c index 2d4cfa298..8e76e9f6b 100644 --- a/drivers/net/fmv18x.c +++ b/drivers/net/fmv18x.c @@ -197,10 +197,6 @@ int __init fmv18x_probe1(struct net_device *dev, short ioaddr) return -EAGAIN; } - /* Allocate a new 'dev' if needed. */ - if (dev == NULL) - dev = init_etherdev(0, sizeof(struct net_local)); - /* Grab the region so that we can find another board if the IRQ request fails. */ request_region(ioaddr, FMV18X_IO_EXTENT, "fmv18x"); @@ -607,15 +603,10 @@ static void set_multicast_list(struct net_device *dev) } #ifdef MODULE -static char devicename[9] = { 0, }; -static struct net_device dev_fmv18x = { - devicename, /* device name is inserted by linux/drivers/net/net_init.c */ - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, fmv18x_probe }; +static struct net_device dev_fmv18x = { init: fmv18x_probe }; static int io = 0x220; -static int irq = 0; +static int irq; MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); diff --git a/drivers/net/hamradio/Makefile b/drivers/net/hamradio/Makefile index 7ca3c1efd..3c5e330b5 100644 --- a/drivers/net/hamradio/Makefile +++ b/drivers/net/hamradio/Makefile @@ -4,7 +4,7 @@ # # 19971130 Moved the amateur radio related network drivers from # drivers/net/ to drivers/hamradio for easier maintainance. -# Joerg Reuter DL1BKE <jreuter@poboxes.com> +# Joerg Reuter DL1BKE <jreuter@yaina.de> # # 20000806 Rewritten to use lists instead of if-statements. # Christoph Hellwig <hch@caldera.de> diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index cd6815df7..4e1bb8bf0 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -1506,7 +1506,7 @@ module_exit(cleanup_baycomepp); static int __init baycom_epp_setup(char *str) { - static unsigned __initlocaldata nr_dev = 0; + static unsigned __initdata nr_dev = 0; int ints[2]; if (nr_dev >= NR_PORTS) diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index 6319f983d..5f765d5bf 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -652,7 +652,7 @@ static void __exit bpq_cleanup_driver(void) unregister_netdev(&bpq->axdev); } -MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@poboxes.com>"); +MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@yaina.de>"); MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet"); module_init(bpq_init_driver); module_exit(bpq_cleanup_driver); diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 99d8c65aa..2ea55b0f1 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -130,9 +130,9 @@ vy 73, Joerg Reuter ampr-net: dl1bke@db0pra.ampr.org - AX-25 : DL1BKE @ DB0ACH.#NRW.DEU.EU - Internet: jreuter@poboxes.com - www : http://poboxes.com/jreuter/ + AX-25 : DL1BKE @ DB0ABH.#BAY.DEU.EU + Internet: jreuter@yaina.de + www : http://yaina.de/jreuter */ /* ----------------------------------------------------------------------- */ @@ -2226,8 +2226,8 @@ static void __exit scc_cleanup_driver(void) scc_net_procfs_remove(); } -MODULE_AUTHOR("Joerg Reuter <jreuter@poboxes.com>"); +MODULE_AUTHOR("Joerg Reuter <jreuter@yaina.de>"); MODULE_DESCRIPTION("AX.25 Device Driver for Z8530 based HDLC cards"); -MODULE_SUPPORTED_DEVICE("scc"); +MODULE_SUPPORTED_DEVICE("Z8530 based SCC cards for Amateur Radio"); module_init(scc_init_driver); module_exit(scc_cleanup_driver); diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 71952f54e..9d278a1cc 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -95,7 +95,7 @@ enum HP_Option { MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, }; int hp_plus_probe(struct net_device *dev); -int hpp_probe1(struct net_device *dev, int ioaddr); +static int hpp_probe1(struct net_device *dev, int ioaddr); static void hpp_reset_8390(struct net_device *dev); static int hpp_open(struct net_device *dev); @@ -116,12 +116,6 @@ static void hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hd /* Probe a list of addresses for an HP LAN+ adaptor. This routine is almost boilerplate. */ -#ifdef HAVE_DEVLIST -/* Support for an alternate probe manager, which will eliminate the - boilerplate below. */ -struct netdev_entry hpplus_drv = -{"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist}; -#else int __init hp_plus_probe(struct net_device *dev) { @@ -133,36 +127,30 @@ int __init hp_plus_probe(struct net_device *dev) else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; - for (i = 0; hpplus_portlist[i]; i++) { - int ioaddr = hpplus_portlist[i]; - if (check_region(ioaddr, HP_IO_EXTENT)) - continue; - if (hpp_probe1(dev, ioaddr) == 0) + for (i = 0; hpplus_portlist[i]; i++) + if (hpp_probe1(dev, hpplus_portlist[i]) == 0) return 0; - } return -ENODEV; } -#endif /* Do the interesting part of the probe at a single address. */ -int __init hpp_probe1(struct net_device *dev, int ioaddr) +static int __init hpp_probe1(struct net_device *dev, int ioaddr) { - int i; + int i, retval; unsigned char checksum = 0; const char *name = "HP-PC-LAN+"; int mem_start; static unsigned version_printed = 0; - /* Check for the HP+ signature, 50 48 0x 53. */ - if (inw(ioaddr + HP_ID) != 0x4850 - || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) + if (!request_region(ioaddr, HP_IO_EXTENT, "hp-plus")) return -ENODEV; - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("hp-plus.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); + /* Check for the HP+ signature, 50 48 0x 53. */ + if (inw(ioaddr + HP_ID) != 0x4850 + || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) { + retval = -ENODEV; + goto out; } if (ei_debug && version_printed++ == 0) @@ -183,7 +171,8 @@ int __init hpp_probe1(struct net_device *dev, int ioaddr) if (checksum != 0xff) { printk(" bad checksum %2.2x.\n", checksum); - return -ENODEV; + retval = -ENODEV; + goto out; } else { /* Point at the Software Configuration Flags. */ outw(ID_Page, ioaddr + HP_PAGING); @@ -193,12 +182,10 @@ int __init hpp_probe1(struct net_device *dev, int ioaddr) /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk ("hp-plus.c: unable to allocate memory for dev->priv.\n"); - return -ENOMEM; + retval = -ENOMEM; + goto out; } - /* Grab the region so we can find another board if something fails. */ - request_region(ioaddr, HP_IO_EXTENT,"hp-plus"); - /* Read the IRQ line. */ outw(HW_Page, ioaddr + HP_PAGING); { @@ -252,6 +239,9 @@ int __init hpp_probe1(struct net_device *dev, int ioaddr) outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION); return 0; +out: + release_region(ioaddr, HP_IO_EXTENT); + return retval; } static int diff --git a/drivers/net/hp.c b/drivers/net/hp.c index 4af1228a5..f36c341d2 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -79,10 +79,6 @@ static char irqmap[16] __initdata= { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0} /* Probe for an HP LAN adaptor. Also initialize the card and fill in STATION_ADDR with the station address. */ -#ifdef HAVE_DEVLIST -struct netdev_entry netcard_drv = -{"hp", hp_probe1, HP_IO_EXTENT, hppclan_portlist}; -#else int __init hp_probe(struct net_device *dev) { @@ -94,32 +90,32 @@ int __init hp_probe(struct net_device *dev) else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; - for (i = 0; hppclan_portlist[i]; i++) { - int ioaddr = hppclan_portlist[i]; - if (check_region(ioaddr, HP_IO_EXTENT)) - continue; - if (hp_probe1(dev, ioaddr) == 0) + for (i = 0; hppclan_portlist[i]; i++) + if (hp_probe1(dev, hppclan_portlist[i]) == 0) return 0; - } return -ENODEV; } -#endif int __init hp_probe1(struct net_device *dev, int ioaddr) { - int i, board_id, wordmode; + int i, retval, board_id, wordmode; const char *name; static unsigned version_printed = 0; + if (!request_region(ioaddr, HP_IO_EXTENT, "hp")) + return -ENODEV; + /* Check for the HP physical address, 08 00 09 xx xx xx. */ /* This really isn't good enough: we may pick up HP LANCE boards also! Avoid the lance 0x5757 signature. */ if (inb(ioaddr) != 0x08 || inb(ioaddr+1) != 0x00 || inb(ioaddr+2) != 0x09 - || inb(ioaddr+14) == 0x57) - return -ENODEV; + || inb(ioaddr+14) == 0x57) { + retval = -ENODEV; + goto out; + } /* Set up the parameters based on the board ID. If you have additional mappings, please mail them to me -djb. */ @@ -131,19 +127,14 @@ int __init hp_probe1(struct net_device *dev, int ioaddr) wordmode = 0; } - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("hp.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - if (ei_debug && version_printed++ == 0) printk(version); /* 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; + retval = -ENOMEM; + goto out; } printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr); @@ -173,24 +164,19 @@ int __init hp_probe1(struct net_device *dev, int ioaddr) } while (*++irqp); if (*irqp == 0) { printk(" no free IRQ lines.\n"); - kfree(dev->priv); - dev->priv = NULL; - return -EBUSY; + retval = -EBUSY; + goto out1; } } else { if (dev->irq == 2) dev->irq = 9; if (request_irq(dev->irq, ei_interrupt, 0, "hp", dev)) { printk (" unable to get IRQ %d.\n", dev->irq); - kfree(dev->priv); - dev->priv = NULL; - return -EBUSY; + retval = -EBUSY; + goto out1; } } - /* Grab the region so we can find another board if something fails. */ - request_region(ioaddr, HP_IO_EXTENT,"hp"); - /* Set the base address to point to the NIC, not the "real" base! */ dev->base_addr = ioaddr + NIC_OFFSET; dev->open = &hp_open; @@ -209,6 +195,12 @@ int __init hp_probe1(struct net_device *dev, int ioaddr) hp_init_card(dev); return 0; +out1: + kfree(dev->priv); + dev->priv = NULL; +out: + release_region(ioaddr, HP_IO_EXTENT); + return retval; } static int diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index d54857bb6..74938f954 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -46,6 +46,9 @@ ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** ** +** 1.57 -> 1.57b - Jean II +** - fix spinlocks, SMP is now working ! +** ** 1.56 -> 1.57 ** - updates for new PCI interface for 2.1 kernels ** @@ -701,7 +704,7 @@ static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, lp = (struct hp100_private *)dev->priv; memset( lp, 0, sizeof( struct hp100_private ) ); - lp->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&lp->lock); lp->id = eid; lp->chip = chip; lp->mode = local_mode; @@ -1585,9 +1588,11 @@ static int hp100_start_xmit_bm( struct sk_buff *skb, struct net_device *dev ) } else { - hp100_ints_off(); + spin_lock_irqsave (&lp->lock, flags); + hp100_ints_off(); /* Useful ? Jean II */ i = hp100_sense_lan( dev ); hp100_ints_on(); + spin_unlock_irqrestore (&lp->lock, flags); if ( i == HP100_LAN_ERR ) printk( "hp100: %s: link down detected\n", dev->name ); else @@ -1703,6 +1708,7 @@ static void hp100_clean_txring( struct net_device *dev ) /* tx function for slave modes */ static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ) { + unsigned long flags; int i, ok_flag; int ioaddr = dev->base_addr; u_short val; @@ -1759,9 +1765,11 @@ static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ) } else { - hp100_ints_off(); + spin_lock_irqsave (&lp->lock, flags); + hp100_ints_off(); /* Useful ? Jean II */ i = hp100_sense_lan( dev ); hp100_ints_on(); + spin_unlock_irqrestore (&lp->lock, flags); if ( i == HP100_LAN_ERR ) printk( "hp100: %s: link down detected\n", dev->name ); else @@ -1796,6 +1804,7 @@ static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ) #endif } + spin_lock_irqsave (&lp->lock, flags); hp100_ints_off(); val = hp100_inw( IRQ_STATUS ); /* Ack / clear the interrupt TX_COMPLETE interrupt - this interrupt is set @@ -1842,6 +1851,7 @@ static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ) lp->stats.tx_bytes += skb->len; dev->trans_start=jiffies; hp100_ints_on(); + spin_unlock_irqrestore (&lp->lock, flags); dev_kfree_skb_any( skb ); @@ -2104,16 +2114,20 @@ static void hp100_rx_bm( struct net_device *dev ) */ static hp100_stats_t *hp100_get_stats( struct net_device *dev ) { + unsigned long flags; int ioaddr = dev->base_addr; + struct hp100_private *lp = (struct hp100_private *)dev->priv; #ifdef HP100_DEBUG_B hp100_outw( 0x4215, TRACE ); #endif - hp100_ints_off(); + spin_lock_irqsave (&lp->lock, flags); + hp100_ints_off(); /* Useful ? Jean II */ hp100_update_stats( dev ); hp100_ints_on(); - return &((struct hp100_private *)dev->priv)->stats; + spin_unlock_irqrestore (&lp->lock, flags); + return &(lp->stats); } static void hp100_update_stats( struct net_device *dev ) @@ -2535,10 +2549,12 @@ static void hp100_start_interface( struct net_device *dev ) HP100_TX_ERROR | HP100_SET_LB , IRQ_MASK ); } + /* Note : before hp100_set_multicast_list(), because it will play with + * spinlock itself... Jean II */ + spin_unlock_irqrestore (&lp->lock, flags); + /* Enable MAC Tx and RX, set MAC modes, ... */ hp100_set_multicast_list( dev ); - - spin_unlock_irqrestore (&lp->lock, flags); } diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c index c69e52563..63fdd734b 100644 --- a/drivers/net/hplance.c +++ b/drivers/net/hplance.c @@ -106,15 +106,17 @@ static int __init hplance_init(struct net_device *dev, int scode) struct hplance_private *lp; int i; - if (dev == NULL) - dev = init_etherdev(0, sizeof(struct hplance_private)); - else - { - dev->priv = kmalloc(sizeof(struct hplance_private), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - memset(dev->priv, 0, sizeof(struct hplance_private)); - } +#ifdef MODULE + dev = init_etherdev(0, sizeof(struct hplance_private)); + if (!dev) + return -ENOMEM; +#else + dev->priv = kmalloc(sizeof(struct hplance_private), GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct hplance_private)); +#endif + printk("%s: HP LANCE; select code %d, addr", dev->name, scode); /* reset the board */ diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index fd2c79235..e12f65a79 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -178,7 +178,6 @@ int __init hydra_probe(struct net_device *dev) release_mem_region(base_addr, 0x20); continue; } - strcpy(z->name, "Hydra Ethernet Card"); dev = init_etherdev(NULL, sizeof(struct hydra_private)); diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 57d57d339..834300c28 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -74,7 +74,7 @@ static char *driver_name = "nsc-ircc"; /* Module parameters */ static int qos_mtt_bits = 0x07; /* 1 ms or more */ -static int dongle_id = 0; +static int dongle_id; /* Use BIOS settions by default, but user may supply module parameters */ static unsigned int io[] = { ~0, ~0, ~0, ~0 }; diff --git a/drivers/net/skeleton.c b/drivers/net/isa-skeleton.c index 8d6b193a2..c39defcd3 100644 --- a/drivers/net/skeleton.c +++ b/drivers/net/isa-skeleton.c @@ -1,4 +1,4 @@ -/* skeleton.c: A network driver outline for linux. +/* isa-skeleton.c: A network driver outline for linux. * * Written 1993-94 by Donald Becker. * @@ -22,7 +22,7 @@ */ static const char *version = - "skeleton.c:v1.51 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; + "isa-skeleton.c:v1.51 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; /* * Sources: @@ -131,14 +131,6 @@ extern void chipset_init(struct net_device *dev, int startp); * If dev->base_addr == 2, allocate space for the device and return success * (detachable devices only). */ -#ifdef HAVE_DEVLIST -/* - * Support for an alternate probe manager, - * which will eliminate the boilerplate below. - */ -struct netdev_entry netcard_drv = -{cardname, netcard_probe1, NETCARD_IO_EXTENT, netcard_portlist}; -#else int __init netcard_probe(struct net_device *dev) { @@ -160,7 +152,6 @@ netcard_probe(struct net_device *dev) return -ENODEV; } -#endif /* * This is the real probe routine. Linux has a history of friendly device @@ -184,18 +175,6 @@ static int __init netcard_probe1(struct net_device *dev, int ioaddr) return -ENODEV; } - /* Allocate a new 'dev' if needed. */ - if (dev == NULL) { - /* - * Don't allocate the private data here, it is done later - * This makes it easier to free the memory when this driver - * is used as a module. - */ - dev = init_etherdev(0, 0); - if (dev == NULL) - return -ENOMEM; - } - if (net_debug && version_printed++ == 0) printk(KERN_DEBUG "%s", version); @@ -654,17 +633,11 @@ set_multicast_list(struct net_device *dev) #ifdef MODULE -static char devicename[9] = { 0, }; -static struct net_device this_device = { - devicename, /* will be inserted by linux/drivers/net/net_init.c */ - 0, 0, 0, 0, - 0, 0, /* I/O address, IRQ */ - 0, 0, 0, NULL, netcard_probe }; - +static struct net_device this_device = { init: netcard_probe }; static int io = 0x300; -static int irq = 0; -static int dma = 0; -static int mem = 0; +static int irq; +static int dma; +static int mem; int init_module(void) { diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index ebee89f9f..8e70d45f1 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -144,12 +144,9 @@ static int __init sonic_probe1(struct net_device *dev, return -ENODEV; } - request_region(base_addr, 0x100, "SONIC"); + if (!request_region(base_addr, 0x100, dev->name)) + return -EBUSY; - /* Allocate a new 'dev' if needed. */ - if (dev == NULL) - dev = init_etherdev(0, sizeof(struct sonic_local)); - if (sonic_debug && version_printed++ == 0) printk(version); diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c index 6cfd71f15..c1674c550 100644 --- a/drivers/net/lne390.c +++ b/drivers/net/lne390.c @@ -382,9 +382,9 @@ static struct net_device dev_lne[MAX_LNE_CARDS] = { }, }; -static int io[MAX_LNE_CARDS] = { 0, }; -static int irq[MAX_LNE_CARDS] = { 0, }; -static int mem[MAX_LNE_CARDS] = { 0, }; +static int io[MAX_LNE_CARDS]; +static int irq[MAX_LNE_CARDS]; +static int mem[MAX_LNE_CARDS]; MODULE_PARM(io, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i"); diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index e02298ded..254b42880 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -24,6 +24,8 @@ Version 1.0.1: - Spinlock fixes - Bug fixes and better intr performance (Tjeerd) + Version 1.0.2: + - Now reads correct MAC address from eeprom */ @@ -33,7 +35,7 @@ static const char version1[] = static const char version2[] = " http://www.scyld.com/network/natsemi.html\n"; static const char version3[] = -" (unofficial 2.4.x kernel port, version 1.0.1, September 5, 2000 Jeff Garzik, Tjeerd Mulder)\n"; +" (unofficial 2.4.x kernel port, version 1.0.2, October 6, 2000 Jeff Garzik, Tjeerd Mulder)\n"; /* Updated to recommendations in pci-skeleton v2.03. */ /* Automatically extracted configuration info: @@ -405,8 +407,13 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, printk(KERN_INFO "%s: %s at 0x%lx, ", dev->name, natsemi_pci_info[chip_idx].name, ioaddr); - for (i = 0; i < ETH_ALEN/2; i++) - ((u16 *)dev->dev_addr)[i] = be16_to_cpu(eeprom_read(ioaddr, i + 7)); + for (i = 0; i < ETH_ALEN/2; i++) { + /* weird organization */ + unsigned short a; + a = (le16_to_cpu(eeprom_read(ioaddr, i + 6)) >> 15) + + (le16_to_cpu(eeprom_read(ioaddr, i + 7)) << 1); + ((u16 *)dev->dev_addr)[i] = a; + } for (i = 0; i < ETH_ALEN-1; i++) printk("%2.2x:", dev->dev_addr[i]); printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); @@ -513,7 +520,8 @@ static int eeprom_read(long addr, int location) for (i = 16; i > 0; i--) { writel(EE_ChipSelect | EE_ShiftClk, ee_addr); eeprom_delay(ee_addr); - retval = (retval << 1) | ((readl(ee_addr) & EE_DataOut) ? 1 : 0); + /* data bits are LSB first */ + retval = (retval >> 1) | ((readl(ee_addr) & EE_DataOut) ? 0x8000 : 0); writel(EE_ChipSelect, ee_addr); eeprom_delay(ee_addr); } diff --git a/drivers/net/ne.c b/drivers/net/ne.c index e2ed67aaa..806f1e114 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -175,11 +175,6 @@ static void ne_block_output(struct net_device *dev, const int count, E2010 starts at 0x100 and ends at 0x4000. E2010-x starts at 0x100 and ends at 0xffff. */ -#ifdef HAVE_DEVLIST -struct netdev_entry netcard_drv = -{"ne", ne_probe1, NE_IO_EXTENT, netcard_portlist}; -#else - /* * Note that at boot, this probe only picks up one card at a time, even for * multiple PCI ne2k cards. Use "ether=0,0,eth1" if you have a second PCI @@ -220,7 +215,6 @@ int __init ne_probe(struct net_device *dev) return -ENODEV; } -#endif #ifdef CONFIG_PCI static int __init ne_probe_pci(struct net_device *dev) @@ -328,13 +322,6 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) } } - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) - { - printk(KERN_ERR "ne.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - if (ei_debug && version_printed++ == 0) printk(version); @@ -805,19 +792,10 @@ retry: #ifdef MODULE #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ -#define NAMELEN 8 /* # of chars for storing dev->name */ -static struct net_device dev_ne[MAX_NE_CARDS] = { - { - "", - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; - -static int io[MAX_NE_CARDS] = { 0, }; -static int irq[MAX_NE_CARDS] = { 0, }; -static int bad[MAX_NE_CARDS] = { 0, }; /* 0xbad = bad sig or no reset ack */ +static struct net_device dev_ne[MAX_NE_CARDS]; +static int io[MAX_NE_CARDS]; +static int irq[MAX_NE_CARDS]; +static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */ MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c index b780ee175..2a558e20e 100644 --- a/drivers/net/ne2.c +++ b/drivers/net/ne2.c @@ -207,12 +207,6 @@ static int __init ne2_probe1(struct net_device *dev, int slot) int start_page, stop_page; static unsigned version_printed = 0; - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk(KERN_ERR "ne2.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - if (ei_debug && version_printed++ == 0) printk(version); @@ -619,18 +613,10 @@ retry: #ifdef MODULE #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ -static struct net_device dev_ne[MAX_NE_CARDS] = { - { - "", - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; - -static int io[MAX_NE_CARDS] = { 0, }; -static int irq[MAX_NE_CARDS] = { 0, }; -static int bad[MAX_NE_CARDS] = { 0, }; /* 0xbad = bad sig or no reset ack */ +static struct net_device dev_ne[MAX_NE_CARDS]; +static int io[MAX_NE_CARDS]; +static int irq[MAX_NE_CARDS]; +static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */ #ifdef MODULE_PARM MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c index 1fceea2fd..02b70351b 100644 --- a/drivers/net/ne3210.c +++ b/drivers/net/ne3210.c @@ -157,12 +157,6 @@ int __init ne3210_probe1(struct net_device *dev, int ioaddr) } #endif - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("ne3210.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk ("ne3210.c: unable to allocate memory for dev->priv!\n"); @@ -360,18 +354,10 @@ static int ne3210_close(struct net_device *dev) #ifdef MODULE #define MAX_NE3210_CARDS 4 /* Max number of NE3210 cards per module */ -static struct net_device dev_ne3210[MAX_NE3210_CARDS] = { - { - "", - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; - -static int io[MAX_NE3210_CARDS] = { 0, }; -static int irq[MAX_NE3210_CARDS] = { 0, }; -static int mem[MAX_NE3210_CARDS] = { 0, }; +static struct net_device dev_ne3210[MAX_NE3210_CARDS]; +static int io[MAX_NE3210_CARDS]; +static int irq[MAX_NE3210_CARDS]; +static int mem[MAX_NE3210_CARDS]; MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i"); diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index c9e8c1ff7..7e11e5483 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c @@ -235,14 +235,6 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr) PRINTK2((KERN_DEBUG "%s: I/O #3 passed!\n", dev->name)); - if (dev == NULL) { - dev = init_etherdev(0,0); - if (dev == NULL) { - printk(KERN_WARNING "%s: Failed to allocate device memory\n", boardname); - return -ENOMEM; - } - } - if (NI5010_DEBUG && version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -741,14 +733,9 @@ static void show_registers(struct net_device *dev) } #ifdef MODULE -static struct net_device dev_ni5010 = { - "", - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, ni5010_probe }; - -int io = 0; -int irq = 0; +static struct net_device dev_ni5010 = { init: ni5010_probe }; +static int io; +static int irq; MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c index 910906aa2..9efbd33ef 100644 --- a/drivers/net/ni52.c +++ b/drivers/net/ni52.c @@ -362,11 +362,9 @@ int __init ni52_probe(struct net_device *dev) #endif int base_addr = dev->base_addr; - if (base_addr > 0x1ff) { /* Check a single specified location. */ - if( (inb(base_addr+NI52_MAGIC1) == NI52_MAGICVAL1) && - (inb(base_addr+NI52_MAGIC2) == NI52_MAGICVAL2)) - return ni52_probe1(dev, base_addr); - } else if (base_addr > 0) /* Don't probe at all. */ + if (base_addr > 0x1ff) /* Check a single specified location. */ + return ni52_probe1(dev, base_addr); + else if (base_addr > 0) /* Don't probe at all. */ return -ENXIO; #ifdef MODULE @@ -374,29 +372,15 @@ int __init ni52_probe(struct net_device *dev) #else for (port = ports; *port; port++) { int ioaddr = *port; - if (check_region(ioaddr, NI52_TOTAL_SIZE)) - continue; - if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || - !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2)) - continue; - dev->base_addr = ioaddr; if (ni52_probe1(dev, ioaddr) == 0) return 0; } #ifdef FULL_IO_PROBE - for(dev->base_addr=0x200;dev->base_addr<0x400;dev->base_addr+=8) - { - int ioaddr = dev->base_addr; - if (check_region(ioaddr, NI52_TOTAL_SIZE)) - continue; - if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || - !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2)) - continue; - if (ni52_probe1(dev, ioaddr) == 0) + for(dev->base_addr=0x200; dev->base_addr<0x400; dev->base_addr+=8) + if (ni52_probe1(dev, dev->base_addr) == 0) return 0; - } #endif #endif @@ -407,33 +391,42 @@ int __init ni52_probe(struct net_device *dev) static int __init ni52_probe1(struct net_device *dev,int ioaddr) { - int i,size; + int i, size, retval; + + if (!request_region(ioaddr, NI52_TOTAL_SIZE, "ni5210")) + return -ENODEV; + + if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || + !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2)) { + retval = -ENODEV; + goto out; + } for(i=0;i<ETH_ALEN;i++) dev->dev_addr[i] = inb(dev->base_addr+i); if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1 - || dev->dev_addr[2] != NI52_ADDR2) - return -ENODEV; + || dev->dev_addr[2] != NI52_ADDR2) { + retval = -ENODEV; + goto out; + } printk("%s: NI5210 found at %#3lx, ",dev->name,dev->base_addr); - request_region(ioaddr,NI52_TOTAL_SIZE,"ni5210"); - /* * check (or search) IO-Memory, 8K and 16K */ #ifdef MODULE size = dev->mem_end - dev->mem_start; - if(size != 0x2000 && size != 0x4000) - { + if(size != 0x2000 && size != 0x4000) { printk("\n%s: Illegal memory size %d. Allowed is 0x2000 or 0x4000 bytes.\n",dev->name,size); - return -ENODEV; + retval = -ENODEV; + goto out; } - if(!check586(dev,(char *) dev->mem_start,size)) - { + if(!check586(dev,(char *) dev->mem_start,size)) { printk("?memcheck, Can't find memory at 0x%lx with size %d!\n",dev->mem_start,size); - return -ENODEV; + retval = -ENODEV; + goto out; } #else if(dev->mem_start != 0) /* no auto-mem-probe */ @@ -443,7 +436,8 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr) size = 0x2000; /* check for 8K mem */ if(!check586(dev,(char *) dev->mem_start,size)) { printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start); - return -ENODEV; + retval = -ENODEV; + goto out; } } } @@ -455,7 +449,8 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr) { if(!memaddrs[i]) { printk("?memprobe, Can't find io-memory!\n"); - return -ENODEV; + retval = -ENODEV; + goto out; } dev->mem_start = memaddrs[i]; size = 0x2000; /* check for 8K mem */ @@ -470,10 +465,10 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr) #endif dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); - if(dev->priv == NULL) - { + if(dev->priv == NULL) { printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name); - return -ENOMEM; + retval = -ENOMEM; + goto out; } /* warning: we don't free it on errors */ memset((char *) dev->priv,0,sizeof(struct priv)); @@ -498,7 +493,10 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr) if(!(dev->irq = autoirq_report(2))) { printk("?autoirq, Failed to detect IRQ line!\n"); - return 1; + kfree(dev->priv); + dev->priv = NULL; + retval = -EAGAIN; + goto out; } printk("IRQ %d (autodetected).\n",dev->irq); } @@ -521,6 +519,9 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr) ether_setup(dev); return 0; +out: + release_region(ioaddr, NI52_TOTAL_SIZE); + return retval; } /********************************************** diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 7f3f76ebf..a5b83887a 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -117,7 +117,7 @@ static int irq_list[4] = { -1 }; static int max_interrupt_work = 32; /* Force full duplex modes? */ -static int full_duplex = 0; +static int full_duplex; /* To minimize the size of the driver source and make the driver more readable not all constants are symbolically defined. @@ -511,11 +511,11 @@ static void tc574_config(dev_link_t *link) /* Roadrunner only: Turn on the MII transceiver */ outw(0x8040, ioaddr + Wn3_Options); - udelay(1000); + mdelay(1); outw(0xc040, ioaddr + Wn3_Options); wait_for_completion(dev, TxReset); wait_for_completion(dev, RxReset); - udelay(1000); + mdelay(1); outw(0x8040, ioaddr + Wn3_Options); EL3WINDOW(4); @@ -783,11 +783,11 @@ static void tc574_reset(struct net_device *dev) /* Roadrunner only: Turn on the MII transceiver. */ outw(0x8040, ioaddr + Wn3_Options); - udelay(1000); + mdelay(1); outw(0xc040, ioaddr + Wn3_Options); wait_for_completion(dev, TxReset); wait_for_completion(dev, RxReset); - udelay(1000); + mdelay(1); outw(0x8040, ioaddr + Wn3_Options); /* Switch to the stats window, and clear all stats by reading. */ diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 3cbba20b9..7ba0c4e18 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -4,7 +4,7 @@ Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net - 3c589_cs.c 1.153 2000/06/12 21:27:25 + 3c589_cs.c 1.154 2000/09/30 17:39:04 The network driver code is based on Donald Becker's 3c589 code: @@ -117,7 +117,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"3c589_cs.c 1.153 2000/06/12 21:27:25 (David Hinds)"; +"3c589_cs.c 1.154 2000/09/30 17:39:04 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -1007,36 +1007,19 @@ static int el3_rx(struct net_device *dev) return 0; } -/* Set or clear the multicast filter for this adapter. - num_addrs == -1 Promiscuous mode, receive all packets - num_addrs == 0 Normal mode, clear multicast list - num_addrs > 0 Multicast mode, receive normal and MC packets, and do - best-effort filtering. - */ static void set_multicast_list(struct net_device *dev) { struct el3_private *lp = dev->priv; dev_link_t *link = &lp->link; ioaddr_t ioaddr = dev->base_addr; + u_short opts = SetRxFilter | RxStation | RxBroadcast; if (!(DEV_OK(link))) return; -#ifdef PCMCIA_DEBUG - if (pc_debug > 2) { - static int old = 0; - if (old != dev->mc_count) { - old = dev->mc_count; - DEBUG(0, "%s: setting Rx mode to %d addresses.\n", - dev->name, old); - } - } -#endif if (dev->flags & IFF_PROMISC) - outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm, - ioaddr + EL3_CMD); + opts |= RxMulticast | RxProm; else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) - outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); - else - outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); + opts |= RxMulticast; + outw(opts, ioaddr + EL3_CMD); } static int el3_close(struct net_device *dev) diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 8be4b7a62..8bb6d0a04 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -1,5 +1,5 @@ /*====================================================================== - fmvj18x_cs.c,v 1.9 1996/08/06 03:13:53 root Exp + fmvj18x_cs.c,v 2.0 2000/10/01 03:13:53 root Exp A fmvj18x (and its compatibles) PCMCIA client driver @@ -88,7 +88,7 @@ MODULE_PARM(sram_config, "i"); */ #ifdef PCMCIA_DEBUG static char *version = - "fmvj18x_cs.c,v 1.9 1996/08/06 03:13:53 root Exp"; + "fmvj18x_cs.c,v 2.0 2000/10/01 03:13:53 root Exp"; #endif /*====================================================================*/ @@ -122,7 +122,9 @@ static dev_link_t *dev_list = NULL; /* card type */ -typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501 } cardtype_t; +typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN } cardtype_t; + +#define MANFID_UNGERMANN 0x02c0 /* driver specific data structure @@ -169,6 +171,7 @@ typedef struct local_info_t { #define LAN_CTRL 16 /* LAN card control register */ #define MAC_ID 0x1a /* hardware address */ +#define UNGERMANN_MAC_ID 0x18 /* UNGERMANN-BASS hardware address */ /* control bits @@ -237,6 +240,10 @@ typedef struct local_info_t { #define TX_TIMEOUT ((400*HZ)/1000) +#define BANK_0U 0x20 /* bank 0 (CONFIG_1) */ +#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */ +#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */ + /*====================================================================== This bit of code is used to avoid unregistering network devices @@ -388,7 +395,7 @@ static void fmvj18x_config(dev_link_t *link) tuple_t tuple; cisparse_t parse; u_short buf[32]; - int i, last_fn, last_ret; + int i, last_fn, last_ret, ret; ioaddr_t ioaddr; cardtype_t cardtype; char *card_name = "unknown"; @@ -424,9 +431,10 @@ static void fmvj18x_config(dev_link_t *link) CS_CHECK(ParseTuple, handle, &tuple, &parse); link->conf.ConfigIndex = parse.cftable_entry.index; tuple.DesiredTuple = CISTPL_MANFID; - CS_CHECK(GetFirstTuple, handle, &tuple); - CS_CHECK(GetTupleData, handle, &tuple); - + if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) + CS_CHECK(GetTupleData, handle, &tuple); + else + buf[0] = 0xffff; switch (le16_to_cpu(buf[0])) { case MANFID_TDK: cardtype = TDK; @@ -447,10 +455,39 @@ static void fmvj18x_config(dev_link_t *link) } } else { /* old type card */ - cardtype = MBH10302; - link->conf.ConfigIndex = 1; + tuple.DesiredTuple = CISTPL_MANFID; + if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) + CS_CHECK(GetTupleData, handle, &tuple); + else + buf[0] = 0xffff; + switch (le16_to_cpu(buf[0])) { + case MANFID_UNGERMANN: + cardtype = UNGERMANN; + /* + Ungermann-Bass Access/CARD accepts 0x300,0x320,0x340,0x360 + 0x380,0x3c0 only for ioport. + */ + for (link->io.BasePort1 = 0x300; link->io.BasePort1 < 0x3e0; + link->io.BasePort1 += 0x20) { + ret = CardServices(RequestIO, link->handle, &link->io); + if (ret == CS_SUCCESS) { + /* calculate ConfigIndex value */ + link->conf.ConfigIndex = + ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22; + goto req_irq; + } + } + /* if ioport allocation is failed, goto failed */ + printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); + goto failed; + default: + cardtype = MBH10302; + link->conf.ConfigIndex = 1; + } } + CS_CHECK(RequestIO, link->handle, &link->io); +req_irq: CS_CHECK(RequestIRQ, link->handle, &link->irq); CS_CHECK(RequestConfiguration, link->handle, &link->conf); dev->irq = link->irq.AssignedIRQ; @@ -463,7 +500,11 @@ static void fmvj18x_config(dev_link_t *link) ioaddr = dev->base_addr; /* Power On chip and select bank 0 */ - outb(BANK_0, ioaddr + CONFIG_1); + if(cardtype == UNGERMANN) + outb(BANK_0U, ioaddr + CONFIG_1); + else + outb(BANK_0, ioaddr + CONFIG_1); + /* Reset controler */ if( sram_config == 0 ) outb(CONFIG0_RST, ioaddr + CONFIG_0); @@ -503,6 +544,12 @@ static void fmvj18x_config(dev_link_t *link) for (i = 0; i < 6; i++) dev->dev_addr[i] = node_id[i]; break; + case UNGERMANN: + /* Read MACID from register */ + for (i = 0; i < 6; i++) + dev->dev_addr[i] = inb(ioaddr + UNGERMANN_MAC_ID + i); + card_name = "Access/CARD"; + break; case MBH10302: default: /* Read MACID from register */ @@ -806,7 +853,11 @@ static void fjn_reset(struct net_device *dev) DEBUG(4, "fjn_reset(%s) called.\n",dev->name); /* Power On chip and select bank 0 */ - outb(BANK_0, ioaddr + CONFIG_1); + if( lp->cardtype == UNGERMANN) + outb(BANK_0U, ioaddr + CONFIG_1); + else + outb(BANK_0, ioaddr + CONFIG_1); + /* Reset buffers */ if( sram_config == 0 ) outb(CONFIG0_RST, ioaddr + CONFIG_0); @@ -823,14 +874,20 @@ static void fjn_reset(struct net_device *dev) outb(dev->dev_addr[i], ioaddr + NODE_ID + i); /* Switch to bank 1 */ - outb(BANK_1, ioaddr + CONFIG_1); + if ( lp->cardtype == UNGERMANN ) + outb(BANK_1U, ioaddr + CONFIG_1); + else + outb(BANK_1, ioaddr + CONFIG_1); /* set the multicast table to accept none. */ for (i = 0; i < 6; i++) outb(0x00, ioaddr + MAR_ADR + i); /* Switch to bank 2 (runtime mode) */ - outb(BANK_2, ioaddr + CONFIG_1); + if ( lp->cardtype == UNGERMANN ) + outb(BANK_2U, ioaddr + CONFIG_1); + else + outb(BANK_2, ioaddr + CONFIG_1); /* set 16col ctrl bits */ if( lp->cardtype == TDK ) diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 0f9552961..21ced0318 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -11,7 +11,7 @@ Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net - pcnet_cs.c 1.124 2000/07/21 19:47:31 + pcnet_cs.c 1.126 2000/10/02 20:38:23 The network driver code is based on Donald Becker's NE2000 code: @@ -72,7 +72,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"pcnet_cs.c 1.124 2000/07/21 19:47:31 (David Hinds)"; +"pcnet_cs.c 1.126 2000/10/02 20:38:23 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -81,39 +81,22 @@ static char *version = /* Parameters that can be set with 'insmod' */ +#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") + /* Bit map of interrupts to choose from */ -static u_int irq_mask = 0xdeb8; +INT_MODULE_PARM(irq_mask, 0xdeb8); static int irq_list[4] = { -1 }; +MODULE_PARM(irq_list, "1-4i"); -/* Transceiver type, for Socket EA and IBM CC cards. */ -static int if_port = 1; - -/* Use 64K packet buffer, for Socket EA cards. */ -static int use_big_buf = 1; - -/* Shared memory speed, in ns */ -static int mem_speed = 0; - -/* Insert a pause in block_output after sending a packet */ -static int delay_output = 0; - -/* Length of delay, in microseconds */ -static int delay_time = 4; - -/* Use shared memory, if available? */ -static int use_shmem = -1; +INT_MODULE_PARM(if_port, 1); /* Transceiver type */ +INT_MODULE_PARM(use_big_buf, 1); /* use 64K packet buffer? */ +INT_MODULE_PARM(mem_speed, 0); /* shared mem speed, in ns */ +INT_MODULE_PARM(delay_output, 0); /* pause after xmit? */ +INT_MODULE_PARM(delay_time, 4); /* in usec */ +INT_MODULE_PARM(use_shmem, -1); /* use shared memory? */ /* Ugh! Let the user hardwire the hardware address for queer cards */ static int hw_addr[6] = { 0, /* ... */ }; - -MODULE_PARM(irq_mask, "i"); -MODULE_PARM(irq_list, "1-4i"); -MODULE_PARM(if_port, "i"); -MODULE_PARM(use_big_buf, "i"); -MODULE_PARM(mem_speed, "i"); -MODULE_PARM(delay_output, "i"); -MODULE_PARM(delay_time, "i"); -MODULE_PARM(use_shmem, "i"); MODULE_PARM(hw_addr, "6i"); /*====================================================================*/ @@ -465,7 +448,7 @@ static hw_info_t *get_prom(dev_link_t *link) }; pcnet_reset_8390(dev); - udelay(10000); + mdelay(10); for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); @@ -1046,7 +1029,7 @@ static void pcnet_reset_8390(struct net_device *dev) for (i = 0; i < 100; i++) { if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0) break; - udelay(100L); + udelay(100); } outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index cf98d7401..bf3255978 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -247,25 +247,16 @@ static char *version = /*====================================================================*/ /* Parameters that can be set with 'insmod' */ -static int if_port = 0; -MODULE_PARM(if_port, "i"); -/* Bit map of interrupts to choose from */ -/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ -static u_long irq_mask = 0xdeb8; -MODULE_PARM(irq_mask, "i"); +#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") static int irq_list[4] = { -1 }; MODULE_PARM(irq_list, "1-4i"); - -static int do_sound = 1; -MODULE_PARM(do_sound, "i"); - -static int card_type = 0; -MODULE_PARM(card_type, "i"); /* dummy, not used anymore */ - -static int lockup_hack = 0; -MODULE_PARM(lockup_hack, "i"); /* anti lockup hack */ +INT_MODULE_PARM(irq_mask, 0xdeb8); +INT_MODULE_PARM(if_port, 0); +INT_MODULE_PARM(full_duplex, 0); +INT_MODULE_PARM(do_sound, 1); +INT_MODULE_PARM(lockup_hack, 0); /* anti lockup hack */ /*====================================================================*/ @@ -601,29 +592,6 @@ mii_wr(ioaddr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len) mii_idle(ioaddr); } -#ifdef PCMCIA_DEBUG -static void -mii_dump(struct net_device *dev) -{ - ioaddr_t ioaddr = dev->base_addr; - int i; - - /* Note that registers 14, 1d,1e and 1f are reserved and should - * not be read according to the DP83840A specs. - */ - printk(KERN_DEBUG "%s: MII register dump:\n", dev->name); - for (i=0; i < 32; i++) { - if (!(i % 8)) { - if (i) - printk("\n"); - printk(KERN_DEBUG "%s:", dev->name); - } - printk(" %04x", mii_rd(ioaddr, 0, i)); - } - printk("\n"); -} -#endif - /*============= Main bulk of functions =========================*/ /**************** @@ -1706,12 +1674,6 @@ do_config(struct net_device *dev, struct ifmap *map) dev->name, if_names[dev->if_port]); do_reset(dev,1); /* not the fine way :-) */ } - #ifdef PCMCIA_DEBUG - else if (local->mohawk) { - /* kludge to print the mii regsiters */ - mii_dump(dev); - } - #endif return 0; } @@ -1903,6 +1865,8 @@ do_reset(struct net_device *dev, int full) PutByte(XIRCREG42_SWC1, 0x80); busy_loop(HZ/25); /* wait 40 msec to let it complete */ } + if (full_duplex) + PutByte(XIRCREG1_ECR, GetByte(XIRCREG1_ECR | FullDuplex)); } else { /* No MII */ SelectPage(0); value = GetByte(XIRCREG_ESR); /* read the ESR */ @@ -1957,12 +1921,6 @@ init_mii(struct net_device *dev) unsigned control, status, linkpartner; int i; - #ifdef PCMCIA_DEBUG - if (pc_debug>1) { - mii_dump(dev); - } - #endif - status = mii_rd(ioaddr, 0, 1); if ((status & 0xff00) != 0x7800) return 0; /* No MII */ @@ -2019,11 +1977,6 @@ init_mii(struct net_device *dev) } } - #ifdef PCMCIA_DEBUG - if (pc_debug) - mii_dump(dev); - #endif - return 1; } @@ -2077,8 +2030,6 @@ init_xirc2ps_cs(void) servinfo_t serv; printk(KERN_INFO "%s\n", version); - if (card_type) - printk(KINF_XIRC "option card_type is obsolete\n"); if (lockup_hack) printk(KINF_XIRC "lockup hack is enabled\n"); CardServices(GetCardServicesInfo, &serv); diff --git a/drivers/net/pcmcia/xircom_tulip_cb.c b/drivers/net/pcmcia/xircom_tulip_cb.c index aff697033..c5f5d34de 100644 --- a/drivers/net/pcmcia/xircom_tulip_cb.c +++ b/drivers/net/pcmcia/xircom_tulip_cb.c @@ -28,9 +28,9 @@ static int max_interrupt_work = 25; #define MAX_UNITS 8 /* Used to pass the full-duplex flag, etc. */ -static int full_duplex[MAX_UNITS] = {0, }; -static int options[MAX_UNITS] = {0, }; -static int mtu[MAX_UNITS] = {0, }; /* Jumbo MTU for interfaces. */ +static int full_duplex[MAX_UNITS]; +static int options[MAX_UNITS]; +static int mtu[MAX_UNITS]; /* Jumbo MTU for interfaces. */ /* The possible media types that can be set in options[] are: */ static const char * const medianame[] = { @@ -506,12 +506,12 @@ static struct net_device *tulip_probe1(struct pci_dev *pdev, struct net_device *dev, long ioaddr, int irq, int chip_idx, int board_idx) { - static int did_version = 0; /* Already printed version info. */ + static int did_version; /* Already printed version info. */ struct tulip_private *tp; /* See note below on the multiport cards. */ static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; - static int last_irq = 0; - static int multiport_cnt = 0; /* For four-port boards w/one EEPROM */ + static int last_irq; + static int multiport_cnt; /* For four-port boards w/one EEPROM */ u8 chip_rev; int i; unsigned short sum; @@ -913,9 +913,9 @@ static const char * block_name[] = {"21140 non-MII", "21140 MII PHY", static void parse_eeprom(struct net_device *dev) { /* The last media info list parsed, for multiport boards. */ - static struct mediatable *last_mediatable = NULL; - static unsigned char *last_ee_data = NULL; - static int controller_index = 0; + static struct mediatable *last_mediatable; + static unsigned char *last_ee_data; + static int controller_index; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; unsigned char *ee_data = tp->eeprom; @@ -3074,7 +3074,7 @@ MODULE_DEVICE_TABLE(pci, tulip_pci_table); static int __devinit tulip_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct net_device *dev; - static int board_idx = 0; + static int board_idx; printk(KERN_INFO "tulip_attach(%s)\n", pdev->slot_name); diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 44276a3d9..976dd5781 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -42,7 +42,7 @@ static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, static int pcnet32_debug = 1; static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */ -static struct net_device *pcnet32_dev = NULL; +static struct net_device *pcnet32_dev; static const int max_interrupt_work = 80; static const int rx_copybreak = 200; @@ -83,8 +83,8 @@ static unsigned char options_mapping[] = { }; #define MAX_UNITS 8 -static int options[MAX_UNITS] = {0, }; -static int full_duplex[MAX_UNITS] = {0, }; +static int options[MAX_UNITS]; +static int full_duplex[MAX_UNITS]; /* * Theory of Operation @@ -476,7 +476,7 @@ static int __init pcnet32_probe_vlbus(int cards_found) static int __init pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent) { - static int card_idx = 0; + static int card_idx; long ioaddr; int err = 0; @@ -683,11 +683,11 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car if (fdx && !(lp->options & PORT_ASEL) && full_duplex[card_idx]) lp->options |= PORT_FD; - lp->a = *a; if (a == NULL) { printk(KERN_ERR "pcnet32: No access methods\n"); return -ENODEV; } + lp->a = *a; /* detect special T1/E1 WAN card by checking for MAC address */ if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 && dev->dev_addr[2] == 0x75) diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index f59653eef..98b7db0f8 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -709,7 +709,7 @@ static struct file_operations ppp_device_fops = { #define PPP_MAJOR 108 -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; /* Called at boot time if ppp is compiled into the kernel, or at module load time (from init_module) if compiled as a module. */ diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index c71539c9a..05d0c06d1 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -5,7 +5,7 @@ * PPPoE --- PPP over Ethernet (RFC 2516) * * - * Version: 0.6.2 + * Version: 0.6.3 * * 030700 : Fixed connect logic to allow for disconnect. * 270700 : Fixed potential SMP problems; we must protect against @@ -18,6 +18,8 @@ * guards against sock_put not actually freeing the sk * in pppoe_release. * + * 051000 : Initialization cleanup + * * Author: Michal Ostrowski <mostrows@styx.uwaterloo.ca> * Contributors: * Arnaldo Carvalho de Melo <acme@conectiva.com.br> @@ -1025,7 +1027,7 @@ int __init pppoe_init(void) int err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto); if (err == 0) { - printk(KERN_INFO "Registered PPPoE v0.5\n"); + printk(KERN_INFO "Registered PPPoE v0.6.3\n"); dev_add_pack(&pppoes_ptype); register_netdevice_notifier(&pppoe_notifier); @@ -1034,15 +1036,7 @@ int __init pppoe_init(void) return err; } - -#ifdef MODULE -MODULE_PARM(debug, "i"); -int init_module(void) -{ - return pppoe_init(); -} - -void cleanup_module(void) +void __exit pppoe_exit(void) { unregister_pppox_proto(PX_PROTO_OE); dev_remove_pack(&pppoes_ptype); @@ -1050,11 +1044,5 @@ void cleanup_module(void) proc_net_remove("pppoe"); } -#else - -int pppoe_proto_init(struct net_proto *np) -{ - return pppoe_init(); -} - -#endif +module_init(pppoe_init); +module_exit(pppoe_exit); diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c index f460e16fd..50cdd2fee 100644 --- a/drivers/net/pppox.c +++ b/drivers/net/pppox.c @@ -5,10 +5,12 @@ * PPPoE --- PPP over Ethernet (RFC 2516) * * - * Version: 0.5.0 + * Version: 0.5.1 * * Author: Michal Ostrowski <mostrows@styx.uwaterloo.ca> * + * 051000 : Initialization cleanup + * * License: * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -140,13 +142,7 @@ struct net_proto_family pppox_proto_family = { pppox_create }; -extern int pppoe_init (void); - -#ifdef MODULE -int init_module(void) -#else -int __init pppox_proto_init(struct net_proto *pro) -#endif +int __init pppox_init(void) { int err = 0; @@ -154,19 +150,15 @@ int __init pppox_proto_init(struct net_proto *pro) if (err == 0) { printk(KERN_INFO "Registered PPPoX v0.5\n"); - pppoe_init(); } return err; } -#ifdef MODULE - -MODULE_PARM(debug, "i"); - -void cleanup_module(void) +void __exit pppox_exit(void) { sock_unregister(PF_PPPOX); } -#endif +module_init(pppox_init); +module_exit(pppox_exit); diff --git a/drivers/net/rclanmtl.c b/drivers/net/rclanmtl.c index c1c79247e..2721cb05e 100644 --- a/drivers/net/rclanmtl.c +++ b/drivers/net/rclanmtl.c @@ -311,14 +311,7 @@ PAB, *PPAB; ** Indexed by a zero based (0-31) interface number. */ #define MAX_ADAPTERS 32 -static PPAB PCIAdapterBlock[MAX_ADAPTERS] = -{ - 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 -}; - +static PPAB PCIAdapterBlock[MAX_ADAPTERS]; /* ** typedef NICSTAT diff --git a/drivers/net/rclanmtl.h b/drivers/net/rclanmtl.h index 2e594440c..3e7e1ecb4 100644 --- a/drivers/net/rclanmtl.h +++ b/drivers/net/rclanmtl.h @@ -38,6 +38,7 @@ #define RCLANMTL_H /* Linux specific includes */ +#include <asm/types.h> #define kprintf printk #ifdef RC_LINUX_MODULE /* linux modules need non-library version of string functions */ #include <linux/string.h> @@ -68,12 +69,12 @@ #define WARM_REBOOT_CAPABLE 0x01 /* scalar data types */ -typedef unsigned char U8; -typedef unsigned char* PU8; -typedef unsigned short U16; -typedef unsigned short* PU16; -typedef unsigned long U32; -typedef unsigned long* PU32; +typedef __u8 U8; +typedef __u16 U16; +typedef __u32 U32; +typedef __u8* PU8; +typedef __u16* PU16; +typedef __u32* PU32; typedef unsigned long BF; typedef int RC_RETURN; diff --git a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c index e4e2d1160..666078eec 100644 --- a/drivers/net/rcpci45.c +++ b/drivers/net/rcpci45.c @@ -135,14 +135,7 @@ DPA, *PDPA; #define MAX_ADAPTERS 32 -static PDPA PCIAdapters[MAX_ADAPTERS] = -{ - 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 -}; - +static PDPA PCIAdapters[MAX_ADAPTERS]; static int RCinit(struct net_device *dev); static int RCscan(void); @@ -163,7 +156,7 @@ static int RC_allocate_and_post_buffers(struct net_device *, int); /* A list of all installed RC devices, for removing the driver module. */ -static struct net_device *root_RCdev = NULL; +static struct net_device *root_RCdev; static int __init rcpci_init_module (void) { @@ -178,7 +171,7 @@ static int __init rcpci_init_module (void) static int RCscan(void) { int cards_found = 0; - static int pci_index = 0; + static int pci_index; if (!pcibios_present()) return cards_found; @@ -816,7 +809,7 @@ static void rc_timer(unsigned long data) struct net_device *dev = (struct net_device *)data; PDPA pDpa = (PDPA) (dev->priv); int init_status; - static int retry = 0; + static int retry; int post_buffers = MAX_NMBR_RCV_BUFFERS; int count = 0; int requested = 0; @@ -1111,7 +1104,7 @@ static int RCioctl(struct net_device *dev, struct ifreq *rq, int cmd) } RCUD_GETSPEED = &RCuser.RCUS_GETSPEED; RCGetLinkSpeed(pDpa->id, (PU32) &RCUD_GETSPEED->LinkSpeedCode, NULL); - printk("RC speed = 0x%ld\n", RCUD_GETSPEED->LinkSpeedCode); + printk("RC speed = 0x%u\n", RCUD_GETSPEED->LinkSpeedCode); break; case RCUC_SETIPANDMASK: printk("RC SETIPANDMASK\n"); diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index 13e66f96e..532a0f9e7 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -104,12 +104,7 @@ static inline void wait_for_buffer(struct net_device *dev); If dev->base_addr == 2, allocate space for the device and return success (detachable devices only). */ -#ifdef HAVE_DEVLIST -/* Support for an alternate probe manager, which will eliminate the - boilerplate below. */ -struct netdev_entry seeq8005_drv = -{"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist}; -#else + int __init seeq8005_probe(struct net_device *dev) { @@ -131,7 +126,6 @@ seeq8005_probe(struct net_device *dev) return -ENODEV; } -#endif /* This is the real probe routine. Linux has a history of friendly device probes on the ISA bus. A good device probes avoids doing writes, and @@ -270,10 +264,6 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) } #endif - /* Allocate a new 'dev' if needed. */ - if (dev == NULL) - dev = init_etherdev(0, sizeof(struct net_local)); - if (net_debug && version_printed++ == 0) printk(version); @@ -712,18 +702,9 @@ inline void wait_for_buffer(struct net_device * dev) #ifdef MODULE -static char devicename[9] = { 0, }; - -static struct net_device dev_seeq = -{ - devicename, /* device name is inserted by linux/drivers/net/net_init.c */ - 0, 0, 0, 0, - 0x300, 5, - 0, 0, 0, NULL, seeq8005_probe -}; - -static int io=0x320; -static int irq=10; +static struct net_device dev_seeq = { init: seeq8005_probe }; +static int io = 0x320; +static int irq = 10; MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 53a223151..2992457ae 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -599,13 +599,9 @@ int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, int i; struct sgiseeq_private *sp; - if (dev == NULL) { - dev = init_etherdev(0, sizeof(struct sgiseeq_private)); - } else { - dev->priv = (struct sgiseeq_private *) get_free_page(GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - } + dev->priv = (struct sgiseeq_private *) get_free_page(GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; if (!version_printed++) printk(version); diff --git a/drivers/net/sis900.h b/drivers/net/sis900.h index 136a51ed8..e905f09a6 100644 --- a/drivers/net/sis900.h +++ b/drivers/net/sis900.h @@ -10,7 +10,7 @@ * http://www.sis.com.tw/support/databook.htm */ -/* MAC operationl registers of SiS 7016 and SiS 900 ehternet controller */ +/* MAC operation registers of SiS 7016 and SiS 900 ethernet controller */ /* The I/O extent, SiS 900 needs 256 bytes of io address */ #define SIS900_TOTAL_SIZE 0x100 diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 0b945d36f..5ef2a4a1e 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -1110,7 +1110,7 @@ struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev) * dev - pointer to device information * * Functional Description: - * This function aquires the driver lock and only calls + * This function acquires the driver lock and only calls * skfp_ctl_set_multicast_list_wo_lock then. * This routine follows a fairly simple algorithm for setting the * adapter filters and CAM: diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index f884458f5..f106732a7 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -67,7 +67,7 @@ static unsigned int ultra_portlist[] __initdata = {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; int ultra_probe(struct net_device *dev); -int ultra_probe1(struct net_device *dev, int ioaddr); +static int ultra_probe1(struct net_device *dev, int ioaddr); static int ultra_open(struct net_device *dev); static void ultra_reset_8390(struct net_device *dev); @@ -101,10 +101,6 @@ static int ultra_close_card(struct net_device *dev); address PROM at I/O ports <base>+8 to <base>+13, with a checksum following. */ -#ifdef HAVE_DEVLIST -struct netdev_entry ultra_drv = -{"ultra", ultra_probe1, NETCARD_IO_EXTENT, netcard_portlist}; -#else int __init ultra_probe(struct net_device *dev) { @@ -126,9 +122,8 @@ int __init ultra_probe(struct net_device *dev) return -ENODEV; } -#endif -int __init ultra_probe1(struct net_device *dev, int ioaddr) +static int __init ultra_probe1(struct net_device *dev, int ioaddr) { int i; int checksum = 0; @@ -153,9 +148,6 @@ int __init ultra_probe1(struct net_device *dev, int ioaddr) if ((checksum & 0xff) != 0xFF) return -ENODEV; - if (dev == NULL) - dev = init_etherdev(0, 0); - if (ei_debug && version_printed++ == 0) printk(version); @@ -421,17 +413,9 @@ ultra_close_card(struct net_device *dev) #ifdef MODULE #define MAX_ULTRA_CARDS 4 /* Max number of Ultra cards per module */ -static struct net_device dev_ultra[MAX_ULTRA_CARDS] = { - { - "", /* assign a chunk of namelist[] below */ - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; - -static int io[MAX_ULTRA_CARDS] = { 0, }; -static int irq[MAX_ULTRA_CARDS] = { 0, }; +static struct net_device dev_ultra[MAX_ULTRA_CARDS]; +static int io[MAX_ULTRA_CARDS]; +static int irq[MAX_ULTRA_CARDS]; MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i"); diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c index c371aebab..9d54e2d05 100644 --- a/drivers/net/smc-ultra32.c +++ b/drivers/net/smc-ultra32.c @@ -148,12 +148,6 @@ int __init ultra32_probe1(struct net_device *dev, int ioaddr) if ((checksum & 0xff) != 0xff) return -ENODEV; - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("smc-ultra32.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - if (ei_debug && version_printed++ == 0) printk(version); @@ -365,14 +359,7 @@ static void ultra32_block_output(struct net_device *dev, #ifdef MODULE #define MAX_ULTRA32_CARDS 4 /* Max number of Ultra cards per module */ -static struct net_device dev_ultra[MAX_ULTRA32_CARDS] = { - { - "", - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; +static struct net_device dev_ultra[MAX_ULTRA32_CARDS]; int init_module(void) { diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index b89c4ec2e..3036684f9 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1,4 +1,4 @@ -/* $Id: sunbmac.c,v 1.20 2000/07/11 22:35:22 davem Exp $ +/* $Id: sunbmac.c,v 1.21 2000/10/22 16:08:38 davem Exp $ * sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -63,9 +63,7 @@ static char *version = #define DIRQ(x) #endif -#ifdef MODULE static struct bigmac *root_bigmac_dev = NULL; -#endif #define DEFAULT_JAMSIZE 4 /* Toe jam */ @@ -1197,11 +1195,12 @@ static int __init bigmac_ether_init(struct net_device *dev, struct sbus_dev *qec dev->dma = 0; ether_setup(dev); -#ifdef MODULE - /* Put us into the list of instances attached for later module unloading. */ + /* Put us into the list of instances attached for later driver + * exit. + */ bp->next_module = root_bigmac_dev; root_bigmac_dev = bp; -#endif + return 0; fail_and_cleanup: @@ -1257,9 +1256,7 @@ static int __init bigmac_probe(void) static int called = 0; int cards = 0, v; -#ifdef MODULE root_bigmac_dev = NULL; -#endif if (called) return -ENODEV; @@ -1284,8 +1281,6 @@ static int __init bigmac_probe(void) static void __exit bigmac_cleanup(void) { -#ifdef MODULE - /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_bigmac_dev) { struct bigmac *bp = root_bigmac_dev; struct bigmac *bp_nxt = root_bigmac_dev->next_module; @@ -1303,7 +1298,6 @@ static void __exit bigmac_cleanup(void) kfree(bp->dev); root_bigmac_dev = bp_nxt; } -#endif /* MODULE */ } module_init(bigmac_probe); diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 44a759c9f..2f0f46d95 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1,4 +1,4 @@ -/* $Id: sunhme.c,v 1.97 2000/09/05 23:12:36 davem Exp $ +/* $Id: sunhme.c,v 1.98 2000/10/22 16:08:38 davem Exp $ * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, * auto carrier detecting ethernet driver. Also known as the * "Happy Meal Ethernet" found on SunSwift SBUS cards. @@ -55,9 +55,7 @@ static char *version = #include "sunhme.h" -#ifdef MODULE static struct happy_meal *root_happy_dev = NULL; -#endif static struct quattro *qfe_sbus_list = NULL; #ifdef CONFIG_PCI @@ -2669,14 +2667,14 @@ static int __init happy_meal_sbus_init(struct net_device *dev, happy_meal_set_initial_advertisement(hp); ether_setup(dev); -#ifdef MODULE + /* We are home free at this point, link us in to the happy - * module device list. + * device list. */ dev->ifindex = dev_new_index(); hp->next_module = root_happy_dev; root_happy_dev = hp; -#endif + return 0; } #endif @@ -2843,14 +2841,13 @@ static int __init happy_meal_pci_init(struct net_device *dev, struct pci_dev *pd ether_setup(dev); -#ifdef MODULE /* We are home free at this point, link us in to the happy - * module device list. + * device list. */ dev->ifindex = dev_new_index(); hp->next_module = root_happy_dev; root_happy_dev = hp; -#endif + return 0; } #endif @@ -2909,9 +2906,7 @@ static int __init happy_meal_probe(void) static int called = 0; int cards; -#ifdef MODULE root_happy_dev = NULL; -#endif if (called) return -ENODEV; @@ -2934,8 +2929,6 @@ static int __init happy_meal_probe(void) static void __exit happy_meal_cleanup_module(void) { -#ifdef MODULE - /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_happy_dev) { struct happy_meal *hp = root_happy_dev; struct happy_meal *next = root_happy_dev->next_module; @@ -2965,7 +2958,6 @@ static void __exit happy_meal_cleanup_module(void) kfree(hp->dev); root_happy_dev = next; } -#endif /* MODULE */ } module_init(happy_meal_probe); diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 34c0ae78a..2ce4b7509 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1,4 +1,4 @@ -/* $Id: sunlance.c,v 1.103 2000/08/12 19:23:38 anton Exp $ +/* $Id: sunlance.c,v 1.105 2000/10/22 16:08:38 davem Exp $ * lance.c: Linux/Sparc/Lance driver * * Written 1995, 1996 by Miguel de Icaza @@ -291,9 +291,7 @@ int sparc_lance_debug = 2; #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) -#ifdef MODULE static struct lance_private *root_lance_dev = NULL; -#endif /* Load the CSR registers */ static void load_csrs(struct lance_private *lp) @@ -1489,11 +1487,10 @@ no_link_test: lp->multicast_timer.data = (unsigned long) dev; lp->multicast_timer.function = &lance_set_multicast_retry; -#ifdef MODULE dev->ifindex = dev_new_index(); lp->next_module = root_lance_dev; root_lance_dev = lp; -#endif + return 0; fail: @@ -1524,9 +1521,7 @@ static int __init sparc_lance_probe(void) static struct sbus_dev sdev; static int called = 0; -#ifdef MODULE root_lance_dev = NULL; -#endif if (called) return -ENODEV; @@ -1554,9 +1549,7 @@ static int __init sparc_lance_probe(void) static int called = 0; int cards = 0, v; -#ifdef MODULE root_lance_dev = NULL; -#endif if (called) return -ENODEV; @@ -1597,7 +1590,6 @@ static int __init sparc_lance_probe(void) static void __exit sparc_lance_cleanup(void) { -#ifdef MODULE struct lance_private *lp; while (root_lance_dev) { @@ -1608,7 +1600,6 @@ static void __exit sparc_lance_cleanup(void) kfree(root_lance_dev->dev); root_lance_dev = lp; } -#endif /* MODULE */ } module_init(sparc_lance_probe); diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index f4ea45189..7eb295cd6 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -1,4 +1,4 @@ -/* $Id: sunqe.c,v 1.46 2000/06/19 06:24:46 davem Exp $ +/* $Id: sunqe.c,v 1.47 2000/10/22 16:08:38 davem Exp $ * sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver. * Once again I am out to prove that every ethernet * controller out there can be most efficiently programmed @@ -46,9 +46,7 @@ static char *version = #include "sunqe.h" -#ifdef MODULE static struct sunqec *root_qec_dev = NULL; -#endif static void qe_set_multicast(struct net_device *dev); @@ -917,15 +915,13 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) printk("\n"); } -#ifdef MODULE /* We are home free at this point, link the qe's into - * the master list for later module unloading. + * the master list for later driver exit. */ for (i = 0; i < 4; i++) qe_devs[i]->ifindex = dev_new_index(); qecp->next_module = root_qec_dev; root_qec_dev = qecp; -#endif return 0; @@ -994,9 +990,7 @@ static int __init qec_probe(void) static int called = 0; int cards = 0, v; -#ifdef MODULE root_qec_dev = NULL; -#endif if (called) return -ENODEV; @@ -1021,11 +1015,9 @@ static int __init qec_probe(void) static void __exit qec_cleanup(void) { -#ifdef MODULE struct sunqec *next_qec; int i; - /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_qec_dev) { next_qec = root_qec_dev->next_module; @@ -1049,7 +1041,6 @@ static void __exit qec_cleanup(void) kfree(root_qec_dev); root_qec_dev = next_qec; } -#endif /* MODULE */ } module_init(qec_probe); diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 63dce60eb..33e98c23e 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -98,14 +98,47 @@ * v1.8a May 28, 2000 - Minor updates. * * v1.9 July 25, 2000 - Fixed a few remaining Full-Duplex issues. - * - Updated with timer fixes from Andrew Morton. - * - Fixed module race in TLan_Open. - * - Added routine to monitor PHY status. - * - Added activity led support for Proliant devices. + * - Updated with timer fixes from Andrew Morton. + * - Fixed module race in TLan_Open. + * - Added routine to monitor PHY status. + * - Added activity led support for Proliant devices. + * + * v1.10 Aug 30, 2000 - Added support for EISA based tlan controllers + * like the Compaq NetFlex3/E. + * - Rewrote tlan_probe to better handle multiple + * bus probes. Probing and device setup is now + * done through TLan_Probe and TLan_init_one. Actual + * hardware probe is done with kernel API and + * TLan_EisaProbe. + * - Adjusted debug information for probing. + * - Fixed bug that would cause general debug information + * to be printed after driver removal. + * - Added transmit timeout handling. + * - Fixed OOM return values in tlan_probe. + * - Fixed possible mem leak in tlan_exit + * (now tlan_remove_one). + * - Fixed timer bug in TLan_phyMonitor. + * - This driver version is alpha quality, please + * send me any bug issues you may encounter. + * + * v1.11 Aug 31, 2000 - Do not try to register irq 0 if no irq line was + * set for EISA cards. + * - Added support for NetFlex3/E with nibble-rate + * 10Base-T PHY. This is untestet as I haven't got + * one of these cards. + * - Fixed timer being added twice. + * - Disabled PhyMonitoring by default as this is + * work in progress. Define MONITOR to enable it. + * - Now we don't display link info with PHYs that + * doesn't support it (level1). + * - Incresed tx_timeout beacuse of auto-neg. + * - Adjusted timers for forced speeds. + * + * v1.12 Oct 12, 2000 - Minor fixes (memleak, init, etc.) * *******************************************************************************/ - + #include <linux/module.h> #include "tlan.h" @@ -121,14 +154,15 @@ typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 ); +/* For removing EISA devices */ +static struct net_device *TLan_Eisa_Devices; -static struct net_device *TLanDevices = NULL; -static int TLanDevicesInstalled = 0; +static int TLanDevicesInstalled; /* Force speed, duplex and aui settings */ -static int aui = 0; -static int duplex = 0; -static int speed = 0; +static int aui; +static int duplex; +static int speed; MODULE_AUTHOR("Maintainer: Torben Mathiasen <torben.mathiasen@compaq.com>"); MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); @@ -138,13 +172,18 @@ MODULE_PARM(speed, "i"); MODULE_PARM(debug, "i"); EXPORT_NO_SYMBOLS; +/* Define this to enable Link beat monitoring */ +#undef MONITOR + /* Turn on debugging. See linux/Documentation/networking/tlan.txt for details */ -static int debug = 0; +static int debug; -static int bbuf = 0; +static int bbuf; static u8 *TLanPadBuffer; static char TLanSignature[] = "TLAN"; -static const char *tlan_banner = "ThunderLAN driver v1.9\n"; +static const char *tlan_banner = "ThunderLAN driver v1.12\n"; +static int tlan_have_pci; +static int tlan_have_eisa; const char *media[] = { "10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ", @@ -153,103 +192,73 @@ const char *media[] = { int media_map[] = { 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,}; -static TLanAdapterEntry TLanAdapterList[] __initdata = { - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETELLIGENT_10, - "Compaq Netelligent 10 T PCI UTP", - TLAN_ADAPTER_ACTIVITY_LED, - 0x83 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETELLIGENT_10_100, - "Compaq Netelligent 10/100 TX PCI UTP", - TLAN_ADAPTER_ACTIVITY_LED, - 0x83 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETFLEX_3P_INTEGRATED, - "Compaq Integrated NetFlex-3/P", - TLAN_ADAPTER_NONE, - 0x83 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETFLEX_3P, - "Compaq NetFlex-3/P", - TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, - 0x83 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETFLEX_3P_BNC, - "Compaq NetFlex-3/P", - TLAN_ADAPTER_NONE, - 0x83 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETELLIGENT_10_100_PROLIANT, - "Compaq Netelligent Integrated 10/100 TX UTP", - TLAN_ADAPTER_ACTIVITY_LED, - 0x83 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETELLIGENT_10_100_DUAL, - "Compaq Netelligent Dual 10/100 TX PCI UTP", - TLAN_ADAPTER_NONE, - 0x83 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_DESKPRO_4000_5233MMX, - "Compaq Netelligent 10/100 TX Embedded UTP", - TLAN_ADAPTER_NONE, - 0x83 - }, - { PCI_VENDOR_ID_OLICOM, - PCI_DEVICE_ID_OLICOM_OC2183, - "Olicom OC-2183/2185", - TLAN_ADAPTER_USE_INTERN_10, - 0xF8 - }, - { PCI_VENDOR_ID_OLICOM, - PCI_DEVICE_ID_OLICOM_OC2325, - "Olicom OC-2325", - TLAN_ADAPTER_UNMANAGED_PHY, - 0xF8 - }, - { PCI_VENDOR_ID_OLICOM, - PCI_DEVICE_ID_OLICOM_OC2326, - "Olicom OC-2326", - TLAN_ADAPTER_USE_INTERN_10, - 0xF8 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100, - "Compaq Netelligent 10/100 TX UTP", - TLAN_ADAPTER_ACTIVITY_LED, - 0x83 - }, - { PCI_VENDOR_ID_COMPAQ, - PCI_DEVICE_ID_NETELLIGENT_10_T2, - "Compaq Netelligent 10 T/2 PCI UTP/Coax", - TLAN_ADAPTER_NONE, - 0x83 - }, - { 0, - 0, - NULL, - 0, - 0 - } /* End of List */ +static struct board { + const char *deviceLabel; + u32 flags; + u16 addrOfs; +} board_info[] __devinitdata = { + { "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, + { "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, + { "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 }, + { "Compaq NetFlex-3/P", TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 }, + { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 }, + { "Compaq Netelligent Integrated 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, + { "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 }, + { "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 }, + { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 }, + { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xF8 }, + { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 }, + { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, + { "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 }, + { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */ + TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 }, + { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */ }; +static struct pci_device_id tlan_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETFLEX_3P_INTEGRATED, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETFLEX_3P, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETFLEX_3P_BNC, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_PROLIANT, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_DUAL, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_DESKPRO_4000_5233MMX, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, + { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, + { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, + { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, + { 0,} +}; +MODULE_DEVICE_TABLE(pci, tlan_pci_tbl); -static int TLan_PciProbe( u8 *, u8 *, u8 *, u32 *, u32 * ); +static void TLan_EisaProbe( void ); +static void TLan_Eisa_Cleanup( void ); static int TLan_Init( struct net_device * ); -static int TLan_Open(struct net_device *dev); -static int TLan_StartTx(struct sk_buff *, struct net_device *); -static void TLan_HandleInterrupt(int, void *, struct pt_regs *); -static int TLan_Close(struct net_device *); -static struct net_device_stats *TLan_GetStats( struct net_device * ); -static void TLan_SetMulticastList( struct net_device * ); -static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int TLan_Open( struct net_device *dev ); +static int TLan_StartTx( struct sk_buff *, struct net_device *); +static void TLan_HandleInterrupt( int, void *, struct pt_regs *); +static int TLan_Close( struct net_device *); +static struct net_device_stats *TLan_GetStats( struct net_device *); +static void TLan_SetMulticastList( struct net_device *); +static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd); +static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent); +static void TLan_tx_timeout( struct net_device *dev); +static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent); static u32 TLan_HandleInvalid( struct net_device *, u16 ); static u32 TLan_HandleTxEOF( struct net_device *, u16 ); @@ -278,7 +287,10 @@ static void TLan_PhyPowerUp( struct net_device * ); static void TLan_PhyReset( struct net_device * ); static void TLan_PhyStartLink( struct net_device * ); static void TLan_PhyFinishAutoNeg( struct net_device * ); -static void TLan_PhyMonitor( struct net_device * ); +#ifdef MONITOR +static void TLan_PhyMonitor( struct net_device * ); +#endif + /* static int TLan_PhyNop( struct net_device * ); static int TLan_PhyInternalCheck( struct net_device * ); @@ -316,7 +328,7 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) spin_lock_irqsave(&priv->lock, flags); if ( priv->timer.function != NULL && - priv->timerType != TLAN_TIMER_ACTIVITY) { + priv->timerType != TLAN_TIMER_ACTIVITY ) { spin_unlock_irqrestore(&priv->lock, flags); return; } @@ -324,11 +336,10 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) spin_unlock_irqrestore(&priv->lock, flags); priv->timer.data = (unsigned long) dev; - priv->timer.expires = jiffies + ticks; priv->timerSetAt = jiffies; priv->timerType = type; - add_timer( &priv->timer ); - + mod_timer(&priv->timer, jiffies + ticks); + } /* TLan_SetTimer */ @@ -344,8 +355,10 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) + + /*************************************************************** - * tlan_exit + * tlan_remove_one * * Returns: * Nothing @@ -360,31 +373,77 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) **************************************************************/ -static void __exit tlan_exit(void) +static void __devexit tlan_remove_one( struct pci_dev *pdev) { - struct net_device *dev; - TLanPrivateInfo *priv; + struct net_device *dev = pdev->driver_data; + TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; + + unregister_netdev( dev ); - while ( TLanDevicesInstalled ) { - dev = TLanDevices; - priv = (TLanPrivateInfo *) dev->priv; - if ( priv->dmaStorage ) { - kfree( priv->dmaStorage ); - } - release_region( dev->base_addr, 0x10 ); - unregister_netdev( dev ); - TLanDevices = priv->nextDevice; - kfree( dev ); - TLanDevicesInstalled--; + if ( priv->dmaStorage ) { + kfree( priv->dmaStorage ); } - kfree( TLanPadBuffer ); + release_region( dev->base_addr, 0x10 ); + + kfree( dev ); + } +static struct pci_driver tlan_driver = { + name: "tlan", + id_table: tlan_pci_tbl, + probe: tlan_init_one, + remove: tlan_remove_one, +}; + +static int __init tlan_probe(void) +{ + static int pad_allocated = 0; + + printk(KERN_INFO "%s", tlan_banner); + + TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE, + (GFP_KERNEL | GFP_DMA)); + + if (TLanPadBuffer == NULL) { + printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n"); + return -ENOMEM; + } + + memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE); + pad_allocated = 1; + + TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n"); + + /* Use new style PCI probing. Now the kernel will + do most of this for us */ + pci_module_init(&tlan_driver); + + TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n"); + TLan_EisaProbe(); + + printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n", + TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s", + tlan_have_pci, tlan_have_eisa); + + return ((TLanDevicesInstalled > 0) ? 0 : -ENODEV); + +} + + +static int __devinit tlan_init_one( struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + return TLan_probe1( pdev, pci_resource_start(pdev, 0), pdev->irq, + 0, ent); + +} + /* *************************************************************** - * tlan_probe + * tlan_probe1 * * Returns: * 0 on success, error code on error @@ -401,197 +460,249 @@ static void __exit tlan_exit(void) * **************************************************************/ -static int __init tlan_probe(void) +static int __devinit TLan_probe1(struct pci_dev *pdev, + long ioaddr, int irq, int rev, const struct pci_device_id *ent ) { struct net_device *dev; TLanPrivateInfo *priv; - static int pad_allocated = 0; - u8 dfn, irq, rev; - u32 io_base, index; - int found; - - printk(KERN_INFO "%s", tlan_banner); + u8 pci_rev; + u16 device_id; - TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE, - (GFP_KERNEL | GFP_DMA)); - - if (TLanPadBuffer == NULL) { - printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n"); + dev = init_etherdev(NULL, sizeof(TLanPrivateInfo)); + if (dev == NULL) { + printk(KERN_ERR "TLAN: Could not allocate memory for device.\n"); return -ENOMEM; } - - memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE); - - while((found = TLan_PciProbe( &dfn, &irq, &rev, &io_base, &index))) { - dev = init_etherdev(NULL, sizeof(TLanPrivateInfo)); - if (dev == NULL) { - printk(KERN_ERR "TLAN: Could not allocate memory for device.\n"); - return -ENOMEM; + + priv = dev->priv; + + dev->base_addr = ioaddr; + dev->irq = irq; + + + /* Is this a PCI device? */ + if (pdev) { + priv->adapter = &board_info[ent->driver_data]; + if (pci_enable_device(pdev)) { + unregister_netdev(dev); + kfree(dev); + return -1; } - priv = dev->priv; - if (dev->priv == NULL) { - dev->priv = kmalloc(sizeof(TLanPrivateInfo), GFP_KERNEL); - priv = dev->priv; + pci_read_config_byte ( pdev, PCI_REVISION_ID, &pci_rev); + priv->adapterRev = pci_rev; + pci_set_master(pdev); + pdev->driver_data = dev; + + } else { /* EISA card */ + /* This is a hack. We need to know which board structure + * is suited for this adapter */ + device_id = inw(ioaddr + EISA_ID2); + priv->is_eisa = 1; + if (device_id == 0x20F1) { + priv->adapter = &board_info[13]; /* NetFlex-3/E */ + priv->adapterRev = 23; /* TLAN 2.3 */ + } else { + priv->adapter = &board_info[14]; + priv->adapterRev = 10; /* TLAN 1.0 */ } - memset(priv, 0, sizeof(TLanPrivateInfo)); - - pad_allocated = 1; - - dev->base_addr = io_base; - dev->irq = irq; - priv->adapter = &TLanAdapterList[index]; - priv->adapterRev = rev; + } + + /* Kernel parameters */ + if (dev->mem_start) { + priv->aui = dev->mem_start & 0x01; + priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1; + priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3; + + if (priv->speed == 0x1) { + priv->speed = TLAN_SPEED_10; + } else if (priv->speed == 0x2) { + priv->speed = TLAN_SPEED_100; + } + debug = priv->debug = dev->mem_end; + } else { + + if ( ( duplex != 1 ) && ( duplex != 2 ) ) + duplex = 0; + priv->duplex = duplex; + + if ( ( speed != 10 ) && ( speed != 100 ) ) + speed = 0; - /* Kernel parameters */ - if (dev->mem_start) { - priv->aui = dev->mem_start & 0x01; - priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1; - priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3; + priv->aui = aui; + priv->speed = speed; + priv->debug = debug; - if (priv->speed == 0x1) { - priv->speed = TLAN_SPEED_10; - } else if (priv->speed == 0x2) { - priv->speed = TLAN_SPEED_100; - } - debug = priv->debug = dev->mem_end; - } else { + } + + spin_lock_init(&priv->lock); + + if (TLan_Init(dev)) { + printk(KERN_ERR "TLAN: Could not register device.\n"); + unregister_netdev(dev); + kfree(dev); + return -EAGAIN; + } else { + + TLanDevicesInstalled++; + + /* pdev is NULL if this is an EISA device */ + if (pdev) + tlan_have_pci++; + else { + priv->nextDevice = TLan_Eisa_Devices; + TLan_Eisa_Devices = dev; + tlan_have_eisa++; + } + + printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n", + dev->name, + (int) dev->irq, + (int) dev->base_addr, + priv->adapter->deviceLabel, + priv->adapterRev); + return 0; + } - if ( ( duplex != 1 ) && ( duplex != 2 ) ) - duplex = 0; - - priv->duplex = duplex; +} - if ( ( speed != 10 ) && ( speed != 100 ) ) - speed = 0; - - priv->aui = aui; - priv->speed = speed; - priv->debug = debug; - - } - - spin_lock_init(&priv->lock); - - if (TLan_Init(dev)) { - printk(KERN_ERR "TLAN: Could not register device.\n"); - unregister_netdev(dev); - kfree(dev); - } else { - - TLanDevicesInstalled++; - priv->nextDevice = TLanDevices; - TLanDevices = dev; - printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n", - dev->name, - (int) dev->irq, - (int) dev->base_addr, - priv->adapter->deviceLabel, - priv->adapterRev); - } - } +static void TLan_Eisa_Cleanup(void) +{ + struct net_device *dev; + TLanPrivateInfo *priv; - printk(KERN_INFO "TLAN: %d device%s installed\n", - TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s"); + while( tlan_have_eisa ) { + dev = TLan_Eisa_Devices; + priv = (TLanPrivateInfo *) dev->priv; + if (priv->dmaStorage) { + kfree(priv->dmaStorage); + } + release_region( dev->base_addr, 0x10); + unregister_netdev( dev ); + TLan_Eisa_Devices = priv->nextDevice; + kfree( dev ); + tlan_have_eisa--; + } +} - return ((TLanDevicesInstalled > 0) ? 0 : -ENODEV); + +static void __exit tlan_exit(void) +{ + if (tlan_have_pci) + pci_unregister_driver(&tlan_driver); + + if (tlan_have_eisa) + TLan_Eisa_Cleanup(); + + kfree( TLanPadBuffer ); + } + /* Module loading/unloading */ module_init(tlan_probe); module_exit(tlan_exit); - /*************************************************************** - * TLan_PciProbe + /************************************************************** + * TLan_EisaProbe * - * Returns: - * 1 if another TLAN card was found, 0 if not. - * Parms: - * pci_dfn The PCI whatever the card was - * found at. - * pci_irq The IRQ of the found adapter. - * pci_rev The revision of the adapter. - * pci_io_base The first IO port used by the - * adapter. - * dl_ix The index in the device list - * of the adapter. - * - * This function searches for an adapter with PCI vendor - * and device IDs matching those in the TLanAdapterList. - * The function 'remembers' the last device it found, - * and so finds a new device (if anymore are to be found) - * each time the function is called. It then looks up - * pertinent PCI info and returns it to the caller. + * Returns: 0 on success, 1 otherwise * - **************************************************************/ + * Parms: None + * + * + * This functions probes for EISA devices and calls + * TLan_probe1 when one is found. + * + *************************************************************/ -static int __init TLan_PciProbe(u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_io_base, u32 *dl_ix ) +static void __init TLan_EisaProbe (void) { - static int dl_index = 0; - static struct pci_dev * pdev = NULL; - u16 pci_command; - int reg; - - - for (; TLanAdapterList[dl_index].vendorId != 0; dl_index++) { - - pdev = pci_find_device( - TLanAdapterList[dl_index].vendorId, - TLanAdapterList[dl_index].deviceId, pdev); - - if ( pdev ) { - - TLAN_DBG( - TLAN_DEBUG_GNRL, - "found: Vendor Id = 0x%hx, Device Id = 0x%hx\n", - TLanAdapterList[dl_index].vendorId, - TLanAdapterList[dl_index].deviceId - ); + long ioaddr; + int rc = -ENODEV; + int irq; + u16 device_id; - if (pci_enable_device(pdev)) - continue; - - *pci_irq = pdev->irq; - *pci_io_base = pci_resource_start (pdev, 0); - *pci_dfn = pdev->devfn; - pci_read_config_byte ( pdev, PCI_REVISION_ID, pci_rev); - pci_read_config_word ( pdev, PCI_COMMAND, &pci_command); - - for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg +=4 ) { - pci_read_config_dword( pdev, reg, pci_io_base); - if ((pci_command & PCI_COMMAND_IO) && (*pci_io_base & 0x3)) { - *pci_io_base &= PCI_BASE_ADDRESS_IO_MASK; - TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n", *pci_io_base); - break; - } else { - *pci_io_base = 0; - } - } - - if ( *pci_io_base == 0 ) - printk(KERN_INFO "TLAN: IO mapping not available, ignoring device.\n"); + if (!EISA_bus) { + TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n"); + return; + } + + /* Loop through all slots of the EISA bus */ + for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { + + TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID)); + TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2)); - pci_set_master(pdev); - if ( *pci_io_base ) { - *dl_ix = dl_index; - return 1; - } + TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ", + (int) ioaddr); + if (request_region(ioaddr, 0x10, TLanSignature) == NULL) + goto out; - } else { - pdev = NULL; + if (inw(ioaddr + EISA_ID) != 0x110E) { + release_region(ioaddr, 0x10); + goto out; + } + + device_id = inw(ioaddr + EISA_ID2); + if (device_id != 0x20F1 && device_id != 0x40F1) { + release_region (ioaddr, 0x10); + goto out; } + + if (inb(ioaddr + EISA_CR) != 0x1) { /* Check if adapter is enabled */ + release_region (ioaddr, 0x10); + goto out2; + } + + if (debug == 0x10) + printk("Found one\n"); + + + /* Get irq from board */ + switch (inb(ioaddr + 0xCC0)) { + case(0x10): + irq=5; + break; + case(0x20): + irq=9; + break; + case(0x40): + irq=10; + break; + case(0x80): + irq=11; + break; + default: + goto out; + } + + + /* Setup the newly found eisa adapter */ + rc = TLan_probe1( NULL, ioaddr, irq, + 12, NULL); + continue; + + out: + if (debug == 0x10) + printk("None found\n"); + continue; + + out2: if (debug == 0x10) + printk("Card found but it is not enabled, skipping\n"); + continue; + } - return 0; - -} /* TLan_PciProbe */ +} /* TLan_EisaProbe */ + /*************************************************************** @@ -620,14 +731,14 @@ static int TLan_Init( struct net_device *dev ) priv = (TLanPrivateInfo *) dev->priv; - 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 (!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 ) @@ -658,7 +769,7 @@ static int TLan_Init( struct net_device *dev ) (u8) priv->adapter->addrOfs + i, (u8 *) &dev->dev_addr[i] ); if ( err ) { - printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n", + printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n", dev->name, err ); } @@ -671,6 +782,8 @@ static int TLan_Init( struct net_device *dev ) dev->get_stats = &TLan_GetStats; dev->set_multicast_list = &TLan_SetMulticastList; dev->do_ioctl = &TLan_ioctl; + dev->tx_timeout = &TLan_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; return 0; @@ -712,6 +825,7 @@ static int TLan_Open( struct net_device *dev ) return err; } + init_timer(&priv->timer); netif_start_queue(dev); /* NOTE: It might not be necessary to read the stats before a @@ -772,6 +886,32 @@ static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } /* tlan_ioctl */ + /*************************************************************** + * TLan_tx_timeout + * + * Returns: nothing + * + * Params: + * dev structure of device which timed out + * during transmit. + * + **************************************************************/ + +static void TLan_tx_timeout(struct net_device *dev) +{ + + TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name); + + /* Ok so we timed out, lets see what we can do about it...*/ + TLan_ResetLists( dev ); + TLan_ReadAndClearStats( dev, TLAN_IGNORE ); + TLan_ResetAdapter( dev ); + dev->trans_start = jiffies; + netif_wake_queue( dev ); + +} + + /*************************************************************** * TLan_StartTx @@ -953,6 +1093,7 @@ static int TLan_Close(struct net_device *dev) del_timer_sync( &priv->timer ); priv->timer.function = NULL; } + free_irq( dev->irq, dev ); TLan_FreeLists( dev ); TLAN_DBG( TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name ); @@ -993,7 +1134,7 @@ static struct net_device_stats *TLan_GetStats( struct net_device *dev ) TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name, priv->txBusyCount ); if ( debug & TLAN_DEBUG_GNRL ) { TLan_PrintDio( dev->base_addr ); - TLan_PhyPrint( dev ); + TLan_PhyPrint( dev ); } if ( debug & TLAN_DEBUG_LIST ) { for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) @@ -1495,7 +1636,7 @@ u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) } if (debug) { - TLan_PhyPrint( dev ); + TLan_PhyPrint( dev ); } } } @@ -1598,9 +1739,11 @@ void TLan_Timer( unsigned long data ) priv->timer.function = NULL; switch ( priv->timerType ) { +#ifdef MONITOR case TLAN_TIMER_LINK_BEAT: TLan_PhyMonitor( dev ); break; +#endif case TLAN_TIMER_PHY_PDOWN: TLan_PhyPowerDown( dev ); break; @@ -2007,6 +2150,7 @@ TLan_FinishReset( struct net_device *dev ) u16 partner; u16 tlphy_ctl; u16 tlphy_par; + u16 tlphy_id1, tlphy_id2; int i; phy = priv->phy[priv->phyNum]; @@ -2022,7 +2166,9 @@ TLan_FinishReset( struct net_device *dev ) } TLan_DioWrite8( dev->base_addr, TLAN_NET_MASK, data ); TLan_DioWrite16( dev->base_addr, TLAN_MAX_RX, TLAN_MAX_FRAME_SIZE ); - + TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 ); + TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 ); + if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || ( priv->aui ) ) { status = MII_GS_LINK; printk( "TLAN: %s: Link forced.\n", dev->name ); @@ -2030,7 +2176,9 @@ TLan_FinishReset( struct net_device *dev ) TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); udelay( 1000 ); TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); - if ( status & MII_GS_LINK ) { + if ( (status & MII_GS_LINK) && /* We only support link info on Nat.Sem. PHY's */ + (tlphy_id1 == NAT_SEM_ID1) && + (tlphy_id2 == NAT_SEM_ID2) ) { TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner ); TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par ); @@ -2043,7 +2191,6 @@ TLan_FinishReset( struct net_device *dev ) printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n", tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0", tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half"); - printk("TLAN: Partner capability: "); for (i = 5; i <= 10; i++) if (partner & (1<<i)) @@ -2052,12 +2199,15 @@ TLan_FinishReset( struct net_device *dev ) } TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK ); - +#ifdef MONITOR /* We have link beat..for now anyway */ - priv->link = 1; - /*Enabling link beat monitoring */ + priv->link = 1; + /*Enabling link beat monitoring */ TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT ); - +#endif + } else if (status & MII_GS_LINK) { + printk( "TLAN: %s: Link active\n", dev->name ); + TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK ); } } @@ -2074,13 +2224,12 @@ TLan_FinishReset( struct net_device *dev ) TLan_SetMac( dev, 0, dev->dev_addr ); priv->phyOnline = 1; outb( ( TLAN_HC_INT_ON >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 ); - if ( debug >= 1 ) { + 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( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD ); - - } else { + } else { printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name ); TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET ); return; @@ -2217,7 +2366,7 @@ void TLan_PhyDetect( struct net_device *dev ) } TLan_MiiReadReg( dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi ); - + if ( hi != 0xFFFF ) { priv->phy[0] = TLAN_PHY_MAX_ADDR; } else { @@ -2289,7 +2438,7 @@ void TLan_PhyPowerUp( struct net_device *dev ) * tranceiver. The TLAN docs say both 50 ms and * 500 ms, so do the longer, just in case. */ - TLan_SetTimer( dev, (HZ/2), TLAN_TIMER_PHY_RESET ); + TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET ); } /* TLan_PhyPowerUp */ @@ -2338,24 +2487,24 @@ void TLan_PhyStartLink( struct net_device *dev ) TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name ); TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability ); + if ( ( status & MII_GS_AUTONEG ) && ( ! priv->aui ) ) { - ability = status >> 11; if ( priv->speed == TLAN_SPEED_10 && priv->duplex == TLAN_DUPLEX_HALF) { TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000); } else if ( priv->speed == TLAN_SPEED_10 && priv->duplex == TLAN_DUPLEX_FULL) { - priv->tlanFullDuplex = TRUE; - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100); + priv->tlanFullDuplex = TRUE; + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100); } else if ( priv->speed == TLAN_SPEED_100 && priv->duplex == TLAN_DUPLEX_HALF) { - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000); + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000); } else if ( priv->speed == TLAN_SPEED_100 && priv->duplex == TLAN_DUPLEX_FULL) { - priv->tlanFullDuplex = TRUE; - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100); + priv->tlanFullDuplex = TRUE; + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100); } else { /* Set Auto-Neg advertisement */ @@ -2370,7 +2519,7 @@ void TLan_PhyStartLink( struct net_device *dev ) * .5 sec should be plenty extra. */ printk( "TLAN: %s: Starting autonegotiation.\n", dev->name ); - TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_PHY_FINISH_AN ); + TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN ); return; } @@ -2404,7 +2553,7 @@ void TLan_PhyStartLink( struct net_device *dev ) /* Wait for 2 sec to give the tranceiver time * to establish link. */ - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_FINISH_RESET ); + TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET ); } /* TLan_PhyStartLink */ @@ -2424,6 +2573,9 @@ void TLan_PhyFinishAutoNeg( struct net_device *dev ) phy = priv->phy[priv->phyNum]; TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); + udelay( 1000 ); + TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); + if ( ! ( status & MII_GS_AUTOCMPLT ) ) { /* Wait for 8 sec to give the process * more time. Perhaps we should fail after a while. @@ -2438,9 +2590,9 @@ void TLan_PhyFinishAutoNeg( struct net_device *dev ) TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa ); mode = an_adv & an_lpa & 0x03E0; if ( mode & 0x0100 ) { - priv->tlanFullDuplex = TRUE; + priv->tlanFullDuplex = TRUE; } else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) { - priv->tlanFullDuplex = TRUE; + priv->tlanFullDuplex = TRUE; } if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) { @@ -2467,62 +2619,60 @@ void TLan_PhyFinishAutoNeg( struct net_device *dev ) } /* TLan_PhyFinishAutoNeg */ - - - - /********************************************************************* - * - * TLan_PhyMonitor - * - * Returns: - * None - * - * Params: - * dev The device structure of this device. - * - * - * This function monitors PHY condition by reading the status - * register via the MII bus. This can be used to give info - * about link changes (up/down), and possible switch to alternate - * media. - * - * ******************************************************************/ +#ifdef MONITOR + + /********************************************************************* + * + * TLan_phyMonitor + * + * Returns: + * None + * + * Params: + * dev The device structure of this device. + * + * + * This function monitors PHY condition by reading the status + * register via the MII bus. This can be used to give info + * about link changes (up/down), and possible switch to alternate + * media. + * + * ******************************************************************/ void TLan_PhyMonitor( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; - u16 phy; - u16 phy_status; + u16 phy; + u16 phy_status; phy = priv->phy[priv->phyNum]; - /* Get PHY status register */ - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status ); - - /* Check if link has been lost */ - if (!(phy_status & MII_GS_LINK)) { - if (priv->link) { - priv->link = 0; - printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name); - dev->flags &= ~IFF_RUNNING; - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); - return; + /* Get PHY status register */ + TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status ); + + /* Check if link has been lost */ + if (!(phy_status & MII_GS_LINK)) { + if (priv->link) { + priv->link = 0; + printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name); + dev->flags &= ~IFF_RUNNING; + TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); + return; } } - /* Link restablished? */ - if ((phy_status & MII_GS_LINK) && !priv->link) { - priv->link = 1; - printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name); - dev->flags |= IFF_RUNNING; - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); - } + /* Link restablished? */ + if ((phy_status & MII_GS_LINK) && !priv->link) { + priv->link = 1; + printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name); + dev->flags |= IFF_RUNNING; + } /* Setup a new monitor */ TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); +} -} - +#endif /* MONITOR */ /***************************************************************************** @@ -2996,4 +3146,3 @@ fail: - diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h index 1d032f4b0..deb96db01 100644 --- a/drivers/net/tlan.h +++ b/drivers/net/tlan.h @@ -50,7 +50,9 @@ #define TLAN_DEBUG_TX 0x0002 #define TLAN_DEBUG_RX 0x0004 #define TLAN_DEBUG_LIST 0x0008 +#define TLAN_DEBUG_PROBE 0x0010 +#define TX_TIMEOUT (10*HZ) /* We need time for auto-neg */ @@ -103,6 +105,24 @@ typedef struct tlan_adapter_entry { + /***************************************************************** + * EISA Definitions + * + ****************************************************************/ + +#define EISA_ID 0xc80 /* EISA ID Registers */ +#define EISA_ID0 0xc80 /* EISA ID Register 0 */ +#define EISA_ID1 0xc81 /* EISA ID Register 1 */ +#define EISA_ID2 0xc82 /* EISA ID Register 2 */ +#define EISA_ID3 0xc83 /* EISA ID Register 3 */ +#define EISA_CR 0xc84 /* EISA Control Register */ +#define EISA_REG0 0xc88 /* EISA Configuration Register 0 */ +#define EISA_REG1 0xc89 /* EISA Configuration Register 1 */ +#define EISA_REG2 0xc8a /* EISA Configuration Register 2 */ +#define EISA_REG3 0xc8f /* EISA Configuration Register 3 */ +#define EISA_APROM 0xc90 /* Ethernet Address PROM */ + + /***************************************************************** * Rx/Tx List Definitions @@ -156,7 +176,7 @@ typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE]; ****************************************************************/ typedef struct tlan_private_tag { - struct net_device *nextDevice; + struct net_device *nextDevice; void *dmaStorage; u8 *padBuffer; TLanList *rxList; @@ -175,7 +195,7 @@ typedef struct tlan_private_tag { u32 timerType; struct timer_list timer; struct net_device_stats stats; - TLanAdapterEntry *adapter; + struct board *adapter; u32 adapterRev; u32 aui; u32 debug; @@ -188,6 +208,7 @@ typedef struct tlan_private_tag { char devName[8]; spinlock_t lock; u8 link; + u8 is_eisa; } TLanPrivateInfo; @@ -382,9 +403,9 @@ typedef struct tlan_private_tag { #define MII_GIL_OUI 0xFC00 #define MII_GIL_MODEL 0x03F0 #define MII_GIL_REVISION 0x000F -#define MII_AN_ADV 0x0004 -#define MII_AN_LPA 0x0005 -#define MII_AN_EXP 0x0006 +#define MII_AN_ADV 0x04 +#define MII_AN_LPA 0x05 +#define MII_AN_EXP 0x06 /* ThunderLAN Specific MII/PHY Registers */ @@ -411,6 +432,12 @@ typedef struct tlan_private_tag { #define TLAN_PHY_DUPLEX_FULL 0x0080 #define TLAN_PHY_AN_EN_STAT 0x0400 +/* National Sem. & Level1 PHY id's */ +#define NAT_SEM_ID1 0x2000 +#define NAT_SEM_ID2 0x5C01 +#define LEVEL1_ID1 0x7810 +#define LEVEL1_ID2 0x0000 + #define CIRC_INC( a, b ) if ( ++a >= b ) a = 0 /* Routines to access internal registers. */ diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index fb6d438d0..9a0315f0c 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -1861,8 +1861,8 @@ int ibmtr_change_mtu(struct net_device *dev, int mtu) { /* 3COM 3C619C supports 8 interrupts, 32 I/O ports */ static struct net_device* dev_ibmtr[IBMTR_MAX_ADAPTERS]; static int io[IBMTR_MAX_ADAPTERS] = {0xa20,0xa24}; -static int irq[IBMTR_MAX_ADAPTERS] = {0,0}; -static int mem[IBMTR_MAX_ADAPTERS] = {0,0}; +static int irq[IBMTR_MAX_ADAPTERS]; +static int mem[IBMTR_MAX_ADAPTERS]; MODULE_PARM(io, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i"); diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 83024732a..32a596d2a 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -5801,9 +5801,9 @@ static int smctr_wait_while_cbusy(struct net_device *dev) #ifdef MODULE static struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS]; -static int io[SMCTR_MAX_ADAPTERS] = { 0, 0 }; -static int irq[SMCTR_MAX_ADAPTERS] = { 0, 0 }; -static int mem[SMCTR_MAX_ADAPTERS] = { 0, 0 }; +static int io[SMCTR_MAX_ADAPTERS]; +static int irq[SMCTR_MAX_ADAPTERS]; +static int mem[SMCTR_MAX_ADAPTERS]; MODULE_PARM(io, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i"); diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 22dd24ab2..19d4f8f5e 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -38,9 +38,9 @@ static int max_interrupt_work = 25; #define MAX_UNITS 8 /* Used to pass the full-duplex flag, etc. */ -static int full_duplex[MAX_UNITS] = {0, }; -static int options[MAX_UNITS] = {0, }; -static int mtu[MAX_UNITS] = {0, }; /* Jumbo MTU for interfaces. */ +static int full_duplex[MAX_UNITS]; +static int options[MAX_UNITS]; +static int mtu[MAX_UNITS]; /* Jumbo MTU for interfaces. */ /* The possible media types that can be set in options[] are: */ const char * const medianame[] = { @@ -924,18 +924,20 @@ static void set_rx_mode(struct net_device *dev) i++, mclist = mclist->next) set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff, hash_table); - for (i = 0; i < 32; i++) - *setup_frm++ = *setup_frm++ = hash_table[i]; + for (i = 0; i < 32; i++) { + *setup_frm++ = hash_table[i]; + *setup_frm++ = hash_table[i]; + } setup_frm = &tp->setup_frame[13*6]; } else { /* We have <= 14 addresses so we can use the wonderful 16 address perfect filtering of the Tulip. */ for (i = 0, mclist = dev->mc_list; i < dev->mc_count; i++, mclist = mclist->next) { - eaddrs = (u16 *)mclist->dmi_addr; - *setup_frm++ = *setup_frm++ = *eaddrs++; - *setup_frm++ = *setup_frm++ = *eaddrs++; - *setup_frm++ = *setup_frm++ = *eaddrs++; + u16 *eaddrs = (u16 *)mclist->dmi_addr; + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; } /* Fill the unused entries with the broadcast address. */ memset(setup_frm, 0xff, (15-i)*12); @@ -944,9 +946,9 @@ static void set_rx_mode(struct net_device *dev) /* Fill the final entry with our physical address. */ eaddrs = (u16 *)dev->dev_addr; - *setup_frm++ = *setup_frm++ = eaddrs[0]; - *setup_frm++ = *setup_frm++ = eaddrs[1]; - *setup_frm++ = *setup_frm++ = eaddrs[2]; + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; spin_lock_irqsave(&tp->lock, flags); @@ -1010,12 +1012,12 @@ static void set_rx_mode(struct net_device *dev) static int __devinit tulip_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { - static int did_version = 0; /* Already printed version info. */ + static int did_version; /* Already printed version info. */ struct tulip_private *tp; /* See note below on the multiport cards. */ static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; - static int last_irq = 0; - static int multiport_cnt = 0; /* For four-port boards w/one EEPROM */ + static int last_irq; + static int multiport_cnt; /* For four-port boards w/one EEPROM */ u8 chip_rev; int i, irq; unsigned short sum; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 667b9cb6e..8a80813aa 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -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.2 2000/09/22 12:40:31 maxk Exp $ + * $Id: tun.c,v 1.3 2000/10/23 10:01:25 maxk Exp $ */ /* @@ -20,7 +20,7 @@ * Modifications for 2.3.99-pre5 kernel. */ -#define TUN_VER "1.2" +#define TUN_VER "1.3" #include <linux/module.h> @@ -47,7 +47,6 @@ #include <asm/system.h> #include <asm/uaccess.h> - #ifdef TUN_DEBUG static int debug=0; #endif @@ -89,12 +88,6 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->name, skb->len); - - if (netif_queue_stopped(dev)) - return 1; - - tun->stats.tx_packets++; - /* Queue frame */ skb_queue_tail(&tun->txq, skb); if (skb_queue_len(&tun->txq) >= TUN_TXQ_SIZE) @@ -214,7 +207,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, const char *buf, } skb_reserve(skb, 2); - copy_from_user(skb_put(skb, count), ptr, len); + copy_from_user(skb_put(skb, len), ptr, len); skb->dev = &tun->dev; switch (tun->flags & TUN_TYPE_MASK) { @@ -233,6 +226,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, const char *buf, netif_rx(skb); tun->stats.rx_packets++; + tun->stats.rx_bytes += len; + return count; } @@ -281,6 +276,9 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, copy_to_user(ptr, skb->data, len); total += len; + tun->stats.tx_packets++; + tun->stats.tx_bytes += len; + return total; } diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 5ab238eb0..e4fa70c31 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -228,7 +228,7 @@ static int cosa_major = 117; /* Maybe the following should be allocated dynamically */ static struct cosa_data cosa_cards[MAX_CARDS]; -static int nr_cards = 0; +static int nr_cards; #ifdef COSA_ISA_AUTOPROBE static int io[MAX_CARDS+1] = { 0x220, 0x228, 0x210, 0x218, 0, }; @@ -365,7 +365,7 @@ static void debug_status_out(struct cosa_data *cosa, int status); /* ---------- Initialization stuff ---------- */ -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; #ifdef MODULE int init_module(void) @@ -1387,7 +1387,7 @@ static void cosa_kick(struct cosa_data *cosa) */ static int cosa_dma_able(struct channel_data *chan, char *buf, int len) { - static int count = 0; + static int count; unsigned long b = (unsigned long)buf; if (b+len >= MAX_DMA_ADDRESS) return 0; diff --git a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c index 6d46b2e46..520b1341a 100644 --- a/drivers/net/wan/sdlamain.c +++ b/drivers/net/wan/sdlamain.c @@ -102,8 +102,8 @@ static char drvname[] = "wanpipe"; static char fullname[] = "WANPIPE(tm) Multiprotocol Driver"; static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc."; static int ncards = CONFIG_WANPIPE_CARDS; -static int active = 0; /* number of active cards */ -static sdla_t* card_array = NULL; /* adapter data space */ +static int active; /* number of active cards */ +static sdla_t* card_array; /* adapter data space */ /* Task queue element for creating a 'thread' */ static struct tq_struct sdla_tq = diff --git a/drivers/net/wavelan.c b/drivers/net/wavelan.c index 1a11b1bd9..5c43c9a3a 100644 --- a/drivers/net/wavelan.c +++ b/drivers/net/wavelan.c @@ -173,37 +173,29 @@ static inline void wv_16_on(unsigned long ioaddr, u16 hacr) /*------------------------------------------------------------------*/ /* * Disable interrupts on the WaveLAN hardware. + * (called by wv_82586_stop()) */ static inline void wv_ints_off(device * dev) { net_local *lp = (net_local *) dev->priv; unsigned long ioaddr = dev->base_addr; - unsigned long flags; - - wv_splhi(lp, &flags); lp->hacr &= ~HACR_INTRON; hacr_write(ioaddr, lp->hacr); - - wv_splx(lp, &flags); } /* wv_ints_off */ /*------------------------------------------------------------------*/ /* * Enable interrupts on the WaveLAN hardware. + * (called by wv_hw_reset()) */ static inline void wv_ints_on(device * dev) { net_local *lp = (net_local *) dev->priv; unsigned long ioaddr = dev->base_addr; - unsigned long flags; - - wv_splhi(lp, &flags); lp->hacr |= HACR_INTRON; hacr_write(ioaddr, lp->hacr); - - wv_splx(lp, &flags); } /* wv_ints_on */ /******************* MODEM MANAGEMENT SUBROUTINES *******************/ @@ -871,14 +863,18 @@ if (lp->tx_n_in_use > 0) static inline void wv_82586_reconfig(device * dev) { net_local *lp = (net_local *) dev->priv; + unsigned long flags; /* Arm the flag, will be cleard in wv_82586_config() */ lp->reconfig_82586 = 1; /* Check if we can do it now ! */ - if((netif_running(dev)) && !(netif_queue_stopped(dev))) + if((netif_running(dev)) && !(netif_queue_stopped(dev))) { + wv_splhi(lp, &flags); /* May fail */ wv_82586_config(dev); + wv_splx(lp, &flags); + } else { #ifdef DEBUG_CONFIG_INFO printk(KERN_DEBUG @@ -2806,6 +2802,7 @@ static inline int wv_packet_write(device * dev, void *buf, short length) static int wavelan_packet_xmit(struct sk_buff *skb, device * dev) { net_local *lp = (net_local *) dev->priv; + unsigned long flags; #ifdef DEBUG_TX_TRACE printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name, @@ -2822,7 +2819,9 @@ static int wavelan_packet_xmit(struct sk_buff *skb, device * dev) * we can do it now. */ if (lp->reconfig_82586) { + wv_splhi(lp, &flags); wv_82586_config(dev); + wv_splx(lp, &flags); /* Check that we can continue */ if (lp->tx_n_in_use == (NTXBLOCKS - 1)) return 1; @@ -3369,21 +3368,17 @@ static void wv_82586_config(device * dev) ac_ias_t ias; /* IA-setup action */ ac_mcs_t mcs; /* Multicast setup */ struct dev_mc_list *dmi; - unsigned long flags; #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_82586_config()\n", dev->name); #endif - wv_splhi(lp, &flags); - /* Check nothing bad has happened */ if (lp->tx_n_in_use == (NTXBLOCKS - 1)) { #ifdef DEBUG_CONFIG_ERROR printk(KERN_INFO "%s: wv_82586_config(): Tx queue full.\n", dev->name); #endif - wv_splx(lp, &flags); return; } @@ -3524,8 +3519,6 @@ static void wv_82586_config(device * dev) if (lp->tx_n_in_use == (NTXBLOCKS - 1)) netif_stop_queue(dev); - wv_splx(lp, &flags); - #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: <-wv_82586_config()\n", dev->name); #endif @@ -3535,6 +3528,7 @@ static void wv_82586_config(device * dev) /* * This routine, called by wavelan_close(), gracefully stops the * WaveLAN controller (i82586). + * (called by wavelan_close()) */ static inline void wv_82586_stop(device * dev) { @@ -3571,6 +3565,7 @@ static inline void wv_82586_stop(device * dev) * 3. Reset & Configure LAN controller (using wv_82586_start) * 4. Start the LAN controller's command unit * 5. Start the LAN controller's receive unit + * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open()) */ static int wv_hw_reset(device * dev) { @@ -3676,16 +3671,18 @@ static void wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs) lp = (net_local *) dev->priv; ioaddr = dev->base_addr; -#ifdef DEBUG_INTERRUPT_ERROR - /* Check state of our spinlock (it should be cleared) */ +#ifdef DEBUG_INTERRUPT_INFO + /* Check state of our spinlock */ if(spin_is_locked(&lp->spinlock)) - printk(KERN_INFO + printk(KERN_DEBUG "%s: wavelan_interrupt(): spinlock is already locked !!!\n", dev->name); #endif - /* Prevent reentrancy. It is safe because wv_splhi disable interrupts - * before aquiring the spinlock */ + /* Prevent reentrancy. We need to do that because we may have + * multiple interrupt handler running concurrently. + * It is safe because wv_splhi() disables interrupts before acquiring + * the spinlock. */ spin_lock(&lp->spinlock); /* Check modem interupt */ @@ -3712,6 +3709,7 @@ static void wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs) "%s: wavelan_interrupt(): interrupt not coming from i82586\n", dev->name); #endif + spin_unlock (&lp->spinlock); return; } @@ -3752,9 +3750,6 @@ static void wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs) wv_receive(dev); } - /* Release spinlock here so that wv_hw_reset() can grab it */ - spin_unlock (&lp->spinlock); - /* Check the state of the command unit. */ if (((status & SCB_ST_CNA) == SCB_ST_CNA) || (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) && @@ -3779,6 +3774,9 @@ static void wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs) wv_hw_reset(dev); } + /* Release spinlock */ + spin_unlock (&lp->spinlock); + #ifdef DEBUG_INTERRUPT_TRACE printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name); #endif @@ -3806,14 +3804,13 @@ static void wavelan_watchdog(device * dev) dev->name); #endif - wv_splhi(lp, &flags); - /* Check that we came here for something */ if (lp->tx_n_in_use <= 0) { - wv_splx(lp, &flags); return; } + wv_splhi(lp, &flags); + /* Try to see if some buffers are not free (in case we missed * an interrupt */ nreaped = wv_complete(dev, ioaddr, lp); @@ -3910,6 +3907,7 @@ static int wavelan_open(device * dev) "%s: wavelan_open(): impossible to start the card\n", dev->name); #endif + wv_splx(lp, &flags); return -EAGAIN; } wv_splx(lp, &flags); @@ -3929,6 +3927,9 @@ static int wavelan_open(device * dev) */ static int wavelan_close(device * dev) { + net_local *lp = (net_local *) dev->priv; + unsigned long flags; + #ifdef DEBUG_CALLBACK_TRACE printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name, (unsigned int) dev); @@ -3939,7 +3940,9 @@ static int wavelan_close(device * dev) /* * Flush the Tx and disable Rx. */ + wv_splhi(lp, &flags); wv_82586_stop(dev); + wv_splx(lp, &flags); free_irq(dev->irq, dev); @@ -3965,7 +3968,7 @@ static int __init wavelan_config(device * dev) net_local *lp; #ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%x)\n", + printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n", dev->name, (unsigned int) dev, ioaddr); #endif diff --git a/drivers/net/wavelan.p.h b/drivers/net/wavelan.p.h index 3e20776fb..f7393562b 100644 --- a/drivers/net/wavelan.p.h +++ b/drivers/net/wavelan.p.h @@ -36,9 +36,9 @@ * * SMP * --- - * We now *should* be SMP compliant. - * I don't have a SMP box to verify that (my Pentium 90 is not), so - * someone has to certify that from me. + * We now are SMP compliant (I eventually fixed the remaining bugs). + * The driver has been tested on a dual P6-150 and survived my usual + * set of torture tests. * Anyway, I spent enough time chasing interrupt re-entrancy during * errors or reconfigure, and I designed the locked/unlocked sections * of the driver with great care, and with the recent addition of @@ -340,6 +340,11 @@ * - Fixup a potential gotcha when reconfiguring and thighten a bit * the interactions with Tx queue. * + * Changes made for release in 2.4.0 : + * --------------------------------- + * - Fix spinlock stupid bugs that I left in. The driver is now SMP + * compliant and doesn't lockup at startup. + * * Wishes & dreams: * ---------------- * - roaming (see Pcmcia driver) @@ -430,7 +435,7 @@ /************************ CONSTANTS & MACROS ************************/ #ifdef DEBUG_VERSION_SHOW -static const char *version = "wavelan.c : v22 (wireless extensions) 21/02/00\n"; +static const char *version = "wavelan.c : v23 (SMP + wireless extensions) 05/10/00\n"; #endif /* Watchdog temporisation */ diff --git a/drivers/net/wd.c b/drivers/net/wd.c index 8ce05ba8d..e4d53f88f 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -46,7 +46,7 @@ static unsigned int wd_portlist[] __initdata = {0x300, 0x280, 0x380, 0x240, 0}; int wd_probe(struct net_device *dev); -int wd_probe1(struct net_device *dev, int ioaddr); +static int wd_probe1(struct net_device *dev, int ioaddr); static int wd_open(struct net_device *dev); static void wd_reset_8390(struct net_device *dev); @@ -81,11 +81,6 @@ static int wd_close(struct net_device *dev); The wd_probe1() routine initializes the card and fills the station address field. */ -#ifdef HAVE_DEVLIST -struct netdev_entry wd_drv = -{"wd", wd_probe1, WD_IO_EXTENT, wd_portlist}; -#else - int __init wd_probe(struct net_device *dev) { int i; @@ -106,9 +101,8 @@ int __init wd_probe(struct net_device *dev) return -ENODEV; } -#endif -int __init wd_probe1(struct net_device *dev, int ioaddr) +static int __init wd_probe1(struct net_device *dev, int ioaddr) { int i; int checksum = 0; @@ -124,12 +118,6 @@ int __init wd_probe1(struct net_device *dev, int ioaddr) || (checksum & 0xff) != 0xFF) return -ENODEV; - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("wd.c: Passed a NULL device.\n"); - dev = init_etherdev(0, 0); - } - /* Check for semi-valid mem_start/end values if supplied. */ if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) { printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n"); @@ -438,19 +426,11 @@ wd_close(struct net_device *dev) #ifdef MODULE #define MAX_WD_CARDS 4 /* Max number of wd cards per module */ -static struct net_device dev_wd[MAX_WD_CARDS] = { - { - "", /* assign a chunk of namelist[] below */ - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, NULL - }, -}; - -static int io[MAX_WD_CARDS] = { 0, }; -static int irq[MAX_WD_CARDS] = { 0, }; -static int mem[MAX_WD_CARDS] = { 0, }; -static int mem_end[MAX_WD_CARDS] = { 0, }; /* for non std. mem size */ +static struct net_device dev_wd[MAX_WD_CARDS]; +static int io[MAX_WD_CARDS]; +static int irq[MAX_WD_CARDS]; +static int mem[MAX_WD_CARDS]; +static int mem_end[MAX_WD_CARDS]; /* for non std. mem size */ MODULE_PARM(io, "1-" __MODULE_STRING(MAX_WD_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_WD_CARDS) "i"); diff --git a/drivers/parport/Makefile b/drivers/parport/Makefile index 68d5120e2..95a778e96 100644 --- a/drivers/parport/Makefile +++ b/drivers/parport/Makefile @@ -1,101 +1,51 @@ # -# Makefile for the kernel miscellaneous drivers. +# Makefile for the kernel Parallel port device drivers. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). +# Note! Parport is the Borg. We have assimilated some other +# drivers in the `char', `net' and `scsi' directories, +# but left them there to allay suspicion. # -# Note 2! The CFLAGS definitions are now inherited from the -# parent makes.. +# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> +# Rewritten to use lists instead of if-statements. # -# Note 3! Parport is the Borg. We have assimilated some other -# drivers in the `char', `net' and `scsi' directories, but left them -# there to allay suspicion. - -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -ALL_SUB_DIRS := $(SUB_DIRS) L_TARGET := parport.a -MX_OBJS := -LX_OBJS := -MI_OBJS := -MIX_OBJS := -ifeq ($(CONFIG_PARPORT),y) - L_OBJS += share.o ieee1284.o ieee1284_ops.o procfs.o +export-objs := init.o parport_pc.o - ifeq ($(CONFIG_PARPORT_1284),y) - L_OBJS += daisy.o probe.o - endif +list-multi := parport.o +parport-objs := share.o ieee1284.o ieee1284_ops.o init.o procfs.o - ifeq ($(CONFIG_PARPORT_PC),y) - LX_OBJS += parport_pc.o - else - ifeq ($(CONFIG_PARPORT_PC),m) - MX_OBJS += parport_pc.o - endif - endif - ifeq ($(CONFIG_PARPORT_AMIGA),y) - LX_OBJS += parport_amiga.o - else - ifeq ($(CONFIG_PARPORT_AMIGA),m) - M_OBJS += parport_amiga.o - endif - endif - ifeq ($(CONFIG_PARPORT_MFC3),y) - LX_OBJS += parport_mfc3.o - else - ifeq ($(CONFIG_PARPORT_MFC3),m) - M_OBJS += parport_mfc3.o - endif - endif - ifeq ($(CONFIG_PARPORT_ATARI),y) - LX_OBJS += parport_atari.o - else - ifeq ($(CONFIG_PARPORT_ATARI),m) - M_OBJS += parport_atari.o - endif - endif - ifeq ($(CONFIG_PARPORT_SUNBPP),y) - LX_OBJS += parport_sunbpp.o - else - ifeq ($(CONFIG_PARPORT_SUNBPP),m) - MX_OBJS += parport_sunbpp.o - endif - endif - LX_OBJS += init.o -else - ifeq ($(CONFIG_PARPORT),m) - MI_OBJS += share.o ieee1284.o ieee1284_ops.o - ifeq ($(CONFIG_PARPORT_1284),y) - MI_OBJS += daisy.o probe.o - endif - ifneq ($(CONFIG_PROC_FS),n) - MI_OBJS += procfs.o - endif - MIX_OBJS += init.o - M_OBJS += parport.o - endif - ifeq ($(CONFIG_PARPORT_PC),m) - MX_OBJS += parport_pc.o - endif - ifeq ($(CONFIG_PARPORT_AMIGA),m) - M_OBJS += parport_amiga.o - endif - ifeq ($(CONFIG_PARPORT_MFC3),m) - M_OBJS += parport_mfc3.o - endif - ifeq ($(CONFIG_PARPORT_ATARI),m) - M_OBJS += parport_atari.o - endif - ifeq ($(CONFIG_PARPORT_SUNBPP),m) - M_OBJS += parport_sunbpp.o - endif +ifeq ($(CONFIG_PARPORT_1284),y) + parport-objs += daisy.o probe.o endif +obj-$(CONFIG_PARPORT) += parport.o +obj-$(CONFIG_PARPORT_PC) += parport_pc.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 + +# Extract lists of the multi-part drivers. +# The 'int-*' lists are the intermediate files used to build the multi's. +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) + +# Take multi-part drivers out of obj-y and put components in. +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) + +# Translate to Rules.make lists. +L_OBJS := $(filter-out $(export-objs), $(obj-y)) +LX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) +MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) +MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) + include $(TOPDIR)/Rules.make -# Special rule to build the composite parport.o module -parport.o: $(MI_OBJS) $(MIX_OBJS) - $(LD) $(LD_RFLAG) -r -o $@ $(MI_OBJS) $(MIX_OBJS) +parport.o: $(parport-objs) + $(LD) -r -o $@ $(parport-objs) diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c index 054bb4d89..19045439e 100644 --- a/drivers/parport/parport_mfc3.c +++ b/drivers/parport/parport_mfc3.c @@ -343,7 +343,6 @@ int __init parport_mfc3_init(void) unsigned long piabase = z->resource.start+PIABASE; if (!request_mem_region(piabase, sizeof(struct pia), "PIA")) continue; - strcpy(z->name, "MultiFace III MC6821 PIA"); pp = (struct pia *)ZTWO_VADDR(piabase); if (pias < MAX_MFC) { pp->crb = 0; diff --git a/drivers/pci/gen-devlist.c b/drivers/pci/gen-devlist.c index 9b2c652ac..586ef3d2d 100644 --- a/drivers/pci/gen-devlist.c +++ b/drivers/pci/gen-devlist.c @@ -115,7 +115,7 @@ main(void) #undef VENDOR\n\ #undef DEVICE\n\ #undef ENDVENDOR\n", devf); - fputs("\n#undef CLASS", clsf); + fputs("\n#undef CLASS\n", clsf); fclose(devf); fclose(clsf); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c0541c115..ea13f254d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -474,6 +474,16 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags) return IORESOURCE_MEM; } +/* + * Find the extent of a PCI decode.. + */ +static u32 pci_size(u32 base, unsigned long mask) +{ + u32 size = mask & base; /* Find the significant bits */ + size = size & ~(size-1); /* Get the lowest of them to find the decode size */ + return size-1; /* extent = size - 1 */ +} + static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) { unsigned int pos, reg, next; @@ -501,10 +511,10 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) l = 0; if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) { res->start = l & PCI_BASE_ADDRESS_MEM_MASK; - sz = ~(sz & PCI_BASE_ADDRESS_MEM_MASK); + sz = pci_size(sz, PCI_BASE_ADDRESS_MEM_MASK); } else { res->start = l & PCI_BASE_ADDRESS_IO_MASK; - sz = ~(sz & PCI_BASE_ADDRESS_IO_MASK) & 0xffff; + sz = pci_size(sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff); } res->end = res->start + (unsigned long) sz; res->flags |= (l & 0xf) | pci_calc_resource_flags(l); @@ -543,7 +553,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) res->flags = (l & PCI_ROM_ADDRESS_ENABLE) | IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_READONLY | IORESOURCE_CACHEABLE; res->start = l & PCI_ROM_ADDRESS_MASK; - sz = ~(sz & PCI_ROM_ADDRESS_MASK); + sz = pci_size(sz, PCI_ROM_ADDRESS_MASK); res->end = res->start + (unsigned long) sz; } res->name = dev->name; @@ -575,10 +585,17 @@ void __init pci_read_bridge_bases(struct pci_bus *child) base = ((io_base_lo & PCI_IO_RANGE_MASK) << 8) | (io_base_hi << 16); limit = ((io_limit_lo & PCI_IO_RANGE_MASK) << 8) | (io_limit_hi << 16); if (base && base <= limit) { - res->flags |= (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; + res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; res->start = base; res->end = limit + 0xfff; res->name = child->name; + } else { + /* + * Ugh. We don't know enough about this bridge. Just assume + * that it's entirely transparent. + */ + printk("Unknown bridge resource %d: assuming transparent\n", 0); + child->resource[0] = child->parent->resource[0]; } res = child->resource[1]; @@ -587,10 +604,14 @@ void __init pci_read_bridge_bases(struct pci_bus *child) base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; if (base && base <= limit) { - res->flags |= (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; + res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; res->start = base; res->end = limit + 0xfffff; res->name = child->name; + } else { + /* See comment above. Same thing */ + printk("Unknown bridge resource %d: assuming transparent\n", 1); + child->resource[1] = child->parent->resource[1]; } res = child->resource[2]; @@ -610,10 +631,14 @@ void __init pci_read_bridge_bases(struct pci_bus *child) } #endif if (base && base <= limit) { - res->flags |= (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; + res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; res->start = base; res->end = limit + 0xfffff; res->name = child->name; + } else { + /* See comments above */ + printk("Unknown bridge resource %d: assuming transparent\n", 2); + child->resource[2] = child->parent->resource[2]; } } diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids index 7723913ba..bfb9de0be 100644 --- a/drivers/pci/pci.ids +++ b/drivers/pci/pci.ids @@ -948,6 +948,10 @@ 1053 Young Micro Systems 1054 Hitachi, Ltd 1055 EFAR Microsystems + 9130 EIDE Controller + 9460 PCI to ISA Bridge + 9462 USB Universal Host Controller [OHCI] + 9463 Power Management Controller [Bridge] 1056 ICL # Motorola made a mistake and used 1507 instead of 1057 in some chips. # Please look at the 1507 entry as well when updating this. diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 83a4da2d8..9913c1998 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -209,11 +209,11 @@ static void __init quirk_vt82c686_acpi(struct pci_dev *dev) * * Legacy Support Register (LEGSUP): * bit13: USB PIRQ Enable (USBPIRQDEN), - * bit4: Trap/SMI ON IRQ Enable (USBSMIEN). + * bit4: Trap/SMI On IRQ Enable (USBSMIEN). * * We mask out all r/wc bits, too. */ -static void __init quirk_piix3usb(struct pci_dev *dev) +static void __init quirk_piix3_usb(struct pci_dev *dev) { u16 legsup; @@ -267,7 +267,8 @@ static struct pci_fixup pci_fixups[] __initdata = { { 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_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi }, - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3usb }, + { 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 }, { 0 } }; diff --git a/drivers/pcmcia/bulkmem.c b/drivers/pcmcia/bulkmem.c index e20918a25..232ab5ea5 100644 --- a/drivers/pcmcia/bulkmem.c +++ b/drivers/pcmcia/bulkmem.c @@ -2,7 +2,7 @@ PCMCIA Bulk Memory Services - bulkmem.c 1.37 2000/06/12 21:29:35 + bulkmem.c 1.38 2000/09/25 19:29:51 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -156,8 +156,7 @@ static void retry_erase(erase_busy_t *busy, u_int cause) case MTD_WAITRDY: if (req.Status == MTD_WAITRDY) insert_queue(&s->erase_busy, busy); - busy->timeout.expires = jiffies + req.Timeout*HZ/1000; - add_timer(&busy->timeout); + mod_timer(&busy->timeout, jiffies + req.Timeout*HZ/1000); break; } } else { diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 3f9fb1c7b..a177ca207 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -2,7 +2,7 @@ PCMCIA Card Information Structure parser - cistpl.c 1.90 2000/08/30 20:23:47 + cistpl.c 1.91 2000/09/16 03:48:28 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -96,6 +96,8 @@ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ #define IS_ATTR 1 #define IS_INDIRECT 8 +static int setup_cis_mem(socket_info_t *s); + static void set_cis_map(socket_info_t *s, pccard_mem_map *mem) { s->ss_entry->set_mem_map(s->sock, mem); @@ -118,8 +120,7 @@ void read_cis_mem(socket_info_t *s, int attr, u_int addr, memset(ptr, 0xff, len); return; } - mem->flags = MAP_ACTIVE; - if (cis_width) mem->flags |= MAP_16BIT; + mem->flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0); if (attr & IS_INDIRECT) { /* Indirect accesses use a bunch of special registers at fixed @@ -165,8 +166,7 @@ void write_cis_mem(socket_info_t *s, int attr, u_int addr, DEBUG(3, "cs: write_cis_mem(%d, %#x, %u)\n", attr, addr, len); if (setup_cis_mem(s) != 0) return; - mem->flags = MAP_ACTIVE; - if (cis_width) mem->flags |= MAP_16BIT; + mem->flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0); if (attr & IS_INDIRECT) { /* Indirect accesses use a bunch of special registers at fixed @@ -258,7 +258,7 @@ static int checksum_match(u_long base) return ((a == b) && (a >= 0)); } -int setup_cis_mem(socket_info_t *s) +static int setup_cis_mem(socket_info_t *s) { if (!(s->cap.features & SS_CAP_STATIC_MAP) && (s->cis_mem.sys_start == 0)) { @@ -273,7 +273,6 @@ int setup_cis_mem(socket_info_t *s) return CS_OUT_OF_RESOURCE; } s->cis_mem.sys_stop = s->cis_mem.sys_start+s->cap.map_size-1; - s->cis_mem.flags |= MAP_ACTIVE; s->cis_virt = bus_ioremap(s->cap.bus, s->cis_mem.sys_start, s->cap.map_size); } diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 2a6589aae..21482915a 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -2,7 +2,7 @@ PCMCIA Card Services -- core services - cs.c 1.267 2000/08/30 22:07:31 + 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 @@ -66,7 +66,7 @@ int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); static const char *version = -"cs.c 1.267 2000/08/30 22:07:31 (David Hinds)"; +"cs.c 1.271 2000/10/02 20:27:49 (David Hinds)"; #endif #ifdef CONFIG_PCI @@ -1711,7 +1711,7 @@ int pcmcia_request_configuration(client_handle_t handle, if (!(c->irq.Attributes & IRQ_FORCED_PULSE)) c->Option |= COR_LEVEL_REQ; write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); - udelay(40*1000); + mdelay(40); } if (req->Present & PRESENT_STATUS) { c->Status = req->Status; @@ -1726,14 +1726,14 @@ int pcmcia_request_configuration(client_handle_t handle, write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus); } if (req->Present & PRESENT_IOBASE_0) { - i = c->io.BasePort1 & 0xff; - write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &i); - i = (c->io.BasePort1 >> 8) & 0xff; - write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &i); + u_char b = c->io.BasePort1 & 0xff; + write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b); + b = (c->io.BasePort1 >> 8) & 0xff; + write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b); } if (req->Present & PRESENT_IOSIZE) { - i = c->io.NumPorts1 + c->io.NumPorts2 - 1; - write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &i); + 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 */ @@ -1840,8 +1840,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) { socket_info_t *s; config_t *c; - int try, ret = 0, irq = 0; - u_int mask; + int ret = 0, irq = 0; if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; @@ -1855,21 +1854,22 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) return CS_IN_USE; /* Short cut: if there are no ISA interrupts, then it is PCI */ - if (!s->cap.irq_mask) + if (!s->cap.irq_mask) { irq = s->cap.pci_irq; + ret = (irq) ? 0 : CS_IN_USE; #ifdef CONFIG_ISA - else if (s->irq.AssignedIRQ != 0) { + } else if (s->irq.AssignedIRQ != 0) { /* If the interrupt is already assigned, it must match */ irq = s->irq.AssignedIRQ; if (req->IRQInfo1 & IRQ_INFO2_VALID) { - mask = req->IRQInfo2 & s->cap.irq_mask; + u_int mask = req->IRQInfo2 & s->cap.irq_mask; ret = ((mask >> irq) & 1) ? 0 : CS_BAD_ARGS; } else ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS; } else { ret = CS_IN_USE; if (req->IRQInfo1 & IRQ_INFO2_VALID) { - mask = req->IRQInfo2 & s->cap.irq_mask; + u_int try, mask = req->IRQInfo2 & s->cap.irq_mask; for (try = 0; try < 2; try++) { for (irq = 0; irq < 32; irq++) if ((mask >> irq) & 1) { @@ -1882,8 +1882,8 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) irq = req->IRQInfo1 & IRQ_MASK; ret = try_irq(req->Attributes, irq, 1); } - } #endif + } if (ret != 0) return ret; if (req->Attributes & IRQ_HANDLE_PRESENT) { @@ -1902,7 +1902,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) c->state |= CONFIG_IRQ_REQ; handle->state |= CLIENT_IRQ_REQ; return CS_SUCCESS; -} /* cs_request_irq */ +} /* pcmcia_request_irq */ /*====================================================================== diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 47efc86b0..126506431 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -1,5 +1,5 @@ /* - * cs_internal.h 1.52 2000/06/12 21:29:37 + * cs_internal.h 1.54 2000/10/26 20:10:55 * * 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 @@ -204,14 +204,13 @@ void cb_enable(socket_info_t *s); void cb_disable(socket_info_t *s); void read_cb_mem(socket_info_t *s, u_char fn, int space, u_int addr, u_int len, void *ptr); -void cb_release_cis_mem(socket_info_t * s); +void cb_release_cis_mem(socket_info_t *s); /* In cistpl.c */ void read_cis_mem(socket_info_t *s, int attr, u_int addr, u_int len, void *ptr); void write_cis_mem(socket_info_t *s, int attr, u_int addr, u_int len, void *ptr); -int setup_cis_mem(socket_info_t *s); void release_cis_mem(socket_info_t *s); int verify_cis_cache(socket_info_t *s); void preload_cis_cache(socket_info_t *s); diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c index 4569e0dd8..c9a3ddab3 100644 --- a/drivers/pcmcia/yenta.c +++ b/drivers/pcmcia/yenta.c @@ -256,11 +256,13 @@ static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state) } else { u8 reg; - bridge |= CB_BRIDGE_INTR; reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA); reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; - reg |= state->io_irq; + if (state->io_irq != socket->cb_irq) { + reg |= state->io_irq; + bridge |= CB_BRIDGE_INTR; + } exca_writeb(socket, I365_INTCTL, reg); reg = exca_readb(socket, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK); @@ -626,7 +628,7 @@ static void yenta_config_init(pci_socket_t *socket) PCI_COMMAND_WAIT); /* MAGIC NUMBERS! Fixme */ - config_writeb(socket, PCI_CACHE_LINE_SIZE, 32); + config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4); config_writeb(socket, PCI_LATENCY_TIMER, 168); config_writeb(socket, PCI_SEC_LATENCY_TIMER, 176); config_writeb(socket, PCI_PRIMARY_BUS, dev->bus->number); diff --git a/drivers/pnp/isapnp.c b/drivers/pnp/isapnp.c index 45f7f05f1..7d7b705c7 100644 --- a/drivers/pnp/isapnp.c +++ b/drivers/pnp/isapnp.c @@ -20,6 +20,8 @@ * Changelog: * 2000-01-01 Added quirks handling for buggy hardware * Peter Denison <peterd@pnd-pc.demon.co.uk> + * 2000-06-14 Added isapnp_probe_devs() and isapnp_activate_dev() + * Christoph Hellwig <hch@caldera.de> */ #include <linux/config.h> @@ -244,14 +246,15 @@ static void __init isapnp_peek(unsigned char *data, int bytes) unsigned char d=0; for (i = 1; i <= bytes; i++) { - for (j = 0; j < 10; j++) { + for (j = 0; j < 20; j++) { d = isapnp_read_byte(0x05); if (d & 1) break; udelay(100); } if (!(d & 1)) { - *data++ = 0xff; + if (data != NULL) + *data++ = 0xff; continue; } d = isapnp_read_byte(0x04); /* PRESDI */ @@ -1219,9 +1222,9 @@ isapnp_match_card(const struct isapnp_card_id *ids, struct pci_bus *card) { int idx; - while (ids->vendor || ids->device) { - if ((ids->vendor == ISAPNP_ANY_ID || ids->vendor == card->vendor) && - (ids->device == ISAPNP_ANY_ID || ids->device == card->device)) { + while (ids->card_vendor || ids->card_device) { + if ((ids->card_vendor == ISAPNP_ANY_ID || ids->card_vendor == card->vendor) && + (ids->card_device == ISAPNP_ANY_ID || ids->card_device == card->device)) { for (idx = 0; idx < ISAPNP_CARD_DEVS; idx++) { if (ids->devs[idx].vendor == 0 && ids->devs[idx].function == 0) @@ -1258,6 +1261,56 @@ int isapnp_probe_cards(const struct isapnp_card_id *ids, return count; } +static const struct isapnp_device_id * +isapnp_match_dev(const struct isapnp_device_id *ids, struct pci_dev *dev) +{ + while (ids->card_vendor || ids->card_device) { + if ((ids->card_vendor == ISAPNP_ANY_ID || ids->card_vendor == dev->bus->vendor) && + (ids->card_device == ISAPNP_ANY_ID || ids->card_device == dev->bus->device) && + (ids->vendor == ISAPNP_ANY_ID || ids->vendor == dev->vendor) && + (ids->function == ISAPNP_ANY_ID || ids->function == dev->device)) + return ids; + ids++; + } + return NULL; +} + +int isapnp_probe_devs(const struct isapnp_device_id *ids, + int (*probe)(struct pci_dev *dev, + const struct isapnp_device_id *id)) +{ + + struct pci_dev *dev; + const struct isapnp_device_id *id; + int count = 0; + + if (ids == NULL || probe == NULL) + return -EINVAL; + isapnp_for_each_dev(dev) { + id = isapnp_match_dev(ids, dev); + if (id != NULL && probe(dev, id) >= 0) + count++; + } + return count; +} + +int isapnp_activate_dev(struct pci_dev *dev, const char *name) +{ + int err; + + /* Device already active? Let's use it and inform the caller */ + if (dev->active) + return -EBUSY; + + if ((err = dev->activate(dev)) < 0) { + printk(KERN_ERR "isapnp: config of %s failed (out of resources?)[%d]\n", name, err); + dev->deactivate(dev); + return err; + } + + return 0; +} + static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma) { return dma->flags | IORESOURCE_DMA | IORESOURCE_AUTO; @@ -2104,6 +2157,8 @@ EXPORT_SYMBOL(isapnp_deactivate); EXPORT_SYMBOL(isapnp_find_card); EXPORT_SYMBOL(isapnp_find_dev); EXPORT_SYMBOL(isapnp_probe_cards); +EXPORT_SYMBOL(isapnp_probe_devs); +EXPORT_SYMBOL(isapnp_activate_dev); EXPORT_SYMBOL(isapnp_resource_change); int __init isapnp_init(void) diff --git a/drivers/s390/Config.in b/drivers/s390/Config.in index d973c4e1b..dd95a0ab2 100644 --- a/drivers/s390/Config.in +++ b/drivers/s390/Config.in @@ -5,7 +5,7 @@ tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP if [ "$CONFIG_NET" = "y" ]; then tristate 'Network block device support' CONFIG_BLK_DEV_NBD fi -include drivers/md/Config.in +source drivers/md/Config.in tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD @@ -24,6 +24,8 @@ if [ "$CONFIG_DASD" != "n" ]; then bool ' Support for DIAG access to CMS reserved Disks' CONFIG_DASD_MDSK fi +endmenu + #menu_option next_comment #endmenu @@ -33,7 +35,7 @@ if [ "$CONFIG_NET" = "y" ]; then bool 'Channel Device Configuration (Temporary Option)' CONFIG_CHANDEV bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then - menu_option next_comment + mainmenu_option next_comment comment 'S390 Network devices' bool 'CTC device support' CONFIG_CTC bool 'IUCV device support (VM only)' CONFIG_IUCV @@ -41,6 +43,7 @@ if [ "$CONFIG_NET" = "y" ]; then bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET bool 'Token Ring driver support' CONFIG_TR bool 'FDDI driver support' CONFIG_FDDI + endmenu fi endmenu fi diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index aec5d83af..624d7dfd7 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -795,17 +795,12 @@ static int __init con3215_consetup(struct console *co, char *options) * The console structure for the 3215 console */ static struct console con3215 = { - "tty3215", - con3215_write, - NULL, - con3215_device, - NULL, - con3215_unblank, - con3215_consetup, - CON_PRINTBUFFER, - 0, - 0, - NULL + name: "tty3215", + write: con3215_write, + device: con3215_device, + unblank: con3215_unblank, + setup: con3215_consetup, + flags: CON_PRINTBUFFER, }; #endif diff --git a/drivers/s390/char/hwc_con.c b/drivers/s390/char/hwc_con.c index 16d5553e8..238dd2150 100644 --- a/drivers/s390/char/hwc_con.c +++ b/drivers/s390/char/hwc_con.c @@ -35,17 +35,10 @@ kdev_t hwc_console_device (struct console *); struct console hwc_console = { - hwc_console_name, - hwc_console_write, - NULL, - hwc_console_device, - NULL, - NULL, - NULL, - CON_PRINTBUFFER, - 0, - 0, - NULL + name: hwc_console_name, + write: hwc_console_write, + device: hwc_console_device, + flags: CON_PRINTBUFFER, }; void diff --git a/drivers/sbus/Makefile b/drivers/sbus/Makefile index 9e03e890b..7be59e066 100644 --- a/drivers/sbus/Makefile +++ b/drivers/sbus/Makefile @@ -11,21 +11,21 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) char audio ALL_SUB_DIRS := $(SUB_DIRS) char audio -L_OBJS := sbus.o dvma.o -L_TARGET := sbus.a +O_OBJS := sbus.o dvma.o +O_TARGET := sbus_all.o # Character devices for SBUS-based machines. # ifeq ($(CONFIG_SBUSCHAR),y) SUB_DIRS += char -L_OBJS += char/sunchar.o +O_OBJS += char/sunchar.o endif # Audio devices for SBUS-based machines. # ifeq ($(CONFIG_SPARCAUDIO),y) SUB_DIRS += audio -L_OBJS += audio/sparcaudio.o +O_OBJS += audio/sparcaudio.o endif include $(TOPDIR)/Rules.make diff --git a/drivers/sbus/audio/Makefile b/drivers/sbus/audio/Makefile index cf38aa1d8..eaac51698 100644 --- a/drivers/sbus/audio/Makefile +++ b/drivers/sbus/audio/Makefile @@ -1,76 +1,23 @@ # -# Makefile for the linux kernel. +# Makefile for the kernel SPARC audio drivers. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -# -# sbus audio drivers +# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> +# Rewritten to use lists instead of if-statements. # O_TARGET := sparcaudio.o -O_OBJS := -M_OBJS := -M := -MM := - -ifeq ($(CONFIG_SPARCAUDIO),y) -M=y -else - ifeq ($(CONFIG_SPARCAUDIO),m) - MM=y - endif -endif - -ifeq ($(CONFIG_SPARCAUDIO_AMD7930),y) -M=y -OX_OBJS += amd7930.o -else - ifeq ($(CONFIG_SPARCAUDIO_AMD7930),m) - MM=y - MX_OBJS += amd7930.o - endif -endif - -ifeq ($(CONFIG_SPARCAUDIO_CS4231),y) -M=y -O_OBJS += cs4231.o -else - ifeq ($(CONFIG_SPARCAUDIO_CS4231),m) - MM=y - M_OBJS += cs4231.o - endif -endif -ifeq ($(CONFIG_SPARCAUDIO_DBRI),y) -M=y -OX_OBJS += dbri.o -else - ifeq ($(CONFIG_SPARCAUDIO_DBRI),m) - MM=y - MX_OBJS += dbri.o - endif -endif +export-objs := audio.o amd7930.o dbri.o -ifeq ($(CONFIG_SPARCAUDIO_DUMMY),y) -M=y -O_OBJS += dmy.o -else - ifeq ($(CONFIG_SPARCAUDIO_DUMMY),m) - MM=y - M_OBJS += dmy.o - endif -endif +obj-$(CONFIG_SPARCAUDIO) += audio.o +obj-$(CONFIG_SPARCAUDIO_AMD7930) += amd7930.o +obj-$(CONFIG_SPARCAUDIO_CS4231) += cs4231.o +obj-$(CONFIG_SPARCAUDIO_DBRI) += dbri.o +obj-$(CONFIG_SPARCAUDIO_DUMMY) += dmy.o -ifdef M -OX_OBJS += audio.o -else - ifdef MM - MX_OBJS += audio.o - endif -endif +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff --git a/drivers/sbus/audio/audio.c b/drivers/sbus/audio/audio.c index 46fa74b0c..5062a4300 100644 --- a/drivers/sbus/audio/audio.c +++ b/drivers/sbus/audio/audio.c @@ -1,4 +1,4 @@ -/* $Id: audio.c,v 1.54 2000/07/13 08:06:40 davem Exp $ +/* $Id: audio.c,v 1.56 2000/10/19 00:50:02 davem Exp $ * drivers/sbus/audio/audio.c * * Copyright 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) @@ -70,8 +70,8 @@ static int lis_del_from_elist( strevent_t **list, pid_t pid, short events ); static void lis_free_elist( strevent_t **list); static void kill_procs( struct strevent *elist, int sig, short e); -static struct sparcaudio_driver *drivers[SPARCAUDIO_MAX_DEVICES] = {NULL}; -static devfs_handle_t devfs_handle = NULL; +static struct sparcaudio_driver *drivers[SPARCAUDIO_MAX_DEVICES]; +static devfs_handle_t devfs_handle; /* This crap to be pulled off into a local include file */ #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100 @@ -2192,33 +2192,13 @@ int unregister_sparcaudio_driver(struct sparcaudio_driver *drv, int duplex) return 0; } -#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100 -static struct symbol_table sparcaudio_syms = { -#include <linux/symtab_begin.h> - X(register_sparcaudio_driver), - X(unregister_sparcaudio_driver), - X(sparcaudio_output_done), - X(sparcaudio_input_done), -#include <linux/symtab_end.h> -}; -#else EXPORT_SYMBOL(register_sparcaudio_driver); EXPORT_SYMBOL(unregister_sparcaudio_driver); EXPORT_SYMBOL(sparcaudio_output_done); EXPORT_SYMBOL(sparcaudio_input_done); -#endif -#ifdef MODULE -int init_module(void) -#else -int __init sparcaudio_init(void) -#endif +static int __init sparcaudio_init(void) { -#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100 - /* Export symbols for use by the low-level drivers. */ - register_symtab(&sparcaudio_syms); -#endif - /* Register our character device driver with the VFS. */ if (devfs_register_chrdev(SOUND_MAJOR, "sparcaudio", &sparcaudio_fops)) return -EIO; @@ -2241,13 +2221,14 @@ int __init sparcaudio_init(void) return 0; } -#ifdef MODULE -void cleanup_module(void) +static void __exit sparcaudio_exit(void) { devfs_unregister_chrdev(SOUND_MAJOR, "sparcaudio"); devfs_unregister (devfs_handle); } -#endif + +module_init(sparcaudio_init) +module_exit(sparcaudio_exit) /* * Code from Linux Streams, Copyright 1995 by diff --git a/drivers/sbus/audio/cs4215.h b/drivers/sbus/audio/cs4215.h index 6effd54d3..60139bb19 100644 --- a/drivers/sbus/audio/cs4215.h +++ b/drivers/sbus/audio/cs4215.h @@ -1,4 +1,4 @@ -/* $Id: cs4215.h,v 1.7 1999/09/21 14:37:19 davem Exp $ +/* $Id: cs4215.h,v 1.8 2000/10/27 07:01:38 uzi Exp $ * drivers/sbus/audio/cs4215.h * * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) @@ -103,7 +103,7 @@ static struct { /* Time Slot 6, Output Setting */ #define CS4215_RO(v) v /* Right Output Attenuation 0x3f: -94.5 dB */ -#define CS4215_SE (1<<6) /* Line Out Enable */ +#define CS4215_SE (1<<6) /* Speaker Enable */ #define CS4215_ADI (1<<7) /* A/D Data Invalid: Busy in calibration */ /* Time Slot 7, Input Setting */ diff --git a/drivers/sbus/audio/dbri.c b/drivers/sbus/audio/dbri.c index b3a53b4a7..ad0d879b1 100644 --- a/drivers/sbus/audio/dbri.c +++ b/drivers/sbus/audio/dbri.c @@ -1,4 +1,4 @@ -/* $Id: dbri.c,v 1.21 2000/08/31 23:44:17 davem Exp $ +/* $Id: dbri.c,v 1.22 2000/10/27 07:01:38 uzi Exp $ * drivers/sbus/audio/dbri.c * * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) @@ -486,6 +486,7 @@ static void dbri_process_interrupt_buffer(struct dbri *dbri) else if ((dbri->dbri_irqp & (DBRI_INT_BLK-1)) == 0) dbri->dbri_irqp++; + tprintk(("dbri->dbri_irqp == %d\n", dbri->dbri_irqp)); dbri_process_one_interrupt(dbri, x); } } @@ -1269,6 +1270,7 @@ static void mmcodec_setgain(struct dbri *dbri, int muted) } else { int left_gain = (dbri->perchip_info.play.gain / 4) % 64; int right_gain = (dbri->perchip_info.play.gain / 4) % 64; + int outport = dbri->perchip_info.play.port; if (dbri->perchip_info.play.balance < AUDIO_MID_BALANCE) { right_gain *= dbri->perchip_info.play.balance; @@ -1282,8 +1284,11 @@ static void mmcodec_setgain(struct dbri *dbri, int muted) dprintk(D_MM, ("DBRI: Setting codec gain left: %d right: %d\n", left_gain, right_gain)); - dbri->mm.data[0] = CS4215_LE | CS4215_HE | (63 - left_gain); - dbri->mm.data[1] = CS4215_SE | (63 - right_gain); + dbri->mm.data[0] = (63 - left_gain); + if (outport & AUDIO_HEADPHONE) dbri->mm.data[0] |= CS4215_HE; + if (outport & AUDIO_LINE_OUT) dbri->mm.data[0] |= CS4215_LE; + dbri->mm.data[1] = (63 - right_gain); + if (outport & AUDIO_SPEAKER) dbri->mm.data[1] |= CS4215_SE; } xmit_fixed(dbri, 20, *(int *)dbri->mm.data); @@ -1484,8 +1489,14 @@ static int mmcodec_init(struct sparcaudio_driver *drv) dbri->perchip_info.play.channels = 1; dbri->perchip_info.play.precision = 8; - dbri->perchip_info.play.gain = 255; + dbri->perchip_info.play.gain = (AUDIO_MAX_GAIN * 7 / 10); /* 70% */ dbri->perchip_info.play.balance = AUDIO_MID_BALANCE; + dbri->perchip_info.play.port = dbri->perchip_info.play.avail_ports = + AUDIO_SPEAKER | AUDIO_HEADPHONE | AUDIO_LINE_OUT; + dbri->perchip_info.record.port = AUDIO_MICROPHONE; + dbri->perchip_info.record.avail_ports = + AUDIO_MICROPHONE | AUDIO_LINE_IN; + mmcodec_init_data(dbri); return 0; @@ -1834,32 +1845,52 @@ static int dbri_get_input_rate(struct sparcaudio_driver *drv) static int dbri_set_output_port(struct sparcaudio_driver *drv, int port) { - return 0; + struct dbri *dbri = (struct dbri *) drv->private; + + port &= dbri->perchip_info.play.avail_ports; + dbri->perchip_info.play.port = port; + mmcodec_setgain(dbri, 0); + + return 0; } static int dbri_get_output_port(struct sparcaudio_driver *drv) { - return 0; + struct dbri *dbri = (struct dbri *) drv->private; + + return dbri->perchip_info.play.port; } static int dbri_set_input_port(struct sparcaudio_driver *drv, int port) { - return 0; + struct dbri *dbri = (struct dbri *) drv->private; + + port &= dbri->perchip_info.record.avail_ports; + dbri->perchip_info.record.port = port; + mmcodec_setgain(dbri, 0); + + return 0; } static int dbri_get_input_port(struct sparcaudio_driver *drv) { - return 0; + struct dbri *dbri = (struct dbri *) drv->private; + + return dbri->perchip_info.record.port; } static int dbri_get_output_ports(struct sparcaudio_driver *drv) { - return 0; + struct dbri *dbri = (struct dbri *) drv->private; + + return dbri->perchip_info.play.avail_ports; } static int dbri_get_input_ports(struct sparcaudio_driver *drv) { - return 0; + struct dbri *dbri = (struct dbri *) drv->private; + + return dbri->perchip_info.record.avail_ports; } /******************* sparcaudio midlevel - driver ID ********************/ @@ -1889,12 +1920,6 @@ static int dbri_open(struct inode * inode, struct file * file, { MOD_INC_USE_COUNT; - /* I've taken the liberty of setting half gain and - * mid balance, to put the codec in a known state. - */ - dbri_set_output_balance(drv, AUDIO_MID_BALANCE); - dbri_set_output_volume(drv, AUDIO_MAX_GAIN / 2); - return 0; } diff --git a/drivers/sbus/audio/dbri.h b/drivers/sbus/audio/dbri.h index 1cbe77241..c7f8be99c 100644 --- a/drivers/sbus/audio/dbri.h +++ b/drivers/sbus/audio/dbri.h @@ -1,4 +1,4 @@ -/* $Id: dbri.h,v 1.12 1999/09/21 14:37:34 davem Exp $ +/* $Id: dbri.h,v 1.13 2000/10/13 00:34:24 uzi Exp $ * drivers/sbus/audio/cs4231.h * * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) @@ -18,7 +18,12 @@ #define REG9 0x24UL /* Interrupt Queue Pointer */ #define DBRI_NO_CMDS 64 -#define DBRI_NO_INTS 2 +#define DBRI_NO_INTS 1 /* Note: the value of this define was + * originally 2. The ringbuffer to store + * interrupts in dma is currently broken. + * This is a temporary fix until the ringbuffer + * is fixed. + */ #define DBRI_INT_BLK 64 #define DBRI_NO_DESCS 64 diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile index 7c5a21b2c..ad8b7e140 100644 --- a/drivers/sbus/char/Makefile +++ b/drivers/sbus/char/Makefile @@ -1,128 +1,47 @@ # -# Makefile for the linux kernel. +# Makefile for the kernel miscellaneous SPARC device drivers. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - # Dave Redman Frame Buffer tuning support. -# OK this is kind of ugly but it does allow drivers to be added fairly -# easily. and you can even choose what sort of support you want. +# +# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> +# Rewritten to use lists instead of if-statements. +# O_TARGET := sunchar.o O_OBJS := ${O_OBJ} sunkbd.o sunkbdmap.o sunmouse.o sunserial.o zs.o -M_OBJS := -ifeq ($(ARCH),sparc64) +vfc-objs := vfc_dev.o vfc_i2c.o ifeq ($(CONFIG_PCI),y) - -OX_OBJS += su.o -O_OBJS += pcikbd.o - -ifeq ($(CONFIG_SAB82532),y) -O_OBJS += sab82532.o -else - ifeq ($(CONFIG_SAB82532),m) - M_OBJS += sab82532.o - endif -endif - -ifeq ($(CONFIG_ENVCTRL),y) -O_OBJS += envctrl.o -else - ifeq ($(CONFIG_ENVCTRL),m) - M_OBJS += envctrl.o - endif -endif - -ifeq ($(CONFIG_DISPLAY7SEG),y) -O_OBJS += display7seg.o -else - ifeq ($(CONFIG_DISPLAY7SEG),m) - M_OBJS += display7seg.o - endif -endif - -endif # eq($(CONFIG_PCI,y) - -ifeq ($(CONFIG_OBP_FLASH),y) -O_OBJS += flash.o -else - ifeq ($(CONFIG_OBP_FLASH),m) - M_OBJS += flash.o - endif +OX_OBJS += su.o +O_OBJS += pcikbd.o endif -else # !eq($(ARCH),sparc64) +ifeq ($(ARCH),sparc64) ifeq ($(CONFIG_PCI),y) -OX_OBJS += su.o -O_OBJS += pcikbd.o -endif - -endif # !eq($(ARCH),sparc64) - -ifeq ($(CONFIG_SUN_OPENPROMIO),y) -O_OBJS += openprom.o -else - ifeq ($(CONFIG_SUN_OPENPROMIO),m) - M_OBJS += openprom.o - endif +obj-$(CONFIG_SAB82532) += sab82532.o +obj-$(CONFIG_ENVCTRL) += envctrl.o +obj-$(CONFIG_DISPLAY7SEG) += display7seg.o endif -ifeq ($(CONFIG_SUN_MOSTEK_RTC),y) -O_OBJS += rtc.o -else - ifeq ($(CONFIG_SUN_MOSTEK_RTC),m) - M_OBJS += rtc.o - endif +obj-$(CONFIG_OBP_FLASH) += flash.o endif -ifeq ($(CONFIG_SUN_BPP),y) -O_OBJS += bpp.o -else - ifeq ($(CONFIG_SUN_BPP),m) - M_OBJS += bpp.o - endif -endif - -ifeq ($(CONFIG_SUN_VIDEOPIX),y) -O_OBJS += vfc.o -else - ifeq ($(CONFIG_SUN_VIDEOPIX),m) - M_OBJS += vfc.o - endif -endif +obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o +obj-$(CONFIG_SUN_MOSTEK_RTC) += rtc.o +obj-$(CONFIG_SUN_BPP) += bpp.o +obj-$(CONFIG_SUN_VIDEOPIX) += vfc.o +obj-$(CONFIG_SUN_AURORA) += aurora.o +obj-$(CONFIG_TADPOLE_TS102_UCTRL) += uctrl.o +obj-$(CONFIG_SUN_JSFLASH) += jsflash.o -ifeq ($(CONFIG_SUN_AURORA),y) -O_OBJS += aurora.o -else - ifeq ($(CONFIG_SUN_AURORA),m) - M_OBJS += aurora.o - endif -endif - -ifeq ($(CONFIG_TADPOLE_TS102_UCTRL),y) -O_OBJS += uctrl.o -else - ifeq ($(CONFIG_TADPOLE_TS102_UCTRL),m) - M_OBJS += uctrl.o - endif -endif - -ifeq ($(CONFIG_SUN_JSFLASH),y) -O_OBJS += jsflash.o -endif -ifeq ($(CONFIG_SUN_JSFLASH),m) -M_OBJS += jsflash.o -endif +O_OBJS += $(obj-y) +M_OBJS := $(obj-m) include $(TOPDIR)/Rules.make sunkbdmap.o: sunkeymap.c -vfc.o: vfc_dev.o vfc_i2c.o - $(LD) -r -o vfc.o vfc_dev.o vfc_i2c.o +vfc.o: $(vfc-objs) + $(LD) -r -o $@ $(vfc-objs) diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index 133246129..4579404e3 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c @@ -1015,7 +1015,7 @@ static inline void freeLptPort(int idx) #endif -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; #ifdef MODULE int init_module(void) diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index dbba073de..31c9de932 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1,23 +1,29 @@ -/* $Id: envctrl.c,v 1.17 2000/06/19 06:24:47 davem Exp $ +/* $Id: envctrl.c,v 1.18 2000/10/17 16:20:35 davem Exp $ * envctrl.c: Temperature and Fan monitoring on Machines providing it. * * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) + * Copyright (C) 2000 Vinh Truong (vinh.truong@eng.sun.com) + * VT - The implementation is to support Sun Microelectronics (SME) platform + * environment monitoring. SME platforms use pcf8584 as the i2c bus + * controller to access pcf8591 (8-bit A/D and D/A converter) and + * pcf8571 (256 x 8-bit static low-voltage RAM with I2C-bus interface). + * At board level, it follows SME Firmware I2C Specification. Reference: + * http://www-eu2.semiconductors.com/pip/PCF8584P + * http://www-eu2.semiconductors.com/pip/PCF8574AP + * http://www-eu2.semiconductors.com/pip/PCF8591P + * */ -#include <linux/version.h> #include <linux/config.h> #include <linux/module.h> - -#define __KERNEL_SYSCALLS__ #include <linux/sched.h> -#include <linux/unistd.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/ioport.h> #include <linux/init.h> -#include <linux/malloc.h> #include <linux/miscdevice.h> -#include <linux/smp_lock.h> +#include <linux/mm.h> +#include <linux/malloc.h> #include <asm/ebus.h> #include <asm/uaccess.h> @@ -25,18 +31,6 @@ #define ENVCTRL_MINOR 162 - -#undef U450_SUPPORT /* might fry you machine, careful here !!! */ - - -#undef DEBUG -#undef DEBUG_BUS_SCAN - - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0) -#define schedule_timeout(a) { current->timeout = jiffies + (a); schedule(); } -#endif - #define PCF8584_ADDRESS 0x55 #define CONTROL_PIN 0x80 @@ -71,1532 +65,879 @@ #define CLK_8 0x18 #define CLK_12 0x1c +#define OBD_SEND_START 0xc5 /* value to generate I2c_bus START condition */ +#define OBD_SEND_STOP 0xc3 /* value to generate I2c_bus STOP condition */ -#define I2C_WRITE 0x00 -#define I2C_READ 0x01 - -/* PCF8584 register offsets */ -#define I2C_DATA 0x00UL -#define I2C_CSR 0x01UL -#define I2C_REG_SIZE 0x02UL - -struct i2c_device { - unsigned char addr; - struct i2c_device *next; -}; - -static unsigned long i2c_regs; -static struct i2c_device *i2c_devices; - -static int errno; - -#define MAX_TEMPERATURE 111 -#define MAX_FAN_SPEED 63 - - -/* - * UltraAXi constants. +/* Monitor type of i2c child device. + * Firmware definitions. */ -#define AXI_THERM_ADDR 0x9e -#define AXI_THERM_PORT_CPU 0 -#define AXI_THERM_PORT_MOD 1 -#define AXI_THERM_PORT_PCI 2 -#define AXI_THERM_PORT_DISK 3 - -#define AXI_FAN_ADDR 0x4e -#define AXI_FAN_PORT_FRONT 0 -#define AXI_FAN_PORT_BACK 1 - -#define AXI_PIO_ADDR 0x70 +#define PCF8584_MAX_CHANNELS 8 +#define PCF8584_FANSTAT_TYPE 3 /* fan status monitor */ +#define PCF8584_VOLTAGE_TYPE 2 /* voltage monitor */ +#define PCF8584_TEMP_TYPE 1 /* temperature monitor*/ -/* - * Ultra 450 constants. +/* Monitor type of i2c child device. + * Driver definitions. */ -#define U450_FAN_ADDR 0x4e -#define U450_FAN_PORT_CPU 0 -#define U450_FAN_PORT_PS 1 - -#define U450_PIO_ADDR 0x70 -#define U450_TIMER_ADDR 0xa0 - -static unsigned char -axi_cpu_temp_table[256] = -{ - 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x67, - 0x66, 0x65, 0x64, 0x63, 0x61, 0x60, 0x5f, 0x5e, - 0x5d, 0x5b, 0x5a, 0x59, 0x58, 0x57, 0x55, 0x54, - 0x53, 0x52, 0x50, 0x4f, 0x4e, 0x4d, 0x4c, 0x4a, - 0x49, 0x48, 0x47, 0x46, 0x44, 0x43, 0x42, 0x41, - 0x40, 0x3e, 0x3d, 0x3c, 0x3c, 0x3b, 0x3b, 0x3a, - 0x3a, 0x39, 0x39, 0x38, 0x38, 0x37, 0x37, 0x36, - 0x36, 0x35, 0x35, 0x34, 0x34, 0x33, 0x33, 0x32, - 0x32, 0x31, 0x31, 0x30, 0x30, 0x2f, 0x2f, 0x2e, - 0x2d, 0x2d, 0x2c, 0x2c, 0x2b, 0x2b, 0x2a, 0x2a, - 0x29, 0x29, 0x28, 0x28, 0x27, 0x27, 0x26, 0x26, - 0x25, 0x25, 0x24, 0x24, 0x23, 0x23, 0x22, 0x22, - 0x21, 0x21, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c, - 0x1c, 0x1c, 0x1b, 0x1b, 0x1b, 0x1b, 0x1a, 0x1a, - 0x1a, 0x1a, 0x1a, 0x19, 0x19, 0x19, 0x19, 0x18, - 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x17, 0x16, - 0x16, 0x16, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15, - 0x15, 0x14, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, - 0x13, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, - 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, - 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, - 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, - 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static unsigned char -axi_mod_temp_table[256] = -{ - 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, - 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, 0x57, 0x56, - 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x4e, - 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, - 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, - 0x3d, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x39, - 0x39, 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, - 0x35, 0x35, 0x34, 0x34, 0x33, 0x33, 0x32, 0x32, - 0x31, 0x31, 0x30, 0x30, 0x2f, 0x2f, 0x2e, 0x2e, - 0x2e, 0x2d, 0x2d, 0x2c, 0x2c, 0x2b, 0x2b, 0x2a, - 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x27, 0x27, - 0x26, 0x26, 0x25, 0x25, 0x24, 0x24, 0x23, 0x23, - 0x23, 0x22, 0x22, 0x21, 0x21, 0x20, 0x20, 0x1f, - 0x1f, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1d, - 0x1d, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1b, 0x1b, - 0x1b, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x19, 0x19, - 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x16, 0x16, 0x16, 0x16, 0x15, - 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x14, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x12, - 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, - 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, - 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, - 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static unsigned char -axi_fan_speeds[112] = -{ - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x20, - 0x22, 0x23, 0x25, 0x27, 0x28, 0x2a, 0x2b, 0x2d, - 0x2f, 0x30, 0x32, 0x33, 0x35, 0x37, 0x38, 0x3a, - 0x3b, 0x3d, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f -}; - - -struct therm_regs { - u32 addr; - u32 port; - u32 min_temp; - u32 warning; - u32 shutdown; - u32 num; - u32 den; -}; +#define ENVCTRL_NOMON 0 +#define ENVCTRL_CPUTEMP_MON 1 /* cpu temperature monitor */ +#define ENVCTRL_CPUVOLTAGE_MON 2 /* voltage monitor */ +#define ENVCTRL_FANSTAT_MON 3 /* fan status monitor */ +#define ENVCTRL_ETHERTEMP_MON 4 /* ethernet temperarture */ + /* monitor */ +#define ENVCTRL_VOLTAGESTAT_MON 5 /* voltage status monitor */ +#define ENVCTRL_MTHRBDTEMP_MON 6 /* motherboard temperature */ +#define ENVCTRL_SCSITEMP_MON 7 /* scsi temperarture */ + +/* Child device type. + * Driver definitions. + */ +#define I2C_ADC 0 /* pcf8591 */ +#define I2C_GPIO 1 /* pcf8571 */ -struct thermistor { - char name[8]; - struct therm_regs regs; - unsigned char (*temperature) (struct thermistor *); - unsigned char (*fan_speed) (struct thermistor *); - struct thermistor *next; /* all thermistors */ - struct thermistor *chain; /* thermistors for one fan */ +/* Data read from child device may need to decode + * through a data table and a scale. + * Translation type as defined by firmware. + */ +#define ENVCTRL_TRANSLATE_NO 0 +#define ENVCTRL_TRANSLATE_PARTIAL 1 +#define ENVCTRL_TRANSLATE_COMBINED 2 +#define ENVCTRL_TRANSLATE_FULL 3 /* table[data] */ +#define ENVCTRL_TRANSLATE_SCALE 4 /* table[data]/scale */ + +/* Driver miscellaneous definitions. */ +#define ENVCTRL_MAX_CPU 4 +#define CHANNEL_DESC_SZ 256 + +struct pcf8584_reg { + unsigned char data; + unsigned char csr; }; -struct fan_regs { - u32 addr; - u32 port; +/* Each child device can be monitored by up to PCF8584_MAX_CHANNELS. + * Property of a port or channel as defined by the firmware. + */ +struct pcf8584_channel { + unsigned char chnl_no; + unsigned char io_direction; + unsigned char type; + unsigned char last; }; -struct fan { - char name[8]; - struct fan_regs regs; - int (*set_speed)(struct fan *, unsigned char value); - int (*check_failure)(struct fan *); - unsigned char value; - struct thermistor *monitor; - struct fan *next; +/* Each child device may have one or more tables of bytes to help decode + * data. Table property as defined by the firmware. + */ +struct pcf8584_tblprop { + unsigned int type; + unsigned int scale; + unsigned int offset; /* offset from the beginning of the table */ + unsigned int size; }; - -struct environment { - struct thermistor *thermistors; - struct fan *fans; - unsigned char *cpu_temp_table; - unsigned char *cpu_fan_speeds; - unsigned char *ps_temp_table; - unsigned char *ps_fan_speeds; - void (*enable) (struct environment *); - void (*disable) (struct environment *); - void (*keep_alive) (struct environment *); - int interval; - pid_t kenvd_pid; - wait_queue_head_t kenvd_wait; - int terminate; +/* i2c child */ +struct i2c_child_t { + /* Either ADC or GPIO. */ + unsigned char i2ctype; + unsigned long addr; + struct pcf8584_channel chnl_array[PCF8584_MAX_CHANNELS]; + + /* Channel info. */ + unsigned int total_chnls; /* Number of monitor channels. */ + unsigned char fan_mask; /* Byte mask for fan status channels. */ + unsigned char voltage_mask; /* Byte mask for voltage status channels. */ + struct pcf8584_tblprop tblprop_array[PCF8584_MAX_CHANNELS]; + + /* Properties of all monitor channels. */ + unsigned int total_tbls; /* Number of monitor tables. */ + char *tables; /* Pointer to table(s). */ + char chnls_desc[CHANNEL_DESC_SZ]; /* Channel description. */ + char mon_type[PCF8584_MAX_CHANNELS]; }; +volatile static struct pcf8584_reg *i2c = NULL; +static struct i2c_child_t i2c_childlist[ENVCTRL_MAX_CPU*2]; +static unsigned char chnls_mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; +static unsigned int warning_temperature = 0; +static unsigned int shutdown_temperature = 0; +static char read_cpu; -static struct environment envctrl; - +/* Forward declarations. */ +static struct i2c_child_t *envctrl_get_i2c_child(unsigned char); -#ifdef DEBUG_BUS_SCAN -struct i2c_addr_map { - unsigned char addr; - unsigned char mask; - char *name; -}; - -static struct i2c_addr_map devmap[] = { - { 0x70, 0xf0, "PCF8574A" }, - { 0x40, 0xf0, "TDA8444" }, - { 0x90, 0xf0, "PCF8591" }, - { 0xa0, 0xf0, "PCF8583" }, -}; -#define NR_DEVMAP (sizeof(devmap) / sizeof(devmap[0])) -#endif - -static __inline__ int -PUT_DATA(unsigned long data, char *buffer, int user) +/* Function description: Read a byte from an i2c controller register. + * Return: A byte from the passed in address. + */ +static inline unsigned char envctrl_readb(volatile unsigned char *p) { - if (user) { - u8 tmp = readb(data); - if (put_user(tmp, buffer)) - return -EFAULT; - } else { - *buffer = readb(data); - } - return 0; + return readb(p); } -static __inline__ int -GET_DATA(unsigned long data, const char *buffer, int user) +/* Function description: Write a byte to an i2c controller register. + * Return: Nothing. + */ +static inline void envctrl_writeb(unsigned char val, volatile unsigned char *p) { - if (user) { - u8 tmp; - if (get_user(tmp, buffer)) - return -EFAULT; - writeb(tmp, data); - } else { - writeb(*buffer, data); - } - return 0; + writeb(val, p); } - -static int -i2c_read(unsigned char dev, char *buffer, int len, int user) +/* Function Description: Test the PIN bit (Pending Interrupt Not) + * to test when serial transmission is completed . + * Return : None. + */ +static void envtrl_i2c_test_pin(void) { - unsigned char dummy; - unsigned char stat; - int error = -ENODEV; - int count = 0; - - writeb((dev & 0xfe) | I2C_READ, i2c_regs + I2C_DATA); - - while (!(readb(i2c_regs + I2C_CSR) & STATUS_BB)) - udelay(1); - - writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STA | CONTROL_ACK, - i2c_regs + I2C_CSR); - - do { - udelay(1); - while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN) - udelay(1); - - if (stat & STATUS_LRB) - goto stop; + int limit = 1000000; - error = 0; - if (len == 0) { - count--; + while (--limit > 0) { + if (!(envctrl_readb(&i2c->csr) & STATUS_PIN)) break; - } - - if (count == (len - 1)) - break; - - if (count++ > 0) { - error = PUT_DATA(i2c_regs + I2C_DATA, buffer++, user); - if (error) - break; - } else - dummy = readb(i2c_regs + I2C_DATA); - } while (1); - - writeb(CONTROL_ES0, i2c_regs + I2C_CSR); - if (!error && (count++ > 0)) - error = PUT_DATA(i2c_regs + I2C_DATA, buffer++, user); - else - dummy = readb(i2c_regs + I2C_DATA); - - udelay(1); - while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN) udelay(1); + } -stop: - writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STO | CONTROL_ACK, - i2c_regs + I2C_CSR); - if (!error && (count++ > 0)) - error = PUT_DATA(i2c_regs + I2C_DATA, buffer++, user); - else - dummy = readb(i2c_regs + I2C_DATA); - - if (error) - return error; - return count - 1; + if (limit <= 0) + printk(KERN_INFO "envctrl: Pin status will not clear.\n"); } -static int -i2c_write(unsigned char dev, const char *buffer, int len, int user) +/* Function Description: Test busy bit. + * Return : None. + */ +static void envctrl_i2c_test_bb(void) { - int error = -ENODEV; - int count = 0; - int timeout; - - timeout = 1000000; - while (!(readb(i2c_regs + I2C_CSR) & STATUS_BB) && --timeout) - udelay(1); - if (!timeout) { - printk("%s [%d]: TIMEOUT\n", __FUNCTION__, __LINE__); - return -ENODEV; - } - - writeb((dev & 0xfe) | I2C_WRITE, i2c_regs + I2C_DATA); - writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STA | CONTROL_ACK, - i2c_regs + I2C_CSR); - - do { - unsigned char stat; - - udelay(1); - timeout = 1000000; - while (((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN) && --timeout) - udelay(1); - - if (!timeout) { - printk("%s [%d]: TIMEOUT\n", __FUNCTION__, __LINE__); - break; - } + int limit = 1000000; - if (stat & STATUS_LRB) + while (--limit > 0) { + /* Busy bit 0 means busy. */ + if (envctrl_readb(&i2c->csr) & STATUS_BB) break; + udelay(1); + } - error = count; - if (count == len) - break; - - error = GET_DATA(i2c_regs + I2C_DATA, buffer++, user); - if (error) - break; - - count++; - } while (1); - - writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STO | CONTROL_ACK, - i2c_regs + I2C_CSR); - return error; + if (limit <= 0) + printk(KERN_INFO "envctrl: Busy bit will not clear.\n"); } -#ifdef U450_SUPPORT -static int -i2c_write_read(unsigned char dev, char *outbuf, int outlen, - char *inbuf, int inlen, int user) +/* Function Description: Send the adress for a read access. + * Return : 0 if not acknowledged, otherwise acknowledged. + */ +static int envctrl_i2c_read_addr(unsigned char addr) { - unsigned char dummy; - unsigned char stat; - int error = -ENODEV; - int count = 0; - - while (!(readb(i2c_regs + I2C_CSR) & STATUS_BB)) - udelay(1); - - writeb((dev & 0xfe) | I2C_WRITE, i2c_regs + I2C_DATA); - writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STA | CONTROL_ACK, - i2c_regs + I2C_CSR); - - do { - unsigned char stat; - - udelay(1); - while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN) - udelay(1); + envctrl_i2c_test_bb(); - if (stat & STATUS_LRB) - break; + /* Load address. */ + envctrl_writeb(addr + 1, &i2c->data); - error = count; - if (count == outlen) - break; + envctrl_i2c_test_bb(); - error = GET_DATA(i2c_regs + I2C_DATA, outbuf++, user); - if (error) - break; + envctrl_writeb(OBD_SEND_START, &i2c->csr); - count++; - } while (1); + /* Wait for PIN. */ + envtrl_i2c_test_pin(); - if (error < 0) { - writeb(CONTROL_PIN | CONTROL_ES0 | - CONTROL_STO | CONTROL_ACK, i2c_regs + I2C_CSR); - return error; + /* CSR 0 means acknowledged. */ + if (!(envctrl_readb(&i2c->csr) & STATUS_LRB)) { + return envctrl_readb(&i2c->data); + } else { + envctrl_writeb(OBD_SEND_STOP, &i2c->csr); + return 0; } - - writeb(CONTROL_ES0 | CONTROL_STA | CONTROL_ACK, i2c_regs + I2C_CSR); - udelay(1); - writeb((dev & 0xfe) | I2C_READ, i2c_regs + I2C_DATA); - - count = 0; - do { - udelay(1); - while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN) - udelay(1); - - if (stat & STATUS_LRB) - goto stop; - - error = 0; - if (inlen == 0) { - count--; - break; - } - - if (count == (inlen - 1)) - break; - - if (count++ > 0) { - error = PUT_DATA(i2c_regs + I2C_DATA, inbuf++, user); - if (error) - break; - } else - dummy = readb(i2c_regs + I2C_DATA); - } while (1); - - writeb(CONTROL_ES0, i2c_regs + I2C_CSR); - if (!error && (count++ > 0)) - error = PUT_DATA(i2c_regs + I2C_DATA, inbuf++, user); - else - dummy = readb(i2c_regs + I2C_DATA); - - udelay(1); - while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN) - udelay(1); - -stop: - writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STO | CONTROL_ACK, - i2c_regs + I2C_CSR); - if (!error && (count++ > 0)) - error = PUT_DATA(i2c_regs + I2C_DATA, inbuf++, user); - else - dummy = readb(i2c_regs + I2C_DATA); - - if (error) - return error; - return count - 1; } -#endif /* U450_SUPPORT */ -static struct i2c_device * -i2c_find_device(unsigned char addr) +/* Function Description: Send the adress for write mode. + * Return : None. + */ +static void envctrl_i2c_write_addr(unsigned char addr) { - struct i2c_device *dev; + envctrl_i2c_test_bb(); + envctrl_writeb(addr, &i2c->data); - for (dev = i2c_devices; dev; dev = dev->next) { - if (dev->addr == addr) - return dev; - } - return 0; + /* Generate Start condition. */ + envctrl_writeb(OBD_SEND_START, &i2c->csr); } -static void -i2c_free_devices(void) +/* Function Description: Read 1 byte of data from addr + * set by envctrl_i2c_read_addr() + * Return : Data from address set by envctrl_i2c_read_addr(). + */ +static unsigned char envctrl_i2c_read_data(void) { - struct i2c_device *dev; - - dev = i2c_devices; - while (dev) { - i2c_devices = dev->next; - kfree(dev); - dev = i2c_devices; - } + envtrl_i2c_test_pin(); + envctrl_writeb(CONTROL_ES0, &i2c->csr); /* Send neg ack. */ + return envctrl_readb(&i2c->data); } -static __init int i2c_scan_bus(void) +/* Function Description: Instruct the device which port to read data from. + * Return : None. + */ +static void envctrl_i2c_write_data(unsigned char port) { - struct i2c_device *dev, **last; - unsigned int addr; - int count = 0; - - last = &i2c_devices; - for (addr = 0; addr < 256; addr += 2) { - if (i2c_write(addr, 0, 0, 0) == 0) { -#ifdef DEBUG_BUS_SCAN - int i; - for (i = 0; i < NR_DEVMAP; i++) - if ((addr & devmap[i].mask) == devmap[i].addr) - break; - printk("envctrl: i2c device at %02x: %s\n", addr, - i < NR_DEVMAP ? devmap[i].name : "unknown"); -#endif - - dev = kmalloc(sizeof(struct i2c_device), GFP_KERNEL); - if (!dev) { - printk("i2c: can't alloc i2c_device\n"); - i2c_free_devices(); - return -ENOMEM; - } - memset(dev, 0, sizeof(struct i2c_device)); - - dev->addr = addr; - - *last = dev; - last = &dev->next; - - count++; - } - } - if (!count) { - printk("%s: no devices found\n", __FUNCTION__); - return -ENODEV; - } - return 0; + envtrl_i2c_test_pin(); + envctrl_writeb(port, &i2c->data); } - -static int -read_8591(unsigned char dev, unsigned char offset, unsigned char *value) +/* Function Description: Generate Stop condition after last byte is sent. + * Return : None. + */ +static void envctrl_i2c_stop(void) { - unsigned char data[2]; - - data[0] = 0x40 | offset; - if (i2c_write(dev, data, 1, 0) != 1) - return -1; - if (i2c_read(dev, data, 2, 0) != 2) - return -1; - *value = data[1]; - return 0; + envtrl_i2c_test_pin(); + envctrl_writeb(OBD_SEND_STOP, &i2c->csr); } -static int -write_8444(unsigned char dev, unsigned char offset, unsigned char value) +/* Function Description: Read adc device. + * Return : Data at address and port. + */ +static unsigned char envctrl_i2c_read_8591(unsigned char addr, unsigned char port) { - unsigned char data[2]; + /* Send address. */ + envctrl_i2c_write_addr(addr); - data[0] = offset; - data[1] = value; - if (i2c_write(dev, data, 2, 0) != 2) - return -1; - return 0; -} + /* Setup port to read. */ + envctrl_i2c_write_data(port); + envctrl_i2c_stop(); -#ifdef U450_SUPPORT -static int -read_8583(unsigned char dev, unsigned char offset, unsigned char *value) -{ - unsigned char data; + /* Read port. */ + envctrl_i2c_read_addr(addr); - data = offset; - if (i2c_write_read(dev, &data, 1, &data, 1, 0) != 1) - return -1; - *value = data; - return 0; -} - -static int -write_8583(unsigned char dev, unsigned char offset, unsigned char value) -{ - unsigned char data[2]; + /* Do a single byte read and send stop. */ + envctrl_i2c_read_data(); + envctrl_i2c_stop(); - data[0] = offset; - data[1] = value; - if (i2c_write(dev, data, 2, 0) != 2) - return -1; - return 0; + return envctrl_readb(&i2c->data); } -#endif /* U450_SUPPORT */ -struct thermistor * -find_thermistor(const char *name, struct thermistor *from) +/* Function Description: Read gpio device. + * Return : Data at address. + */ +static unsigned char envctrl_i2c_read_8574(unsigned char addr) { - int n; + unsigned char rd; - if (!from) - from = envctrl.thermistors; - else - from = from->next; + envctrl_i2c_read_addr(addr); - n = strlen(name); - while (from && strncmp(from->name, name, n)) - from = from->next; + /* Do a single byte read and send stop. */ + rd = envctrl_i2c_read_data(); + envctrl_i2c_stop(); - return from; + return rd; } -void -check_temperatures(struct environment *env) +/* Function Description: Decode data read from an adc device using firmware + * table. + * Return: Number of read bytes. Data is stored in bufdata in ascii format. + */ +static int envctrl_i2c_data_translate(unsigned char data, int translate_type, + int scale, char *tbl, char *bufdata) { - struct thermistor *t; - - for (t = env->thermistors; t; t = t->next) { -#ifdef DEBUG - printk("Thermistor `%s' [%02x:%d]: " - "%d C (%d C, %d C)\n", - t->name, t->regs.addr, t->regs.port, - t->temperature(t), t->regs.warning, t->regs.shutdown); -#endif + int len = 0; - /* - * Implement slow-down or shutdown here... - */ - } -} + switch (translate_type) { + case ENVCTRL_TRANSLATE_NO: + /* No decode necessary. */ + len = 1; + bufdata[0] = data; + break; -void -check_fan_speeds(struct environment *env) -{ - unsigned char speed, max; - struct thermistor *t; - struct fan *f; - - for (f = env->fans; f; f = f->next) { -#ifdef DEBUG - printk("Fan `%s' [%02x:%d]:", f->name, - f->regs.addr, f->regs.port); -#endif - max = 0; - for (t = f->monitor; t; t = t->chain) { - speed = t->fan_speed(t); - if (speed > max) - max = speed; -#ifdef DEBUG - printk(" %s:%02x", t->name, speed); -#endif - } + case ENVCTRL_TRANSLATE_FULL: + /* Decode this way: data = table[data]. */ + len = 1; + bufdata[0] = tbl[data]; + break; - f->set_speed(f, max); -#ifdef DEBUG - printk(" -> %02x\n", f->value); -#endif - } -} + case ENVCTRL_TRANSLATE_SCALE: + /* Decode this way: data = table[data]/scale */ + sprintf(bufdata,"%d ", (tbl[data] * 10) / (scale)); + len = strlen(bufdata); + bufdata[len - 1] = bufdata[len - 2]; + bufdata[len - 2] = '.'; + break; -void -envctrl_fans_blast(struct environment *env) -{ - struct fan *f; + default: + break; + }; - for (f = env->fans; f; f = f->next) - f->set_speed(f, MAX_FAN_SPEED); + return len; } -int -kenvd(void *data) +/* Function Description: Read cpu-related data such as cpu temperature, voltage. + * Return: Number of read bytes. Data is stored in bufdata in ascii format. + */ +static int envctrl_read_cpu_info(struct i2c_child_t *pchild, + char mon_type, unsigned char *bufdata) { - struct environment *env = data; - - MOD_INC_USE_COUNT; - lock_kernel(); - - env->kenvd_pid = current->pid; - - exit_files(current); - exit_mm(current); - - spin_lock_irq(¤t->sigmask_lock); - siginitsetinv(¤t->blocked, sigmask(SIGKILL)); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - - current->session = 1; - current->pgrp = 1; - strcpy(current->comm, "kenvd"); - - if (env->enable) - env->enable(env); - - while (!env->terminate) { - - check_temperatures(env); - check_fan_speeds(env); - if (env->keep_alive) - env->keep_alive(env); - - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(env->interval * HZ); + unsigned char data; + int i; + char *tbl, j = -1; - if (signal_pending(current)) { - spin_lock_irq(¤t->sigmask_lock); - flush_signals(current); - spin_unlock_irq(¤t->sigmask_lock); - break; + /* Find the right monitor type and channel. */ + for (i = 0; i < PCF8584_MAX_CHANNELS; i++) { + if (pchild->mon_type[i] == mon_type) { + if (++j == read_cpu) { + break; + } } } - if (env->disable) - env->disable(env); + if (j != read_cpu) + return 0; - env->kenvd_pid = 0; - wake_up(&envctrl.kenvd_wait); + /* Read data from address and port. */ + data = envctrl_i2c_read_8591((unsigned char)pchild->addr, + (unsigned char)pchild->chnl_array[i].chnl_no); - MOD_DEC_USE_COUNT; - return 0; -} + /* Find decoding table. */ + tbl = pchild->tables + pchild->tblprop_array[i].offset; -void -envctrl_stop(void) -{ - DECLARE_WAITQUEUE(wait, current); - struct thermistor *t; - struct fan *f; - pid_t pid; - - if (envctrl.kenvd_pid) { - pid = envctrl.kenvd_pid; - - current->state = TASK_INTERRUPTIBLE; - add_wait_queue(&envctrl.kenvd_wait, &wait); - - envctrl.terminate = 1; - kill_proc(pid, SIGKILL, 1); - - schedule(); - - remove_wait_queue(&envctrl.kenvd_wait, &wait); - current->state = TASK_RUNNING; - } - - t = envctrl.thermistors; - while (t) { - envctrl.thermistors = t->next; - kfree(t); - t = envctrl.thermistors; - } - - f = envctrl.fans; - while (f) { - envctrl.fans = f->next; - kfree(f); - f = envctrl.fans; - } - - if (envctrl.cpu_temp_table) - kfree(envctrl.cpu_temp_table); - - if (envctrl.cpu_fan_speeds) - kfree(envctrl.cpu_fan_speeds); - - if (envctrl.ps_temp_table) - kfree(envctrl.ps_temp_table); - - if (envctrl.ps_fan_speeds) - kfree(envctrl.ps_fan_speeds); -} - - -static unsigned char -axi_get_temperature(struct thermistor *t) -{ - unsigned char value; - - if (read_8591(t->regs.addr, t->regs.port, &value) < 0) - return MAX_TEMPERATURE; - if (t->regs.port == AXI_THERM_PORT_CPU) - return axi_cpu_temp_table[value]; - else - return axi_mod_temp_table[value]; + return envctrl_i2c_data_translate(data, pchild->tblprop_array[i].type, + pchild->tblprop_array[i].scale, + tbl, bufdata); } -static unsigned char -axi_get_fan_speed(struct thermistor *t) +/* Function Description: Read noncpu-related data such as motherboard + * temperature. + * Return: Number of read bytes. Data is stored in bufdata in ascii format. + */ +static int envctrl_read_noncpu_info(struct i2c_child_t *pchild, + char mon_type, unsigned char *bufdata) { - unsigned char temp; - - temp = t->temperature(t); - if (temp >= MAX_TEMPERATURE) - return MAX_FAN_SPEED; - - return axi_fan_speeds[temp]; -} + unsigned char data; + int i; + char *tbl = NULL; -static int -axi_set_fan_speed(struct fan *f, unsigned char value) -{ - if (value != f->value) { - if (write_8444(f->regs.addr, f->regs.port, value)) - return -1; - f->value = value; + for (i = 0; i < PCF8584_MAX_CHANNELS; i++) { + if (pchild->mon_type[i] == mon_type) + break; } - return 0; -} -static void -axi_toggle_i2c_int(struct environment *env) -{ - unsigned char data; + if (i >= PCF8584_MAX_CHANNELS) + return 0; - if (i2c_read(AXI_PIO_ADDR, &data, 1, 0) != 1) - return; + /* Read data from address and port. */ + data = envctrl_i2c_read_8591((unsigned char)pchild->addr, + (unsigned char)pchild->chnl_array[i].chnl_no); - data &= ~(0x08); - if (i2c_write(AXI_PIO_ADDR, &data, 1, 0) != 1) - return; - mdelay(1); + /* Find decoding table. */ + tbl = pchild->tables + pchild->tblprop_array[i].offset; - data |= 0x08; - if (i2c_write(AXI_PIO_ADDR, &data, 1, 0) != 1) - return; - mdelay(1); + return envctrl_i2c_data_translate(data, pchild->tblprop_array[i].type, + pchild->tblprop_array[i].scale, + tbl, bufdata); } - -static int -rasctrl_setup(int node) +/* Function Description: Read fan status. + * Return : Always 1 byte. Status stored in bufdata. + */ +static int envctrl_i2c_fan_status(struct i2c_child_t *pchild, + unsigned char data, + char *bufdata) { - struct thermistor *t, **tlast; - struct fan *f, **flast; - char tmp[32]; - int monitor; - int shutdown; - int warning; - int i; + unsigned char tmp, ret = 0; + int i, j = 0; - prom_getstring(prom_root_node, "name", tmp, sizeof(tmp)); - if (strcmp(tmp, "SUNW,UltraSPARC-IIi-Engine")) { - printk("SUNW,rasctrl will work only on Ultra AXi\n"); - return -ENODEV; - } + tmp = data & pchild->fan_mask; - monitor = prom_getintdefault(node, "env-monitor", 0); - if (monitor == 0) - return -ENODEV; + if (tmp == pchild->fan_mask) { + /* All bits are on. All fans are functioning. */ + ret = ENVCTRL_ALL_FANS_GOOD; + } else if (tmp == 0) { + /* No bits are on. No fans are functioning. */ + ret = ENVCTRL_ALL_FANS_BAD; + } else { + /* Go through all channels, mark 'on' the matched bits. + * Notice that fan_mask may have discontiguous bits but + * return mask are always contiguous. For example if we + * monitor 4 fans at channels 0,1,2,4, the return mask + * should be 00010000 if only fan at channel 4 is working. + */ + for (i = 0; i < PCF8584_MAX_CHANNELS;i++) { + if (pchild->fan_mask & chnls_mask[i]) { + if (!(chnls_mask[i] & tmp)) + ret |= chnls_mask[j]; - envctrl.interval = prom_getintdefault(node, "env-mon-interval", 60); - warning = prom_getintdefault(node, "warning-temp", 55); - shutdown = prom_getintdefault(node, "shutdown-temp", 58); - - tlast = &envctrl.thermistors; - for (i = 0; i < 4; i++) { - t = kmalloc(sizeof(struct thermistor), GFP_KERNEL); - if (!t) - goto out; - memset(t, 0, sizeof(struct thermistor)); - - t->regs.addr = AXI_THERM_ADDR; - t->regs.port = i; - t->regs.warning = warning; - t->regs.shutdown = shutdown; - - switch (i) { - case AXI_THERM_PORT_CPU: - sprintf(t->name, "%.7s", "CPU"); - break; - case AXI_THERM_PORT_MOD: - sprintf(t->name, "%.7s", "MOD"); - break; - case AXI_THERM_PORT_PCI: - sprintf(t->name, "%.7s", "PCI"); - break; - case AXI_THERM_PORT_DISK: - sprintf(t->name, "%.7s", "DISK"); - break; + j++; + } } + } - t->temperature = axi_get_temperature; - t->fan_speed = axi_get_fan_speed; + bufdata[0] = ret; + return 1; +} - if (!i2c_find_device(t->regs.addr)) { - printk("envctrl: `%s': i2c device %02x not found\n", - t->name, t->regs.addr); - kfree(t); - continue; +/* Function Description: Read voltage and power supply status. + * Return : Always 1 byte. Status stored in bufdata. + */ +static unsigned char envctrl_i2c_voltage_status(struct i2c_child_t *pchild, + unsigned char data, + char *bufdata) +{ + unsigned char tmp, ret = 0; + int i, j = 0; + + tmp = data & pchild->voltage_mask; + + /* Two channels are used to monitor voltage and power supply. */ + if (tmp == pchild->voltage_mask) { + /* All bits are on. Voltage and power supply are okay. */ + ret = ENVCTRL_VOLTAGE_POWERSUPPLY_GOOD; + } else if (tmp == 0) { + /* All bits are off. Voltage and power supply are bad */ + ret = ENVCTRL_VOLTAGE_POWERSUPPLY_BAD; + } else { + /* Either voltage or power supply has problem. */ + for (i = 0; i < PCF8584_MAX_CHANNELS; i++) { + if (pchild->voltage_mask & chnls_mask[i]) { + j++; + + /* Break out when there is a mismatch. */ + if (!(chnls_mask[i] & tmp)) + break; + } } - *tlast = t; - tlast = &t->next; + /* Make a wish that hardware will always use the + * first channel for voltage and the second for + * power supply. + */ + if (j == 1) + ret = ENVCTRL_VOLTAGE_BAD; + else + ret = ENVCTRL_POWERSUPPLY_BAD; } - flast = &envctrl.fans; - for (i = 0; i < 2; i++) { - f = kmalloc(sizeof(struct fan), GFP_KERNEL); - if (!f) - goto out; - memset(f, 0, sizeof(struct fan)); - - f->regs.addr = AXI_FAN_ADDR; - f->regs.port = i; - - switch (i) { - case AXI_FAN_PORT_FRONT: - sprintf(f->name, "%.7s", "FRONT"); - t = NULL; - while ((t = find_thermistor("CPU", t))) { - t->chain = f->monitor; - f->monitor = t; - } - break; - case AXI_FAN_PORT_BACK: - sprintf(f->name, "%.7s", "BACK"); - t = NULL; - while ((t = find_thermistor("PCI", t))) { - t->chain = f->monitor; - f->monitor = t; - } - break; - } + bufdata[0] = ret; + return 1; +} - if (!f->monitor) { - kfree(f); - continue; - } +/* Function Description: Read a byte from /dev/envctrl. Mapped to user read(). + * Return: Number of read bytes. 0 for error. + */ +static ssize_t +envctrl_read(struct file *file, char *buf, size_t count, loff_t *ppos) +{ + struct i2c_child_t *pchild; + unsigned char data[10]; + int ret = 0; + + /* Get the type of read as decided in ioctl() call. + * Find the appropriate i2c child. + * Get the data and put back to the user buffer. + */ + + switch ((int)(long)file->private_data) { + case ENVCTRL_RD_WARNING_TEMPERATURE: + if (warning_temperature == 0) + return 0; + + data[0] = (unsigned char)(warning_temperature); + ret = 1; + copy_to_user((unsigned char *)buf, data, ret); + break; + + case ENVCTRL_RD_SHUTDOWN_TEMPERATURE: + if (shutdown_temperature == 0) + return 0; + + data[0] = (unsigned char)(shutdown_temperature); + ret = 1; + copy_to_user((unsigned char *)buf, data, ret); + break; + + case ENVCTRL_RD_MTHRBD_TEMPERATURE: + if (!(pchild = envctrl_get_i2c_child(ENVCTRL_MTHRBDTEMP_MON))) + return 0; + ret = envctrl_read_noncpu_info(pchild, ENVCTRL_MTHRBDTEMP_MON, data); + copy_to_user((unsigned char *)buf, data, ret); + break; + + case ENVCTRL_RD_CPU_TEMPERATURE: + if (!(pchild = envctrl_get_i2c_child(ENVCTRL_CPUTEMP_MON))) + return 0; + ret = envctrl_read_cpu_info(pchild, ENVCTRL_CPUTEMP_MON, data); + + /* Reset cpu to the default cpu0. */ + copy_to_user((unsigned char *)buf, data, ret); + break; + + case ENVCTRL_RD_CPU_VOLTAGE: + if (!(pchild = envctrl_get_i2c_child(ENVCTRL_CPUVOLTAGE_MON))) + return 0; + ret = envctrl_read_cpu_info(pchild, ENVCTRL_CPUVOLTAGE_MON, data); + + /* Reset cpu to the default cpu0. */ + copy_to_user((unsigned char *)buf, data, ret); + break; + + case ENVCTRL_RD_SCSI_TEMPERATURE: + if (!(pchild = envctrl_get_i2c_child(ENVCTRL_SCSITEMP_MON))) + return 0; + ret = envctrl_read_noncpu_info(pchild, ENVCTRL_SCSITEMP_MON, data); + copy_to_user((unsigned char *)buf, data, ret); + break; + + case ENVCTRL_RD_ETHERNET_TEMPERATURE: + if (!(pchild = envctrl_get_i2c_child(ENVCTRL_ETHERTEMP_MON))) + return 0; + ret = envctrl_read_noncpu_info(pchild, ENVCTRL_ETHERTEMP_MON, data); + copy_to_user((unsigned char *)buf, data, ret); + break; + + case ENVCTRL_RD_FAN_STATUS: + if (!(pchild = envctrl_get_i2c_child(ENVCTRL_FANSTAT_MON))) + return 0; + data[0] = envctrl_i2c_read_8574(pchild->addr); + ret = envctrl_i2c_fan_status(pchild,data[0], data); + copy_to_user((unsigned char *)buf, data, ret); + break; + + case ENVCTRL_RD_VOLTAGE_STATUS: + if (!(pchild = envctrl_get_i2c_child(ENVCTRL_VOLTAGESTAT_MON))) + return 0; + data[0] = envctrl_i2c_read_8574(pchild->addr); + ret = envctrl_i2c_voltage_status(pchild, data[0], data); + copy_to_user((unsigned char *)buf, data, ret); + break; + + default: + break; + + }; + + return ret; +} + +/* Function Description: Command what to read. Mapped to user ioctl(). + * Return: Gives 0 for implemented commands, -EINVAL otherwise. + */ +static int +envctrl_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + char *infobuf; - if (!i2c_find_device(f->regs.addr)) { - printk("envctrl: `%s': i2c device %02x not found\n", - f->name, f->regs.addr); - kfree(f); - continue; + switch (cmd) { + case ENVCTRL_RD_WARNING_TEMPERATURE: + case ENVCTRL_RD_SHUTDOWN_TEMPERATURE: + case ENVCTRL_RD_MTHRBD_TEMPERATURE: + case ENVCTRL_RD_FAN_STATUS: + case ENVCTRL_RD_VOLTAGE_STATUS: + case ENVCTRL_RD_ETHERNET_TEMPERATURE: + case ENVCTRL_RD_SCSI_TEMPERATURE: + file->private_data = (void *)(long)cmd; + break; + + case ENVCTRL_RD_CPU_TEMPERATURE: + case ENVCTRL_RD_CPU_VOLTAGE: + /* Check to see if application passes in any cpu number, + * the default is cpu0. + */ + infobuf = (char *) arg; + if (infobuf == NULL) { + read_cpu = 0; + }else { + get_user(read_cpu, infobuf); } - *flast = f; - flast = &f->next; + /* Save the command for use when reading. */ + file->private_data = (void *)(long)cmd; + break; - f->check_failure = NULL; - f->set_speed = axi_set_fan_speed; - } - - envctrl.enable = axi_toggle_i2c_int; - envctrl.disable = envctrl_fans_blast; + default: + return -EINVAL; + }; -#ifdef DEBUG - printk("Warn: %d C, Shutdown %d C, Interval %d s, Monitor %d\n", - warning, shutdown, envctrl.interval, monitor); -#endif return 0; - -out: - return -ENODEV; -} - - -#ifdef U450_SUPPORT - -static unsigned char -envctrl_get_temperature(struct thermistor *t) -{ - unsigned char value; - - if (read_8591(t->regs.addr, t->regs.port, &value) < 0) - return MAX_TEMPERATURE; - if (!strncmp(t->name, "CPU", 3)) - return envctrl.cpu_temp_table[value]; - else - return envctrl.ps_temp_table[value]; } -static unsigned char -envctrl_get_fan_speed(struct thermistor *t) +/* Function Description: open device. Mapped to user open(). + * Return: Always 0. + */ +static int +envctrl_open(struct inode *inode, struct file *file) { - unsigned char temp; - - temp = t->temperature(t); - if (temp >= MAX_TEMPERATURE) - return MAX_FAN_SPEED; - - if (!strncmp(t->name, "CPU", 3)) - return envctrl.cpu_fan_speeds[temp]; - else - return envctrl.ps_fan_speeds[temp]; + file->private_data = 0; + MOD_INC_USE_COUNT; + return 0; } +/* Function Description: Open device. Mapped to user close(). + * Return: Always 0. + */ static int -envctrl_set_fan_speed(struct fan *f, unsigned char value) +envctrl_release(struct inode *inode, struct file *file) { - if (value != f->value) { - if (write_8444(f->regs.addr, f->regs.port, value)) - return -1; - f->value = value; - } - + MOD_DEC_USE_COUNT; return 0; } -static unsigned char u450_default_thermisters[] = -{ - /* CPU0 */ - 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x55, 0x30, 0x00, - /* CPU1 */ - 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x55, 0x31, 0x00, - /* CPU2 */ - 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x55, 0x32, 0x00, - /* CPU3 */ - 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x55, 0x33, 0x00, - /* PS0 */ - 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x50, 0x53, 0x30, 0x00, - /* PS1 */ - 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x50, 0x53, 0x31, 0x00, - /* PS2 */ - 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x50, 0x53, 0x32, 0x00, - /* AMB */ - 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x28, - 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x41, 0x4d, 0x42, 0x00 -}; - -static unsigned char u450_default_cpu_temp_factors[] = -{ - 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x94, 0x92, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, - 0x8a, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, - 0x81, 0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, - 0x79, 0x79, 0x78, 0x78, 0x77, 0x76, 0x75, 0x74, - 0x73, 0x72, 0x71, 0x70, 0x70, 0x6f, 0x6f, 0x6e, - 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6b, 0x6a, 0x6a, - 0x69, 0x69, 0x68, 0x67, 0x66, 0x65, 0x65, 0x64, - 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61, 0x61, - 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, - 0x5c, 0x5c, 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, - 0x59, 0x59, 0x58, 0x58, 0x57, 0x57, 0x56, 0x56, - 0x55, 0x55, 0x54, 0x54, 0x53, 0x53, 0x52, 0x52, - 0x52, 0x51, 0x51, 0x50, 0x50, 0x50, 0x50, 0x4f, - 0x4f, 0x4f, 0x4e, 0x4e, 0x4e, 0x4d, 0x4d, 0x4d, - 0x4c, 0x4c, 0x4c, 0x4b, 0x4b, 0x4b, 0x4a, 0x4a, - 0x4a, 0x49, 0x49, 0x49, 0x48, 0x48, 0x48, 0x47, - 0x47, 0x47, 0x46, 0x46, 0x46, 0x46, 0x45, 0x45, - 0x45, 0x44, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, - 0x43, 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, - 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, - 0x3e, 0x3d, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c, - 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, - 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37, 0x37, - 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35, - 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x33, 0x32, - 0x32, 0x32, 0x31, 0x31, 0x31, 0x30, 0x30, 0x30, - 0x2f, 0x2f, 0x2f, 0x2e, 0x2e, 0x2e, 0x2d, 0x2d, - 0x2d, 0x2c, 0x2c, 0x2c, 0x2b, 0x2b, 0x2b, 0x2a, - 0x2a, 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28 -}; - -static unsigned char u450_default_cpu_fan_speeds[] = -{ - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x2a, 0x2b, 0x2d, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f -}; - -static unsigned char u450_default_ps_temp_factors[] = -{ - 0x9a, 0x96, 0x82, 0x7d, 0x78, 0x73, 0x6e, 0x6b, - 0x69, 0x67, 0x64, 0x5f, 0x5a, 0x57, 0x55, 0x53, - 0x51, 0x50, 0x4e, 0x4d, 0x4c, 0x4b, 0x49, 0x47, - 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3f, - 0x3e, 0x3d, 0x3c, 0x3c, 0x3b, 0x3a, 0x39, 0x39, - 0x38, 0x37, 0x37, 0x36, 0x35, 0x35, 0x34, 0x33, - 0x32, 0x32, 0x32, 0x31, 0x31, 0x30, 0x30, 0x2f, - 0x2f, 0x2e, 0x2e, 0x2d, 0x2d, 0x2c, 0x2c, 0x2b, - 0x2a, 0x2a, 0x29, 0x29, 0x28, 0x28, 0x27, 0x27, - 0x26, 0x26, 0x25, 0x25, 0x25, 0x25, 0x24, 0x24, - 0x23, 0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, - 0x21, 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, - 0x1e, 0x1d, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c, 0x1c, - 0x1b, 0x1b, 0x1b, 0x1a, 0x1a, 0x1a, 0x19, 0x19, - 0x19, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, - 0x17, 0x16, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15, - 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, - 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, - 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; +static struct file_operations envctrl_fops = { + owner: THIS_MODULE, + read: envctrl_read, + ioctl: envctrl_ioctl, + open: envctrl_open, + release: envctrl_release, +}; -static unsigned char u450_default_ps_fan_speeds[] = -{ - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x2b, 0x2d, 0x2e, 0x2f, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f +static struct miscdevice envctrl_dev = { + ENVCTRL_MINOR, + "envctrl", + &envctrl_fops }; -static void -u450_toggle_i2c_int(struct environment *env) +/* Function Description: Set monitor type based on firmware description. + * Return: None. + */ +static void envctrl_set_mon(struct i2c_child_t *pchild, + char *chnl_desc, + int chnl_no) +{ + /* Firmware only has temperature type. It does not distinguish + * different kinds of temperatures. We use channel description + * to disinguish them. + */ + if (!(strcmp(chnl_desc,"temp,cpu")) || + !(strcmp(chnl_desc,"temp,cpu0")) || + !(strcmp(chnl_desc,"temp,cpu1")) || + !(strcmp(chnl_desc,"temp,cpu2")) || + !(strcmp(chnl_desc,"temp,cpu3"))) + pchild->mon_type[chnl_no] = ENVCTRL_CPUTEMP_MON; + + if (!(strcmp(chnl_desc,"vddcore,cpu0")) || + !(strcmp(chnl_desc,"vddcore,cpu1")) || + !(strcmp(chnl_desc,"vddcore,cpu2")) || + !(strcmp(chnl_desc,"vddcore,cpu3"))) + pchild->mon_type[chnl_no] = ENVCTRL_CPUVOLTAGE_MON; + + if (!(strcmp(chnl_desc,"temp,motherboard"))) + pchild->mon_type[chnl_no] = ENVCTRL_MTHRBDTEMP_MON; + + if (!(strcmp(chnl_desc,"temp,scsi"))) + pchild->mon_type[chnl_no] = ENVCTRL_SCSITEMP_MON; + + if (!(strcmp(chnl_desc,"temp,ethernet"))) + pchild->mon_type[chnl_no] = ENVCTRL_ETHERTEMP_MON; + + if (!(strcmp(chnl_desc,"temp,ethernet"))) + pchild->mon_type[chnl_no] = ENVCTRL_ETHERTEMP_MON; +} + +/* Function Description: Initialize monitor channel with channel desc, + * decoding tables, monitor type, optional properties. + * Return: None. + */ +static void envctrl_init_adc(struct i2c_child_t *pchild, int node) +{ + char chnls_desc[CHANNEL_DESC_SZ]; + int i, len, j = 0; + char *ptr; + + /* Firmware describe channels into a stream separated by a '\0'. + * Replace all '\0' with a space. + */ + len = prom_getproperty(node, "channels-description", chnls_desc, + CHANNEL_DESC_SZ); + for (i = 0; i < len; i++) { + if (chnls_desc[i] == '\0') + chnls_desc[i] = ' '; + } + + ptr = strtok(chnls_desc, " "); + while (ptr != NULL) { + envctrl_set_mon(pchild, ptr, j); + ptr = strtok(NULL, " "); + j++; + } + + /* Get optional properties. */ + len = prom_getproperty(node, "warning-temp", (char *)&warning_temperature, + sizeof(warning_temperature)); + len = prom_getproperty(node, "shutdown-temp", (char *)&shutdown_temperature, + sizeof(shutdown_temperature)); +} + +/* Function Description: Initialize child device monitoring fan status. + * Return: None. + */ +static void envctrl_init_fanstat(struct i2c_child_t *pchild) { - unsigned char tmp[80]; - unsigned char data; - int i, n; + int i; - write_8583(U450_TIMER_ADDR, 0, 0x84); - write_8583(U450_TIMER_ADDR, 8, 0x0a); - write_8583(U450_TIMER_ADDR, 7, 0x00); - write_8583(U450_TIMER_ADDR, 0, 0x04); + /* Go through all channels and set up the mask. */ + for (i = 0; i < pchild->total_chnls; i++) + pchild->fan_mask |= chnls_mask[(pchild->chnl_array[i]).chnl_no]; - n = sprintf(tmp, "envctrl: PCF8583:"); - for (i = 0; i < 16; i++) { - if (read_8583(U450_TIMER_ADDR, i, &data) < 0) { - printk("envctrl: error reading PCF8583\n"); - break; - } - n += sprintf(tmp+n, " %02x", data); - } - printk("%s\n", tmp); - -#if 1 - data = 0x70; - if (i2c_write(U450_PIO_ADDR, &data, 1, 0) != 1) - return; - mdelay(1); - - data = 0x78; - if (i2c_write(U450_PIO_ADDR, &data, 1, 0) != 1) - return; - mdelay(1); -#endif + /* We only need to know if this child has fan status monitored. + * We dont care which channels since we have the mask already. + */ + pchild->mon_type[0] = ENVCTRL_FANSTAT_MON; } -static void -u450_set_egg_timer(struct environment *env) +/* Initialize child device monitoring voltage status. */ +static void envctrl_init_voltage_status(struct i2c_child_t *pchild) { - unsigned char value; - -#if 0 - write_8583(U450_TIMER_ADDR, 0x00, 0x84); - read_8583(U450_TIMER_ADDR, 0x07, &value); - write_8583(U450_TIMER_ADDR, 0x07, 0x00); - write_8583(U450_TIMER_ADDR, 0x00, 0x04); -#else - read_8583(U450_TIMER_ADDR, 0x07, &value); - printk("envctrl: TIMER [%02x:07]: %02x\n", U450_TIMER_ADDR, value); - read_8583(U450_TIMER_ADDR, 0x00, &value); - printk("envctrl: TIMER [%02x:00]: %02x\n", U450_TIMER_ADDR, value); -#endif -} + int i; -static int -envctrl_setup(int node) -{ - struct thermistor *t, **tlast; - struct fan *f, **flast; - unsigned char *tmp = NULL, *p; - int len, n, err; - int defaults = 0; - - len = prom_getproplen(node, "thermisters"); - if (len <= 0) { - printk("envctrl: no property `thermisters', using defaults\n"); - defaults++; - len = sizeof(u450_default_thermisters); - } + /* Go through all channels and set up the mask. */ + for (i = 0; i < pchild->total_chnls; i++) + pchild->voltage_mask |= chnls_mask[(pchild->chnl_array[i]).chnl_no]; - tmp = (unsigned char *)kmalloc(len, GFP_KERNEL); - if (!tmp) { - printk("envctrl: can't allocate property buffer\n"); - return -ENODEV; - } + /* We only need to know if this child has voltage status monitored. + * We dont care which channels since we have the mask already. + */ + pchild->mon_type[0] = ENVCTRL_VOLTAGESTAT_MON; +} - if (defaults) { - memcpy(tmp, u450_default_thermisters, len); - } else { - err = prom_getproperty(node, "thermisters", tmp, len); - if (err < 0) { - printk("envctrl: error reading property `thermisters'\n"); - kfree(tmp); - return -ENODEV; +/* Function Description: Initialize i2c child device. + * Return: None. + */ +static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, + struct i2c_child_t *pchild) +{ + int node, len, i, tbls_size = 0; + + node = edev_child->prom_node; + + /* Get device address. */ + len = prom_getproperty(node, "reg", + (char *) &(pchild->addr), + sizeof(pchild->addr)); + + /* Get tables property. Read firmware temperature tables. */ + len = prom_getproperty(node, "translation", + (char *) pchild->tblprop_array, + (PCF8584_MAX_CHANNELS * + sizeof(struct pcf8584_tblprop))); + if (len > 0) { + pchild->total_tbls = len / sizeof(struct pcf8584_tblprop); + for (i = 0; i < pchild->total_tbls; i++) { + if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) { + tbls_size = pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset; + } } - } - - p = tmp; - err = -ENOMEM; - tlast = &envctrl.thermistors; - while (len > sizeof(struct therm_regs)) { - t = kmalloc(sizeof(struct thermistor), GFP_KERNEL); - if (!t) { - printk("envctrl: can't allocate thermistor struct\n"); - goto out; - } - memset(t, 0, sizeof(struct thermistor)); - - memcpy(&t->regs, p, sizeof(struct therm_regs)); - p += sizeof(struct therm_regs); - len -= sizeof(struct therm_regs); - - n = strlen(p) + 1; - strncpy(t->name, p, 7); - p += n; - len -= n; - - if (!i2c_find_device(t->regs.addr)) { - printk("envctrl: `%s': i2c device %02x not found\n", - t->name, t->regs.addr); - kfree(t); - continue; + pchild->tables = kmalloc(tbls_size, GFP_KERNEL); + len = prom_getproperty(node, "tables", + (char *) pchild->tables, tbls_size); + if (len <= 0) { + printk("envctrl: Failed to get table.\n"); + return; } + } - t->temperature = envctrl_get_temperature; - t->fan_speed = envctrl_get_fan_speed; + /* Get the monitor channels. */ + len = prom_getproperty(node, "channels-in-use", + (char *) pchild->chnl_array, + (PCF8584_MAX_CHANNELS * + sizeof(struct pcf8584_channel))); + pchild->total_chnls = len / sizeof(struct pcf8584_channel); - *tlast = t; - tlast = &t->next; - } + for (i = 0; i < pchild->total_chnls; i++) { + switch (pchild->chnl_array[i].type) { + case PCF8584_TEMP_TYPE: + envctrl_init_adc(pchild, node); + break; - flast = &envctrl.fans; - for (n = 0; n < 2; n++) { - f = kmalloc(sizeof(struct fan), GFP_KERNEL); - if (!f) - goto out; - memset(f, 0, sizeof(struct fan)); - - f->regs.addr = U450_FAN_ADDR; - f->regs.port = n; - - switch (n) { - case U450_FAN_PORT_CPU: - sprintf(f->name, "%.7s", "CPU"); - t = NULL; - while ((t = find_thermistor("CPU", t))) { - t->chain = f->monitor; - f->monitor = t; - } + case PCF8584_FANSTAT_TYPE: + envctrl_init_fanstat(pchild); + i = pchild->total_chnls; break; - case U450_FAN_PORT_PS: - sprintf(f->name, "%.7s", "PS"); - t = NULL; - while ((t = find_thermistor("PS", t))) { - t->chain = f->monitor; - f->monitor = t; + + case PCF8584_VOLTAGE_TYPE: + if (pchild->i2ctype == I2C_ADC) { + envctrl_init_adc(pchild,node); + } else { + envctrl_init_voltage_status(pchild); } + i = pchild->total_chnls; break; - } - - if (!f->monitor) { - kfree(f); - continue; - } - - if (!i2c_find_device(f->regs.addr)) { - printk("envctrl: `%s': i2c device %02x not found\n", - f->name, f->regs.addr); - kfree(f); - continue; - } - - *flast = f; - flast = &f->next; - f->check_failure = NULL; - f->set_speed = envctrl_set_fan_speed; - } - - envctrl.cpu_temp_table = kmalloc(256, GFP_KERNEL); - if (!envctrl.cpu_temp_table) { - printk("envctrl: can't allocate temperature table\n"); - goto out; - } - if (defaults) { - memcpy(envctrl.cpu_temp_table, - u450_default_cpu_temp_factors, 256); - } else { - err = prom_getproperty(node, "cpu-temp-factors", - envctrl.cpu_temp_table, 256); - if (err < 0) { - printk("envctrl: can't read `cpu-temp-factors'\n"); - goto out; - } - } - - envctrl.cpu_fan_speeds = kmalloc(112, GFP_KERNEL); - if (!envctrl.cpu_fan_speeds) { - printk("envctrl: can't allocate fan speed table\n"); - goto out; - } - if (defaults) { - memcpy(envctrl.cpu_fan_speeds, - u450_default_cpu_fan_speeds, 112); - } else { - err = prom_getproperty(node, "cpu-fan-speeds", - envctrl.cpu_fan_speeds, 112); - if (err < 0) { - printk("envctrl: can't read `cpu-fan-speeds'\n"); - goto out; - } - } - - envctrl.ps_temp_table = kmalloc(256, GFP_KERNEL); - if (!envctrl.ps_temp_table) { - printk("envctrl: can't allocate temperature table\n"); - goto out; - } - if (defaults) { - memcpy(envctrl.ps_temp_table, - u450_default_ps_temp_factors, 256); - } else { - err = prom_getproperty(node, "ps-temp-factors", - envctrl.ps_temp_table, 256); - if (err < 0) { - printk("envctrl: can't read `ps-temp-factors'\n"); - goto out; - } - } - - envctrl.ps_fan_speeds = kmalloc(112, GFP_KERNEL); - if (!envctrl.ps_fan_speeds) { - printk("envctrl: can't allocate fan speed table\n"); - goto out; - } - if (defaults) { - memcpy(envctrl.ps_fan_speeds, - u450_default_ps_fan_speeds, 112); - } else { - err = prom_getproperty(node, "ps-fan-speeds", - envctrl.ps_fan_speeds, 112); - if (err < 0) { - printk("envctrl: can't read `ps-fan-speeds'\n"); - goto out; - } + default: + break; + }; } - - envctrl.enable = u450_toggle_i2c_int; - envctrl.keep_alive = u450_set_egg_timer; - envctrl.disable = envctrl_fans_blast; - envctrl.interval = 60; - - kfree(tmp); - return 0; - -out: - if (tmp) - kfree(tmp); - return err; -} -#endif /* U450_SUPPORT */ - - - -static loff_t -envctrl_llseek(struct file *file, loff_t offset, int type) -{ - return -ESPIPE; -} - -static ssize_t -envctrl_read(struct file *file, char *buf, size_t count, loff_t *ppos) -{ - unsigned long addr = (unsigned long)file->private_data; - - return i2c_read(addr, buf, count, 1); -} - -static ssize_t -envctrl_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -{ - unsigned long addr = (unsigned long)file->private_data; - - return i2c_write(addr, buf, count, 1); } -static int -envctrl_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +/* Function Description: Search the child device list for a device. + * Return : The i2c child if found. NULL otherwise. + */ +static struct i2c_child_t *envctrl_get_i2c_child(unsigned char mon_type) { - unsigned long data; - int addr; + int i, j; - switch (cmd) { - case I2CIOCSADR: - if (get_user(addr, (int *)arg)) - return -EFAULT; - data = addr & 0xfe; - if (!i2c_find_device(addr & 0xfe)) - return -ENODEV; - file->private_data = (void *)data; - break; - case I2CIOCGADR: - addr = (unsigned long)file->private_data; - if (put_user(addr, (int *)arg)) - return -EFAULT; - break; - default: - return -EINVAL; + for (i = 0; i < ENVCTRL_MAX_CPU*2; i++) { + for (j = 0; j < PCF8584_MAX_CHANNELS; j++) { + if (i2c_childlist[i].mon_type[j] == mon_type) { + return (struct i2c_child_t*)(&(i2c_childlist[i])); + } + } } - return 0; + return NULL; } -static int -envctrl_open(struct inode *inode, struct file *file) -{ - file->private_data = 0; - return 0; -} - -static struct file_operations envctrl_fops = { - owner: THIS_MODULE, - llseek: envctrl_llseek, - read: envctrl_read, - write: envctrl_write, - ioctl: envctrl_ioctl, - open: envctrl_open, -}; - -static struct miscdevice envctrl_dev = { - ENVCTRL_MINOR, - "envctrl", - &envctrl_fops -}; - -#ifdef MODULE -int init_module(void) -#else -int __init envctrl_init(void) -#endif +static int __init envctrl_init(void) { #ifdef CONFIG_PCI - struct linux_ebus *ebus; - struct linux_ebus_device *edev = 0; - pid_t pid; - int err; - + struct linux_ebus *ebus = NULL; + struct linux_ebus_device *edev = NULL; + struct linux_ebus_child *edev_child = NULL; + int i = 0; + + /* Traverse through ebus and ebus device list for i2c device and + * adc and gpio nodes. + */ for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, "SUNW,envctrl")) - goto ebus_done; - if (!strcmp(edev->prom_name, "SUNW,rasctrl")) - goto ebus_done; + if (!strcmp(edev->prom_name, "i2c")) { + i2c = ioremap( edev->resource[0].start, + sizeof(struct pcf8584_reg)); + for_each_edevchild(edev, edev_child) { + if (!strcmp("gpio", edev_child->prom_name)) { + i2c_childlist[i].i2ctype = I2C_GPIO; + envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); + } + if (!strcmp("adc", edev_child->prom_name)) { + i2c_childlist[i].i2ctype = I2C_ADC; + envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); + } + } + goto done; + } } } -ebus_done: - if (!edev) { - printk("%s: ebus device not found\n", __FUNCTION__); - return -ENODEV; - } - - i2c_regs = (unsigned long) ioremap(edev->resource[0].start, I2C_REG_SIZE); - writeb(CONTROL_PIN, i2c_regs + I2C_CSR); - writeb(PCF8584_ADDRESS >> 1, i2c_regs + I2C_DATA); - writeb(CONTROL_PIN | CONTROL_ES1, i2c_regs + I2C_CSR); - writeb(CLK_4_43 | BUS_CLK_90, i2c_regs + I2C_DATA); - writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_ACK, i2c_regs + I2C_CSR); - mdelay(10); - if (misc_register(&envctrl_dev)) { - printk("%s: unable to get misc minor %d\n", - __FUNCTION__, envctrl_dev.minor); +done: + if (!edev) { + printk("envctrl: I2C device not found.\n"); return -ENODEV; } - err = i2c_scan_bus(); - if (err) { - i2c_free_devices(); - misc_deregister(&envctrl_dev); - return err; - } + /* Set device address. */ + envctrl_writeb(CONTROL_PIN, &i2c->csr); + envctrl_writeb(PCF8584_ADDRESS, &i2c->data); - memset(&envctrl, 0, sizeof(struct environment)); + /* Set system clock and SCL frequencies. */ + envctrl_writeb(CONTROL_PIN | CONTROL_ES1, &i2c->csr); + envctrl_writeb(CLK_4_43 | BUS_CLK_90, &i2c->data); - err = -ENODEV; - if (!strcmp(edev->prom_name, "SUNW,rasctrl")) - err = rasctrl_setup(edev->prom_node); -#ifdef U450_SUPPORT - else if (!strcmp(edev->prom_name, "SUNW,envctrl")) - err = envctrl_setup(edev->prom_node); -#endif + /* Enable serial interface. */ + envctrl_writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_ACK, &i2c->csr); + udelay(200); - if (err) { - envctrl_stop(); - i2c_free_devices(); - misc_deregister(&envctrl_dev); - return err; + /* Register the device as a minor miscellaneous device. */ + if (misc_register(&envctrl_dev)) { + printk("envctrl: Unable to get misc minor %d\n", + envctrl_dev.minor); } - init_waitqueue_head(&envctrl.kenvd_wait); - - pid = kernel_thread(kenvd, (void *)&envctrl, CLONE_FS); - if (pid < 0) { - envctrl_stop(); - i2c_free_devices(); - misc_deregister(&envctrl_dev); - return -ENODEV; + /* Note above traversal routine post-incremented 'i' to accomodate + * a next child device, so we decrement before reverse-traversal of + * child devices. + */ + printk("envctrl: initialized "); + for(--i; i >= 0; --i) + { + printk("[%s 0x%lx]%s", + (I2C_ADC == i2c_childlist[i].i2ctype) ? ("adc") : + ((I2C_GPIO == i2c_childlist[i].i2ctype) ? ("gpio") : ("unknown")), + i2c_childlist[i].addr, (0 == i) ? ("\n") : (" ")); } return 0; @@ -1605,13 +946,18 @@ ebus_done: #endif } - -#ifdef MODULE -void cleanup_module(void) +static void __exit envctrl_cleanup(void) { - envctrl_stop(); - i2c_free_devices(); - iounmap(i2c_regs); + int i; + + iounmap(i2c); misc_deregister(&envctrl_dev); + + for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) { + if (i2c_childlist[i].tables) + kfree(i2c_childlist[i].tables); + } } -#endif + +module_init(envctrl_init); +module_exit(envctrl_cleanup); diff --git a/drivers/sbus/char/sab82532.c b/drivers/sbus/char/sab82532.c index 7d010f035..ae7ba7ac1 100644 --- a/drivers/sbus/char/sab82532.c +++ b/drivers/sbus/char/sab82532.c @@ -1,4 +1,4 @@ -/* $Id: sab82532.c,v 1.51 2000/09/04 19:41:26 ecd Exp $ +/* $Id: sab82532.c,v 1.52 2000/10/14 10:09:04 davem Exp $ * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -2133,7 +2133,7 @@ static void __init sab82532_kgdb_hook(int line) static inline void __init show_serial_version(void) { - char *revision = "$Revision: 1.51 $"; + char *revision = "$Revision: 1.52 $"; char *version, *p; version = strchr(revision, ' '); @@ -2596,17 +2596,13 @@ sab82532_console_setup(struct console *con, char *options) } static struct console sab82532_console = { - "ttyS", - sab82532_console_write, - NULL, - sab82532_console_device, - sab82532_console_wait_key, - NULL, - sab82532_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: sab82532_console_write, + device: sab82532_console_device, + wait_key: sab82532_console_wait_key, + setup: sab82532_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; int __init sab82532_console_init(void) diff --git a/drivers/sbus/char/su.c b/drivers/sbus/char/su.c index c6e90328e..1fd2d6fbf 100644 --- a/drivers/sbus/char/su.c +++ b/drivers/sbus/char/su.c @@ -1,4 +1,4 @@ -/* $Id: su.c,v 1.41 2000/09/04 19:41:27 ecd Exp $ +/* $Id: su.c,v 1.42 2000/10/14 10:09:04 davem Exp $ * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -2219,7 +2219,7 @@ done: */ static __inline__ void __init show_su_version(void) { - char *revision = "$Revision: 1.41 $"; + char *revision = "$Revision: 1.42 $"; char *version, *p; version = strchr(revision, ' '); @@ -2938,17 +2938,13 @@ static int __init serial_console_setup(struct console *co, char *options) } static struct console sercons = { - "ttyS", - serial_console_write, - NULL, - serial_console_device, - serial_console_wait_key, - NULL, - serial_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; int su_console_registered = 0; diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c index 5540e734b..f34c12250 100644 --- a/drivers/sbus/char/sunkbd.c +++ b/drivers/sbus/char/sunkbd.c @@ -80,7 +80,7 @@ extern void reset_vc(unsigned int new_console); extern void scrollback(int); extern void scrollfront(int); -struct l1a_kbd_state l1a_state = { 0, 0 }; +struct l1a_kbd_state l1a_state; #ifndef CONFIG_PCI DECLARE_WAIT_QUEUE_HEAD(keypress_wait); @@ -101,30 +101,30 @@ static spinlock_t sunkbd_lock = SPIN_LOCK_UNLOCKED; */ /* shift state counters.. */ -static unsigned char k_down[NR_SHIFT] = {0, }; +static unsigned char k_down[NR_SHIFT]; /* keyboard key bitmap */ -static unsigned long key_down[256/BITS_PER_LONG] = { 0, }; +static unsigned long key_down[256/BITS_PER_LONG]; void push_kbd (int scan); -int kbd_redirected = 0; +int kbd_redirected; -static int dead_key_next = 0; +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 * return the value. I chose the former way. */ #ifndef CONFIG_PCI -/*static*/ int shift_state = 0; +/*static*/ int shift_state; #endif static int npadch = -1; /* -1 or number assembled on pad */ -static unsigned char diacr = 0; -static char rep = 0; /* flag telling character repeat */ +static unsigned char diacr; +static char rep; /* flag telling character repeat */ struct kbd_struct kbd_table[MAX_NR_CONSOLES]; static struct tty_struct **ttytab; static struct kbd_struct * kbd = kbd_table; -static struct tty_struct * tty = NULL; -static int compose_led_on = 0; +static struct tty_struct * tty; +static int compose_led_on; static int kbd_delay_ticks = HZ / 5; static int kbd_rate_ticks = HZ / 20; diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index 77b849ef0..73158f351 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c @@ -43,7 +43,7 @@ #include <asm/vfc_ioctls.h> static struct file_operations vfc_fops; -static devfs_handle_t devfs_handle = NULL; /* For the directory */ +static devfs_handle_t devfs_handle; /* For the directory */ struct vfc_dev **vfc_dev_lst; static char vfcstr[]="vfc"; static unsigned char saa9051_init_array[VFC_SAA9051_NR] = { diff --git a/drivers/sbus/char/zs.c b/drivers/sbus/char/zs.c index 7acfb2aba..67ef24fd3 100644 --- a/drivers/sbus/char/zs.c +++ b/drivers/sbus/char/zs.c @@ -1,4 +1,4 @@ -/* $Id: zs.c,v 1.59 2000/08/29 07:01:55 davem Exp $ +/* $Id: zs.c,v 1.60 2000/10/14 10:09:04 davem Exp $ * zs.c: Zilog serial port driver for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1913,7 +1913,7 @@ int zs_open(struct tty_struct *tty, struct file * filp) static void show_serial_version(void) { - char *revision = "$Revision: 1.59 $"; + char *revision = "$Revision: 1.60 $"; char *version, *p; version = strchr(revision, ' '); @@ -2830,17 +2830,13 @@ static int __init zs_console_setup(struct console *con, char *options) } static struct console zs_console = { - "ttyS", - zs_console_write, - NULL, - zs_console_device, - zs_console_wait_key, - NULL, - zs_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: zs_console_write, + device: zs_console_device, + wait_key: zs_console_wait_key, + setup: zs_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; static int __init zs_console_init(void) diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index b26a8677b..98ceaf3e9 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -205,7 +205,6 @@ int __init a2091_detect(Scsi_Host_Template *tpnt) address = z->resource.start; if (!request_mem_region(address, 256, "wd33c93")) continue; - strcpy(z->name, "A590/A2091 SCSI Host Adapter"); instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); instance->base = ZTWO_VADDR(address); diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index ba54b2bf0..667eedd3c 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -1280,7 +1280,8 @@ int aha152x_detect(Scsi_Host_Template * tpnt) scsi_unregister(shpnt); registered_count--; release_region(shpnt->io_port, IO_RANGE); - aha152x_host[shpnt->irq - IRQ_MIN] = shpnt = 0; + aha152x_host[shpnt->irq - IRQ_MIN] = 0; + shpnt = 0; continue; } HOSTDATA(shpnt)->swint = 0; @@ -1346,7 +1347,7 @@ int aha152x_release(struct Scsi_Host *shpnt) /* * setup controller to generate interrupts depending - * on current state (lock has to be aquired) + * on current state (lock has to be acquired) * */ static int setup_expected_interrupts(struct Scsi_Host *shpnt) diff --git a/drivers/scsi/aic7xxx.c b/drivers/scsi/aic7xxx.c index 166ec8c59..8bb8cd96d 100644 --- a/drivers/scsi/aic7xxx.c +++ b/drivers/scsi/aic7xxx.c @@ -7749,7 +7749,7 @@ aic785x_cable_detect(struct aic7xxx_host *p, int *int_50, * Description: * Detect the cables that are present on the 2940-UWPro cards * - * NOTE: This functions assumes the SEEPROM will have already been aquired + * NOTE: This function assumes the SEEPROM will have already been acquired * prior to invocation of this function. *-F*************************************************************************/ static void @@ -7795,7 +7795,7 @@ aic2940_uwpro_wide_cable_detect(struct aic7xxx_host *p, int *int_68, * Description: * Detect the cables that are present on aic787x class controller chips * - * NOTE: This functions assumes the SEEPROM will have already been aquired + * NOTE: This function assumes the SEEPROM will have already been acquired * prior to invocation of this function. *-F*************************************************************************/ static void @@ -7842,7 +7842,7 @@ aic787x_cable_detect(struct aic7xxx_host *p, int *int_50, int *int_68, * Description: * Detect the termination settings present on ultra2 class controllers * - * NOTE: This functions assumes the SEEPROM will have already been aquired + * NOTE: This function assumes the SEEPROM will have already been acquired * prior to invocation of this function. *-F*************************************************************************/ static void diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c index 217d79819..f2f457b79 100644 --- a/drivers/scsi/amiga7xx.c +++ b/drivers/scsi/amiga7xx.c @@ -72,8 +72,6 @@ int __init amiga7xx_detect(Scsi_Host_Template *tpnt) case ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS: address = 0xf40000; if (request_mem_region(address, 0x1000, "ncr53c710")) { - strcpy(z->name, - "Blizzard 603e+ Accelerator and SCSI Host Adapter"); address = ZTWO_VADDR(address); options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | OPTION_INTFLY | OPTION_SYNCHRONOUS | @@ -89,8 +87,6 @@ int __init amiga7xx_detect(Scsi_Host_Template *tpnt) #ifdef CONFIG_WARPENGINE_SCSI case ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx: if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) { - strcpy(z->name, "Warp Engine 40xx Accelerator, SCSI Host " - "Adapter and RAM Expansion"); address = (unsigned long)ioremap(address, size); options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | OPTION_INTFLY | OPTION_SYNCHRONOUS | @@ -107,7 +103,6 @@ int __init amiga7xx_detect(Scsi_Host_Template *tpnt) case ZORRO_PROD_CBM_A4091_1: case ZORRO_PROD_CBM_A4091_2: if (request_mem_region(address+0x800000, 0x1000, "ncr53c710")) { - strcpy(z->name, "A4091 SCSI Host Adapter"); address = (unsigned long)ioremap(address, size); options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | OPTION_INTFLY | OPTION_SYNCHRONOUS | @@ -123,8 +118,6 @@ int __init amiga7xx_detect(Scsi_Host_Template *tpnt) #ifdef CONFIG_GVP_TURBO_SCSI case ZORRO_PROD_GVP_GFORCE_040_060: if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) { - strcpy(z->name, "GForce 040/060 Accelerator and SCSI Host " - "Adapter"); address = ZTWO_VADDR(address); options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | OPTION_INTFLY | OPTION_SYNCHRONOUS | diff --git a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c index a13a0ff25..6872d7ca6 100644 --- a/drivers/scsi/blz1230.c +++ b/drivers/scsi/blz1230.c @@ -95,7 +95,6 @@ int __init blz1230_esp_detect(Scsi_Host_Template *tpnt) sizeof(struct ESP_regs)); return 0; /* Bail out if address did not hold data */ } - strcpy(z->name, "Blizzard 1230 SCSI IV"); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; diff --git a/drivers/scsi/blz2060.c b/drivers/scsi/blz2060.c index 3daac0f2a..77e3e4f11 100644 --- a/drivers/scsi/blz2060.c +++ b/drivers/scsi/blz2060.c @@ -68,8 +68,6 @@ int __init blz2060_esp_detect(Scsi_Host_Template *tpnt) unsigned long board = z->resource.start; if (request_mem_region(board+BLZ2060_ESP_ADDR, sizeof(struct ESP_regs), "NCR53C9x")) { - strcpy(z->name, "Blizzard 2060 Accelerator"); - esp = esp_allocate(tpnt, (void *)board+BLZ2060_ESP_ADDR); /* Do command transfer with programmed I/O */ diff --git a/drivers/scsi/cyberstorm.c b/drivers/scsi/cyberstorm.c index 87a3e842d..33150121c 100644 --- a/drivers/scsi/cyberstorm.c +++ b/drivers/scsi/cyberstorm.c @@ -89,8 +89,6 @@ int __init cyber_esp_detect(Scsi_Host_Template *tpnt) sizeof(struct ESP_regs)); return 0; } - strcpy(z->name, "Cyberstorm SCSI Host Adapter"); - esp = esp_allocate(tpnt, (void *)board+CYBER_ESP_ADDR); /* Do command transfer with programmed I/O */ diff --git a/drivers/scsi/cyberstormII.c b/drivers/scsi/cyberstormII.c index cfd5ff6cb..a1d53b314 100644 --- a/drivers/scsi/cyberstormII.c +++ b/drivers/scsi/cyberstormII.c @@ -85,7 +85,6 @@ int __init cyberII_esp_detect(Scsi_Host_Template *tpnt) sizeof(struct ESP_regs)); return 0; /* Bail out if address did not hold data */ } - strcpy(z->name, "CyberStorm Mk II SCSI Host Adapter"); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index 0d0711878..a1f277e8d 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -689,12 +689,12 @@ static void do_interrupt_handler(int, void *, struct pt_regs *); static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int); static int do_trace = FALSE; static int setup_done = FALSE; -static int link_statistics = 0; +static int link_statistics; static int tag_mode = TAG_MIXED; static int ext_tran = FALSE; static int rev_scan = TRUE; static int use_new_eh_code = TRUE; -static char *boot_options = NULL; +static char *boot_options; #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE) static int tagged_comm = TRUE; diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c index f928bb3c6..8dce8b2cf 100644 --- a/drivers/scsi/esp.c +++ b/drivers/scsi/esp.c @@ -1,4 +1,4 @@ -/* $Id: esp.c,v 1.96 2000/08/24 03:51:26 davem Exp $ +/* $Id: esp.c,v 1.97 2000/09/19 01:29:27 davem Exp $ * esp.c: EnhancedScsiProcessor Sun SCSI driver code. * * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu) diff --git a/drivers/scsi/fastlane.c b/drivers/scsi/fastlane.c index 0126ac431..bb7f89990 100644 --- a/drivers/scsi/fastlane.c +++ b/drivers/scsi/fastlane.c @@ -100,8 +100,6 @@ int __init fastlane_esp_detect(Scsi_Host_Template *tpnt) sizeof(struct ESP_regs)); return 0; } - strcpy(z->name, "Fastlane Z3 SCSI Host Adapter"); - esp = esp_allocate(tpnt, (void *)board+FASTLANE_ESP_ADDR); /* Do command transfer with programmed I/O */ diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 7eb632ba0..cd64662ee 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -230,7 +230,6 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt) address = z->resource.start; if (!request_mem_region(address, 256, "wd33c93")) continue; - strcpy(z->name, "GVP Series II SCSI"); #ifdef CHECK_WD33C93 diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index b04de5a8a..7d9492804 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -139,6 +139,12 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){ retval = (struct Scsi_Host *)kmalloc(sizeof(struct Scsi_Host) + j, (tpnt->unchecked_isa_dma && j ? GFP_DMA : 0) | GFP_ATOMIC); + if(retval == NULL) + { + printk("scsi: out of memory in scsi_register.\n"); + return NULL; + } + memset(retval, 0, sizeof(struct Scsi_Host) + j); /* trying to find a reserved entry (host_no) */ diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index a6f4f74ca..2b51924cf 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -430,12 +430,12 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) if (drive->using_dma && rq->bh) dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive); + SELECT_DRIVE(HWIF(drive), drive); if (IDE_CONTROL_REG) OUT_BYTE (drive->ctl,IDE_CONTROL_REG); OUT_BYTE (dma_ok,IDE_FEATURE_REG); OUT_BYTE (bcount >> 8,IDE_BCOUNTH_REG); OUT_BYTE (bcount & 0xff,IDE_BCOUNTL_REG); - OUT_BYTE (drive->select.all,IDE_SELECT_REG); if (dma_ok) { set_bit (PC_DMA_IN_PROGRESS, &pc->flags); @@ -608,6 +608,9 @@ int idescsi_detect (Scsi_Host_Template *host_template) host_template->proc_name = "ide-scsi"; host = scsi_register(host_template, 0); + if(host == NULL) + return 0; + for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++) last_lun = IDE_MAX(last_lun, idescsi_drives[id]->last_lun); host->max_id = id; diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 2f0c1a185..6d312168c 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1104,7 +1104,7 @@ int imm_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) } /* - * Aimmrently the the disk->capacity attribute is off by 1 sector + * Apparently the the disk->capacity attribute is off by 1 sector * for all disk drives. We add the one here, but it should really * be done in sd.c. Even if it gets fixed there, this will still * work. @@ -1118,8 +1118,6 @@ int imm_biosparam(Disk * disk, kdev_t dev, int ip[]) ip[0] = 0xff; ip[1] = 0x3f; ip[2] = (disk->capacity + 1) / (ip[0] * ip[1]); - if (ip[2] > 1023) - ip[2] = 1023; } return 0; } diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c index 2e22157f0..976a67dc6 100644 --- a/drivers/scsi/oktagon_esp.c +++ b/drivers/scsi/oktagon_esp.c @@ -124,7 +124,6 @@ int oktagon_esp_detect(Scsi_Host_Template *tpnt) unsigned long board = z->resource.start; if (request_mem_region(board+OKTAGON_ESP_ADDR, sizeof(struct ESP_regs), "NCR53C9x")) { - strcpy(z->name, "Oktagon 2008 SCSI Host Adapter"); /* * It is a SCSI controller. * Hardwire Host adapter to SCSI ID 7 diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 542876daf..cfd290c11 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -74,7 +74,7 @@ #undef USE_STATIC_SCSI_MEMORY -struct proc_dir_entry *proc_scsi = NULL; +struct proc_dir_entry *proc_scsi; #ifdef CONFIG_PROC_FS static int scsi_proc_info(char *buffer, char **start, off_t offset, int length); @@ -98,23 +98,23 @@ static void scsi_dump_status(int level); /* * Data declarations. */ -unsigned long scsi_pid = 0; -Scsi_Cmnd *last_cmnd = NULL; +unsigned long scsi_pid; +Scsi_Cmnd *last_cmnd; /* Command groups 3 and 4 are reserved and should never be used. */ const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 12, 12, 10, 10 }; -static unsigned long serial_number = 0; -static Scsi_Cmnd *scsi_bh_queue_head = NULL; -static Scsi_Cmnd *scsi_bh_queue_tail = NULL; +static unsigned long serial_number; +static Scsi_Cmnd *scsi_bh_queue_head; +static Scsi_Cmnd *scsi_bh_queue_tail; /* * Note - the initial logging level can be set here to log events at boot time. * After the system is up, you may enable logging via the /proc interface. */ -unsigned int scsi_logging_level = 0; +unsigned int scsi_logging_level; const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = { @@ -196,7 +196,7 @@ static int __init scsi_logging_setup(char *str) scsi_logging_level = (tmp ? ~0 : 0); return 1; } else { - printk("scsi_logging_setup : usage scsi_logging_level=n " + printk(KERN_INFO "scsi_logging_setup : usage scsi_logging_level=n " "(n should be 0 or non-zero)\n"); return 0; } @@ -716,7 +716,7 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt) return rtn; } -devfs_handle_t scsi_devfs_handle = NULL; +devfs_handle_t scsi_devfs_handle; /* * scsi_do_cmd sends all the commands out to the low-level driver. It @@ -1466,7 +1466,7 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt) SCpnt->owner = SCSI_OWNER_NOBODY; } if (j < SDpnt->queue_depth) { /* low on space (D.Gilbert 990424) */ - printk("scsi_build_commandblocks: want=%d, space for=%d blocks\n", + printk(KERN_WARNING "scsi_build_commandblocks: want=%d, space for=%d blocks\n", SDpnt->queue_depth, j); SDpnt->queue_depth = j; SDpnt->has_cmdblocks = (0 != j); @@ -1658,7 +1658,7 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, } } - printk("scsi logging level set to 0x%8.8x\n", scsi_logging_level); + printk(KERN_INFO "scsi logging level set to 0x%8.8x\n", scsi_logging_level); } #endif /* CONFIG_SCSI_LOGGING */ /* } */ @@ -1681,7 +1681,7 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, id = simple_strtoul(p + 1, &p, 0); lun = simple_strtoul(p + 1, &p, 0); - printk("scsi singledevice %d %d %d %d\n", host, channel, + printk(KERN_INFO "scsi singledevice %d %d %d %d\n", host, channel, id, lun); for (HBA_ptr = scsi_hostlist; HBA_ptr; HBA_ptr = HBA_ptr->next) { @@ -1839,7 +1839,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt) if (tpnt->present) { if (pcount == next_scsi_host) { if (tpnt->present > 1) { - printk("Failure to register low-level scsi driver"); + printk(KERN_ERR "scsi: Failure to register low-level scsi driver"); scsi_unregister_host(tpnt); return 1; } @@ -1847,7 +1847,12 @@ static int scsi_register_host(Scsi_Host_Template * tpnt) * The low-level driver failed to register a driver. * We can do this now. */ - scsi_register(tpnt, 0); + if(scsi_register(tpnt, 0)==NULL) + { + printk(KERN_ERR "scsi: register failed.\n"); + scsi_unregister_host(tpnt); + return 1; + } } tpnt->next = scsi_hosts; /* Add to the linked list */ scsi_hosts = tpnt; @@ -1886,7 +1891,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt) } else { name = tpnt->name; } - printk("scsi%d : %s\n", /* And print a little message */ + printk(KERN_INFO "scsi%d : %s\n", /* And print a little message */ shpnt->host_no, name); } } @@ -2027,7 +2032,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) online_status = SDpnt->online; SDpnt->online = FALSE; if (SCpnt->request.rq_status != RQ_INACTIVE) { - printk("SCSI device not inactive - rq_status=%d, target=%d, pid=%ld, state=%d, owner=%d.\n", + printk(KERN_ERR "SCSI device not inactive - rq_status=%d, target=%d, pid=%ld, state=%d, owner=%d.\n", SCpnt->request.rq_status, SCpnt->target, SCpnt->pid, SCpnt->state, SCpnt->owner); for (SDpnt1 = shpnt->host_queue; SDpnt1; @@ -2038,7 +2043,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) SCpnt->request.rq_status = RQ_INACTIVE; } SDpnt->online = online_status; - printk("Device busy???\n"); + printk(KERN_ERR "Device busy???\n"); return; } /* @@ -2064,7 +2069,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) /* If something still attached, punt */ if (SDpnt->attached) { - printk("Attached usage count = %d\n", SDpnt->attached); + printk(KERN_ERR "Attached usage count = %d\n", SDpnt->attached); return; } devfs_unregister (SDpnt->de); @@ -2145,7 +2150,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) scsi_resize_dma_pool(); if (pcount0 != next_scsi_host) - printk("scsi : %d host%s left.\n", next_scsi_host, + printk(KERN_INFO "scsi : %d host%s left.\n", next_scsi_host, (next_scsi_host == 1) ? "" : "s"); #if defined(USE_STATIC_SCSI_MEMORY) @@ -2155,20 +2160,22 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) (scsi_memory_upper_value - scsi_init_memory_start) / 1024); #endif - /* Remove it from the linked list and /proc */ - if (tpnt->present) { + /* + * Remove it from the linked list and /proc if all + * hosts were successfully removed (ie preset == 0) + */ + if (!tpnt->present) { Scsi_Host_Template **SHTp = &scsi_hosts; Scsi_Host_Template *SHT; while ((SHT = *SHTp) != NULL) { if (SHT == tpnt) { *SHTp = SHT->next; + remove_proc_entry(tpnt->proc_name, proc_scsi); break; } SHTp = &SHT->next; } - /* Rebuild the /proc/scsi directory entries */ - remove_proc_entry(tpnt->proc_name, proc_scsi); } MOD_DEC_USE_COUNT; } @@ -2379,10 +2386,10 @@ static void scsi_dump_status(int level) struct Scsi_Host *shpnt; Scsi_Cmnd *SCpnt; Scsi_Device *SDpnt; - printk("Dump of scsi host parameters:\n"); + printk(KERN_INFO "Dump of scsi host parameters:\n"); i = 0; for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) { - printk(" %d %d %d : %d %d\n", + printk(KERN_INFO " %d %d %d : %d %d\n", shpnt->host_failed, shpnt->host_busy, atomic_read(&shpnt->host_active), @@ -2390,14 +2397,14 @@ static void scsi_dump_status(int level) shpnt->host_self_blocked); } - printk("\n\n"); - printk("Dump of scsi command parameters:\n"); + printk(KERN_INFO "\n\n"); + printk(KERN_INFO "Dump of scsi command parameters:\n"); for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) { - printk("h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result\n"); + printk(KERN_INFO "h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result\n"); for (SDpnt = shpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) { /* (0) h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result %d %x */ - printk("(%3d) %2d:%1d:%2d:%2d (%6s %4ld %4ld %4ld %4x %1d) (%1d %1d 0x%2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n", + printk(KERN_INFO "(%3d) %2d:%1d:%2d:%2d (%6s %4ld %4ld %4ld %4x %1d) (%1d %1d 0x%2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n", i++, SCpnt->host->host_no, @@ -2430,7 +2437,7 @@ static void scsi_dump_status(int level) for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) { for (SDpnt = shpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { /* Now dump the request lists for each block device */ - printk("Dump of pending block device requests\n"); + printk(KERN_INFO "Dump of pending block device requests\n"); for (i = 0; i < MAX_BLKDEV; i++) { struct list_head * queue_head; @@ -2439,7 +2446,7 @@ static void scsi_dump_status(int level) struct request *req; struct list_head * entry; - printk("%d: ", i); + printk(KERN_INFO "%d: ", i); entry = queue_head->next; do { req = blkdev_entry_to_request(entry); @@ -2525,7 +2532,7 @@ static int __init init_scsi(void) scsi_devfs_handle = devfs_mk_dir (NULL, "scsi", NULL); if (scsihosts) - printk("scsi: host order: %s\n", scsihosts); + printk(KERN_INFO "scsi: host order: %s\n", scsihosts); scsi_host_no_init (scsihosts); /* * This is where the processing takes place for most everything @@ -2578,7 +2585,7 @@ module_exit(exit_scsi); * * Lock status: None assumed. * - * Returns: Nothing + * Returns: The Scsi_Device or NULL * * Notes: */ @@ -2599,6 +2606,9 @@ Scsi_Device * scsi_get_host_dev(struct Scsi_Host * SHpnt) */ SDpnt = (Scsi_Device *) kmalloc(sizeof(Scsi_Device), GFP_ATOMIC); + if(SDpnt == NULL) + return NULL; + memset(SDpnt, 0, sizeof(Scsi_Device)); SDpnt->host = SHpnt; diff --git a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c index c082ae538..7483eb970 100644 --- a/drivers/scsi/scsi_merge.c +++ b/drivers/scsi/scsi_merge.c @@ -869,7 +869,7 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt, * Next, walk the list, and fill in the addresses and sizes of * each segment. */ - memset(sgpnt, 0, SCpnt->use_sg * sizeof(struct scatterlist)); + memset(sgpnt, 0, SCpnt->sglist_len); SCpnt->request_buffer = (char *) sgpnt; SCpnt->request_bufflen = 0; bhprev = NULL; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 6d5b92f1f..971783407 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2578,7 +2578,7 @@ static int sg_proc_dressz_write(struct file * filp, const char * buffer, return -EACCES; num = (count < 10) ? count : 10; copy_from_user(buff, buffer, num); - buff[count] = '\0'; + buff[num] = '\0'; k = simple_strtoul(buff, 0, 10); if (k <= 1048576) { sg_big_buff = k; diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 8ce5a87ab..c479ccfc5 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -1448,10 +1448,16 @@ sim710_detect(Scsi_Host_Template * tpnt) tpnt->proc_name = "sim710"; for(indx = 0; indx < no_of_boards; indx++) { + unsigned long page = __get_free_pages(GFP_ATOMIC, order); + if(page == NULL) + { + printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx); + break; + } host = scsi_register(tpnt, 4); - host->hostdata[0] = __get_free_pages(GFP_ATOMIC, order); - if (host->hostdata[0] == 0) - panic ("sim710: Couldn't get hostdata memory"); + if(host == NULL) + break; + host->hostdata[0] = page; hostdata = (struct sim710_hostdata *)host->hostdata[0]; memset(hostdata, 0, size); #ifdef CONFIG_TP34V_SCSI diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 6357f150a..eb2c84f92 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -473,9 +473,19 @@ void get_sectorsize(int i) Scsi_Request *SRpnt; buffer = (unsigned char *) scsi_malloc(512); - - SRpnt = scsi_allocate_request(scsi_CDs[i].device); + + if(buffer == NULL || SRpnt == NULL) + { + scsi_CDs[i].capacity = 0x1fffff; + sector_size = 2048; /* A guess, just in case */ + scsi_CDs[i].needs_sector_size = 1; + if(buffer) + scsi_free(buffer, 512); + if(SRpnt) + scsi_release_request(SRpnt); + return; + } retries = 3; do { diff --git a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h index 78f23f6d3..5e4b52c78 100644 --- a/drivers/scsi/sym53c8xx_comm.h +++ b/drivers/scsi/sym53c8xx_comm.h @@ -1546,10 +1546,10 @@ out: return retv; } -#undef SET_BIT 0 -#undef CLR_BIT 1 -#undef SET_CLK 2 -#undef CLR_CLK 3 +#undef SET_BIT +#undef CLR_BIT +#undef SET_CLK +#undef CLR_CLK /* * Try reading Symbios NVRAM. diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index b1399d36d..5d943c645 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -951,7 +951,7 @@ static int mail_out (Adapter *host, Scb *scbptr) break; } else - ogmb = (++ogmb) % OGMB_CNT; + ogmb = (ogmb + 1) % OGMB_CNT; } restore_flags (flags); diff --git a/drivers/sgi/char/sgiserial.c b/drivers/sgi/char/sgiserial.c index ad382c751..bf4899735 100644 --- a/drivers/sgi/char/sgiserial.c +++ b/drivers/sgi/char/sgiserial.c @@ -2253,17 +2253,13 @@ static int __init zs_console_setup(struct console *con, char *options) } static struct console sgi_console_driver = { - "ttyS", - zs_console_write, /* write */ - NULL, /* read */ - zs_console_device, /* device */ - zs_console_wait_key, /* wait_key */ - NULL, /* unblank */ - zs_console_setup, /* setup */ - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: zs_console_write, + device: zs_console_device, + wait_key: zs_console_wait_key, + setup: zs_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/drivers/sound/ac97_codec.c b/drivers/sound/ac97_codec.c index aee6aec0c..20f307d13 100644 --- a/drivers/sound/ac97_codec.c +++ b/drivers/sound/ac97_codec.c @@ -1,3 +1,4 @@ + /* * ac97_codec.c: Generic AC97 mixer/modem module * @@ -58,7 +59,8 @@ static struct { char *name; int (*init) (struct ac97_codec *codec); } ac97_codec_ids[] = { - {0x414B4D00, "Asahi Kasei AK4540" , NULL}, + {0x414B4D00, "Asahi Kasei AK4540 rev 0", NULL}, + {0x414B4D01, "Asahi Kasei AK4540 rev 1", NULL}, {0x41445340, "Analog Devices AD1881" , NULL}, {0x41445360, "Analog Devices AD1885" , enable_eapd}, {0x43525900, "Cirrus Logic CS4297" , NULL}, @@ -622,8 +624,8 @@ int ac97_probe_codec(struct ac97_codec *codec) } if (codec->name == NULL) codec->name = "Unknown"; - printk(KERN_INFO "ac97_codec: AC97 %s codec, vendor id1: 0x%04x, " - "id2: 0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""), + printk(KERN_INFO "ac97_codec: AC97 %s codec, id: 0x%04x:" + "0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""), id1, id2, codec->name); return ac97_init_mixer(codec); diff --git a/drivers/sound/es1370.c b/drivers/sound/es1370.c index 72f3e569b..f7ce193f0 100644 --- a/drivers/sound/es1370.c +++ b/drivers/sound/es1370.c @@ -109,7 +109,6 @@ * 12.08.1999 0.27 module_init/__setup fixes * 19.08.1999 0.28 SOUND_MIXER_IMIX fixes, reported by Gianluca <gialluca@mail.tiscalinet.it> * 31.08.1999 0.29 add spin_lock_init - * __initlocaldata to fix gcc 2.7.x problems * replaced current->state = x with set_current_state(x) * 03.09.1999 0.30 change read semantics for MIDI to match * OSS more closely; remove possible wakeup race @@ -2677,7 +2676,7 @@ module_exit(cleanup_es1370); static int __init es1370_setup(char *str) { - static unsigned __initlocaldata nr_dev = 0; + static unsigned __initdata nr_dev = 0; if (nr_dev >= NR_DEVICE) return 0; diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c index 0661ac602..ac420b390 100644 --- a/drivers/sound/es1371.c +++ b/drivers/sound/es1371.c @@ -82,7 +82,6 @@ * updated SRC and CODEC w/r functions to accomodate bugs * in some versions of the ES137x chips. * 31.08.1999 0.17 add spin_lock_init - * __initlocaldata to fix gcc 2.7.x problems * replaced current->state = x with set_current_state(x) * 03.09.1999 0.18 change read semantics for MIDI to match * OSS more closely; remove possible wakeup race @@ -2949,7 +2948,7 @@ module_exit(cleanup_es1371); static int __init es1371_setup(char *str) { - static unsigned __initlocaldata nr_dev = 0; + static unsigned __initdata nr_dev = 0; if (nr_dev >= NR_DEVICE) return 0; diff --git a/drivers/sound/msnd_pinnacle.c b/drivers/sound/msnd_pinnacle.c index dc3e548c6..7b9b1cc29 100644 --- a/drivers/sound/msnd_pinnacle.c +++ b/drivers/sound/msnd_pinnacle.c @@ -1595,20 +1595,20 @@ static int write_ndelay __initdata = -1; static int cfg __initdata = -1; /* Extra Peripheral Configuration */ -static int reset __initdata; -static int mpu_io __initdata; -static int mpu_irq __initdata; -static int ide_io0 __initdata; -static int ide_io1 __initdata; -static int ide_irq __initdata; -static int joystick_io __initdata; +static int reset __initdata = 0; +static int mpu_io __initdata = 0; +static int mpu_irq __initdata = 0; +static int ide_io0 __initdata = 0; +static int ide_io1 __initdata = 0; +static int ide_irq __initdata = 0; +static int joystick_io __initdata = 0; /* If we have the digital daugherboard... */ -static int digital __initdata; +static int digital __initdata = 0; #endif static int fifosize __initdata = DEFFIFOSIZE; -static int calibrate_signal __initdata; +static int calibrate_signal __initdata = 0; #else /* not a module */ diff --git a/drivers/sound/nm256_audio.c b/drivers/sound/nm256_audio.c index c41c858d0..27f432e17 100644 --- a/drivers/sound/nm256_audio.c +++ b/drivers/sound/nm256_audio.c @@ -58,9 +58,7 @@ nm256_release_ports (struct nm256_info *card) for (x = 0; x < 2; x++) { if (card->port[x].ptr != NULL) { - u32 size = - card->port[x].end_offset - card->port[x].start_offset; - release_region ((unsigned long) card->port[x].ptr, size); + iounmap (card->port[x].ptr); card->port[x].ptr = NULL; } } @@ -1025,7 +1023,7 @@ nm256_peek_for_sig (struct nm256_info *card) pointer); } - release_region ((unsigned long) temp, 16); + iounmap (temp); } /* diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c index e7a18d2ad..0aef3da29 100644 --- a/drivers/sound/sonicvibes.c +++ b/drivers/sound/sonicvibes.c @@ -76,7 +76,6 @@ * 12.08.1999 0.18 module_init/__setup fixes * 24.08.1999 0.19 get rid of the dmaio kludge, replace with allocate_resource * 31.08.1999 0.20 add spin_lock_init - * __initlocaldata to fix gcc 2.7.x problems * use new resource allocation to allocate DDMA IO space * replaced current->state = x with set_current_state(x) * 03.09.1999 0.21 change read semantics for MIDI to match @@ -2451,7 +2450,7 @@ static struct initvol { static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) { - static const char __initlocaldata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller"; + static const char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller"; struct sv_state *s; mm_segment_t fs; int i, val; @@ -2694,7 +2693,7 @@ module_exit(cleanup_sonicvibes); static int __init sonicvibes_setup(char *str) { - static unsigned __initlocaldata nr_dev = 0; + static unsigned __initdata nr_dev = 0; if (nr_dev >= NR_DEVICE) return 0; diff --git a/drivers/sound/sound_core.c b/drivers/sound/sound_core.c index dd174bfa6..50a045c1c 100644 --- a/drivers/sound/sound_core.c +++ b/drivers/sound/sound_core.c @@ -152,7 +152,7 @@ spinlock_t sound_loader_lock = SPIN_LOCK_UNLOCKED; * list. Acquires locks as needed */ -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static int sound_insert_unit(struct sound_unit **list, struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode) { diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c index 7ca4666e4..b4db5bb5f 100644 --- a/drivers/sound/trident.c +++ b/drivers/sound/trident.c @@ -12,7 +12,7 @@ * Hacked up by: * Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support - * Ching Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support + * Ching-Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support * * * This program is free software; you can redistribute it and/or modify @@ -30,6 +30,12 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * History + * v0.14.6 + * Oct 18 2000 Ching-Ling Lee + * 5.1-channels support for ALi + * June 28 2000 Ching-Ling Lee + * S/PDIF out/in(playback/record) support for ALi 1535+, using /proc to be selected by user + * Simple Power Management support for ALi * v0.14.5 May 23 2000 Ollie Lho * Misc bug fix from the Net * v0.14.4 May 20 2000 Aaron Holtzman @@ -38,10 +44,10 @@ * remove open_wait wq (which appears to be unused) * v0.14.3 May 10 2000 Ollie Lho * fixed a small bug in trident_update_ptr, xmms 1.0.1 no longer uses 100% CPU - * v0.14.2 Mar 29 2000 Ching Ling Lee + * v0.14.2 Mar 29 2000 Ching-Ling Lee * Add clear to silence advance in trident_update_ptr * fix invalid data of the end of the sound - * v0.14.1 Mar 24 2000 Ching Ling Lee + * v0.14.1 Mar 24 2000 Ching-Ling Lee * ALi 5451 support added, playback and recording O.K. * ALi 5451 originally developed and structured based on sonicvibes, and * suggested to merge into this file by Alan Cox. @@ -113,10 +119,13 @@ #include <asm/uaccess.h> #include <asm/hardirq.h> #include <linux/bitops.h> +#include <linux/proc_fs.h> #include "trident.h" -#define DRIVER_VERSION "0.14.5" +#include <linux/pm.h> + +#define DRIVER_VERSION "0.14.6" /* magic numbers to protect our data structures */ #define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */ @@ -133,6 +142,8 @@ /* minor number of /dev/swmodem (temporary, experimental) */ #define SND_DEV_SWMODEM 7 +static const unsigned ali_multi_channels[] = { ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL,ALI_CENTER_CHANNEL, ALI_LEF_CHANNEL/*, ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL*/}; + static const unsigned sample_size[] = { 1, 2, 2, 4 }; static const unsigned sample_shift[] = { 0, 1, 1, 2 }; @@ -215,6 +226,11 @@ struct trident_state { int ossmaxfrags; unsigned subdivision; } dmabuf; + + /* 5.1channels */ + struct trident_state *other_states[4]; + int multi_channels_adjust_count; + unsigned chans_num; }; /* hardware channels */ @@ -306,10 +322,7 @@ static int attr2mask [] = { DSP_BIND_I2S, DSP_BIND_CENTER_LFE, DSP_BIND_SURR, DSP_BIND_SPDIF }; -static struct trident_card *devs = NULL; - -static void ali_ac97_set(struct ac97_codec *codec, u8 reg, u16 val); -static u16 ali_ac97_get(struct ac97_codec *codec, u8 reg); +static struct trident_card *devs; static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val); static u16 trident_ac97_get(struct ac97_codec *codec, u8 reg); @@ -319,6 +332,37 @@ static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned unsigned long arg); static loff_t trident_llseek(struct file *file, loff_t offset, int origin); +static void ali_ac97_set(struct ac97_codec *codec, u8 reg, u16 val); +static u16 ali_ac97_get(struct ac97_codec *codec, u8 reg); +static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate); +static void ali_enable_special_channel(struct trident_state *stat); +static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *card); +static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card); +static int ali_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data); +static void ali_restore_regs(struct trident_card *card); +static void ali_save_regs(struct trident_card *card); +static int ali_allocate_multi_channels(struct trident_state *state, int chan_nums); +static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel); +static int ali_setup_multi_channels(struct trident_card *card, int chan_nums); +static unsigned int ali_get_spdif_in_rate(struct trident_card *card); +static void ali_setup_spdif_in(struct trident_card *card); +static void ali_disable_spdif_in(struct trident_card *card); +static void ali_disable_special_channel(struct trident_card *card, int ch); +static void ali_setup_spdif_out(struct trident_card *card, int flag); +static unsigned int ali_write_5_1(struct trident_state *state, const char *buffer,int cnt_for_multi_channel); + + +/* save registers for ALi Power Management */ +static struct ali_saved_registers { + unsigned long global_regs[ALI_GLOBAL_REGS]; + unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; + unsigned mixer_regs[ALI_MIXER_REGS]; +} ali_registers; + +#define seek_offset(dma_ptr, buffer, cnt, offset) (dma_ptr) += (offset); \ + (buffer) += (offset); \ + (cnt) -= (offset); + static int trident_enable_loop_interrupts(struct trident_card * card) { u32 global_control; @@ -496,44 +540,6 @@ static struct trident_channel * trident_alloc_pcm_channel(struct trident_card *c return NULL; } -static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card) -{ - struct trident_pcm_bank *bank; - int idx; - - bank = &card->banks[BANK_A]; - - for (idx = ALI_PCM_OUT_CHANNEL_FIRST; idx <= ALI_PCM_OUT_CHANNEL_LAST ; idx++) { - if (!(bank->bitmap & (1 << idx))) { - struct trident_channel *channel = &bank->channels[idx]; - bank->bitmap |= 1 << idx; - channel->num = idx; - return channel; - } - } - - /* no more free channels avaliable */ - printk(KERN_ERR "trident: no more channels available on Bank B.\n"); - return NULL; -} - -static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *card) -{ - struct trident_pcm_bank *bank; - int idx = ALI_PCM_IN_CHANNEL; - - bank = &card->banks[BANK_A]; - - if (!(bank->bitmap & (1 << idx))) { - struct trident_channel *channel = &bank->channels[idx]; - bank->bitmap |= 1 << idx; - channel->num = idx; - return channel; - } - return NULL; -} - - static void trident_free_pcm_channel(struct trident_card *card, unsigned int channel) { int bank; @@ -547,20 +553,6 @@ static void trident_free_pcm_channel(struct trident_card *card, unsigned int cha card->banks[bank].bitmap &= ~(1 << (channel)); } -static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel) -{ - int bank; - - if (channel > 31) - return; - - bank = channel >> 5; - channel = channel & 0x1f; - - card->banks[bank].bitmap &= ~(1 << (channel)); -} - - /* called with spin lock held */ static int trident_load_channel_registers(struct trident_card *card, u32 *data, unsigned int channel) @@ -713,6 +705,16 @@ static void trident_play_setup(struct trident_state *state) if (state->card->pci_id != PCI_DEVICE_ID_SI_7018) { channel->attribute = 0; + if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451) { + if ((channel->num == ALI_SPDIF_IN_CHANNEL) || (channel->num == ALI_PCM_IN_CHANNEL)) + ali_disable_special_channel(state->card, channel->num); + else if ((inl(TRID_REG(state->card, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE) + && (channel->num == ALI_SPDIF_OUT_CHANNEL)) + { + ali_set_spdif_out_rate(state->card, state->dmabuf.rate); + state->dmabuf.channel->delta = 0x1000; + } + } } channel->fm_vol = 0x0; @@ -742,11 +744,14 @@ static void trident_rec_setup(struct trident_state *state) struct trident_card *card = state->card; struct dmabuf *dmabuf = &state->dmabuf; struct trident_channel *channel = dmabuf->channel; + unsigned int rate; /* Enable AC-97 ADC (capture) */ switch (card->pci_id) { case PCI_DEVICE_ID_ALI_5451: + ali_enable_special_channel(state); + break; case PCI_DEVICE_ID_SI_7018: /* for 7018, the ac97 is always in playback/record (duplex) mode */ break; @@ -768,7 +773,12 @@ static void trident_rec_setup(struct trident_state *state) channel->lba = virt_to_bus(dmabuf->rawbuf); channel->delta = compute_rate_rec(dmabuf->rate); - + if ((card->pci_id == PCI_DEVICE_ID_ALI_5451) && (channel->num == ALI_SPDIF_IN_CHANNEL)) { + rate = ali_get_spdif_in_rate(card); + if (rate != 48000) + channel->delta = ((rate << 12) / dmabuf->rate) & 0x0000ffff; + } + channel->eso = dmabuf->dmasize >> sample_shift[dmabuf->fmt]; channel->eso -= 1; @@ -882,6 +892,12 @@ extern __inline__ void __stop_dac(struct trident_state *state) dmabuf->enable &= ~DAC_RUNNING; trident_stop_voice(card, chan_num); + if (state->chans_num == 6) { + trident_stop_voice(card, state->other_states[0]->dmabuf.channel->num); + trident_stop_voice(card, state->other_states[1]->dmabuf.channel->num); + trident_stop_voice(card, state->other_states[2]->dmabuf.channel->num); + trident_stop_voice(card, state->other_states[3]->dmabuf.channel->num); + } trident_disable_voice_irq(card, chan_num); } @@ -907,6 +923,12 @@ static void start_dac(struct trident_state *state) dmabuf->enable |= DAC_RUNNING; trident_enable_voice_irq(card, chan_num); trident_start_voice(card, chan_num); + if (state->chans_num == 6) { + trident_start_voice(card, state->other_states[0]->dmabuf.channel->num); + trident_start_voice(card, state->other_states[1]->dmabuf.channel->num); + trident_start_voice(card, state->other_states[2]->dmabuf.channel->num); + trident_start_voice(card, state->other_states[3]->dmabuf.channel->num); + } } spin_unlock_irqrestore(&card->lock, flags); } @@ -970,64 +992,101 @@ static int prog_dmabuf(struct trident_state *state, unsigned rec) { struct dmabuf *dmabuf = &state->dmabuf; unsigned bytepersec; - unsigned bufsize; + struct trident_state *s = state; + unsigned bufsize, dma_nums, default_order; unsigned long flags; - int ret; - - spin_lock_irqsave(&state->card->lock, flags); - dmabuf->hwptr = dmabuf->swptr = dmabuf->total_bytes = 0; - dmabuf->count = dmabuf->error = 0; - spin_unlock_irqrestore(&state->card->lock, flags); - - /* allocate DMA buffer if not allocated yet */ - if (!dmabuf->rawbuf) - if ((ret = alloc_dmabuf(state))) - return ret; - - /* FIXME: figure out all this OSS fragment stuff */ - bytepersec = dmabuf->rate << sample_shift[dmabuf->fmt]; - bufsize = PAGE_SIZE << dmabuf->buforder; - if (dmabuf->ossfragshift) { - if ((1000 << dmabuf->ossfragshift) < bytepersec) - dmabuf->fragshift = ld2(bytepersec/1000); - else - dmabuf->fragshift = dmabuf->ossfragshift; - } else { - /* lets hand out reasonable big ass buffers by default */ - dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT -2); - } - dmabuf->numfrag = bufsize >> dmabuf->fragshift; - while (dmabuf->numfrag < 4 && dmabuf->fragshift > 3) { - dmabuf->fragshift--; - dmabuf->numfrag = bufsize >> dmabuf->fragshift; + int ret, i, order; + struct page *page, *pend; + + default_order = DMABUF_DEFAULTORDER; + if (s->chans_num == 6) { + dma_nums = 5; + } + else { + dma_nums = 1; } - dmabuf->fragsize = 1 << dmabuf->fragshift; - if (dmabuf->ossmaxfrags >= 4 && dmabuf->ossmaxfrags < dmabuf->numfrag) - dmabuf->numfrag = dmabuf->ossmaxfrags; - dmabuf->fragsamples = dmabuf->fragsize >> sample_shift[dmabuf->fmt]; - dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift; + + for (i = 0; i < dma_nums; i++) { + if (i > 0) { + s = state->other_states[i - 1]; + dmabuf = &s->dmabuf; + dmabuf->fmt = state->dmabuf.fmt; + dmabuf->rate = state->dmabuf.rate; + } - memset(dmabuf->rawbuf, (dmabuf->fmt & TRIDENT_FMT_16BIT) ? 0 : 0x80, - dmabuf->dmasize); + spin_lock_irqsave(&s->card->lock, flags); + dmabuf->hwptr = dmabuf->swptr = dmabuf->total_bytes = 0; + dmabuf->count = dmabuf->error = 0; + spin_unlock_irqrestore(&s->card->lock, flags); - spin_lock_irqsave(&state->card->lock, flags); - if (rec) { - trident_rec_setup(state); - } else { - trident_play_setup(state); - } - spin_unlock_irqrestore(&state->card->lock, flags); + /* allocate DMA buffer if not allocated yet */ + if (!dmabuf->rawbuf) { + if (i == 0) { + if ((ret = alloc_dmabuf(state))) + return ret; + } + else { + if ((order = state->dmabuf.buforder - 1) >= DMABUF_MINORDER) + dmabuf->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order); + if (!dmabuf->rawbuf) { + free_pages((unsigned long)state->dmabuf.rawbuf, state->dmabuf.buforder); + state->dmabuf.rawbuf = NULL; + i-=2; + for (; i >= 0; i--) + free_pages((unsigned long)state->other_states[i]->dmabuf.rawbuf, state->other_states[i]->dmabuf.buforder); + return -ENOMEM; + } + dmabuf->ready = dmabuf->mapped = 0; + dmabuf->buforder = order; + pend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << order) - 1); + for (page = virt_to_page(dmabuf->rawbuf); page <= pend; page++) + mem_map_reserve(page); + } + } + /* FIXME: figure out all this OSS fragment stuff */ + bytepersec = dmabuf->rate << sample_shift[dmabuf->fmt]; + bufsize = PAGE_SIZE << dmabuf->buforder; + if (dmabuf->ossfragshift) { + if ((1000 << dmabuf->ossfragshift) < bytepersec) + dmabuf->fragshift = ld2(bytepersec/1000); + else + dmabuf->fragshift = dmabuf->ossfragshift; + } else { + /* lets hand out reasonable big ass buffers by default */ + dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT -2); + } + dmabuf->numfrag = bufsize >> dmabuf->fragshift; + while (dmabuf->numfrag < 4 && dmabuf->fragshift > 3) { + dmabuf->fragshift--; + dmabuf->numfrag = bufsize >> dmabuf->fragshift; + } + dmabuf->fragsize = 1 << dmabuf->fragshift; + if (dmabuf->ossmaxfrags >= 4 && dmabuf->ossmaxfrags < dmabuf->numfrag) + dmabuf->numfrag = dmabuf->ossmaxfrags; + dmabuf->fragsamples = dmabuf->fragsize >> sample_shift[dmabuf->fmt]; + dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift; + + memset(dmabuf->rawbuf, (dmabuf->fmt & TRIDENT_FMT_16BIT) ? 0 : 0x80, + dmabuf->dmasize); + + spin_lock_irqsave(&s->card->lock, flags); + if (rec) { + trident_rec_setup(s); + } else { + trident_play_setup(s); + } + spin_unlock_irqrestore(&s->card->lock, flags); - /* set the ready flag for the dma buffer */ - dmabuf->ready = 1; + /* set the ready flag for the dma buffer */ + dmabuf->ready = 1; #ifdef DEBUG - printk("trident: prog_dmabuf, sample rate = %d, format = %d, numfrag = %d, " + printk("trident: prog_dmabuf(%d), sample rate = %d, format = %d, numfrag = %d, " "fragsize = %d dmasize = %d\n", - dmabuf->rate, dmabuf->fmt, dmabuf->numfrag, + dmabuf->channel->num, dmabuf->rate, dmabuf->fmt, dmabuf->numfrag, dmabuf->fragsize, dmabuf->dmasize); #endif - + } return 0; } @@ -1151,6 +1210,27 @@ static void trident_update_ptr(struct trident_state *state) __stop_adc(state); dmabuf->error++; } + if (dmabuf->count < (signed)dmabuf->dmasize/2) + wake_up(&dmabuf->wait); + } + } + + /* error handling and process wake up for DAC */ + if (dmabuf->enable == DAC_RUNNING) { + if (dmabuf->mapped) { + dmabuf->count += diff; + if (dmabuf->count >= (signed)dmabuf->fragsize) + wake_up(&dmabuf->wait); + } else { + dmabuf->count -= diff; + + if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) { + /* buffer underrun or buffer overrun, we have no way to recover + it here, just stop the machine and let the process force hwptr + and swptr to sync */ + __stop_dac(state); + dmabuf->error++; + } else if (!dmabuf->endcleared) { swptr = dmabuf->swptr; silence = (dmabuf->fmt & TRIDENT_FMT_16BIT ? 0 : 0x80); @@ -1168,7 +1248,18 @@ static void trident_update_ptr(struct trident_state *state) //clear the invalid data memset (dmabuf->rawbuf + swptr, silence, clear_cnt); - + if (state->chans_num == 6) { + clear_cnt = clear_cnt / 2; + swptr = swptr / 2; + memset (state->other_states[0]->dmabuf.rawbuf + swptr, + silence, clear_cnt); + memset (state->other_states[1]->dmabuf.rawbuf + swptr, + silence, clear_cnt); + memset (state->other_states[2]->dmabuf.rawbuf + swptr, + silence, clear_cnt); + memset (state->other_states[3]->dmabuf.rawbuf + swptr, + silence, clear_cnt); + } dmabuf->endcleared = 1; } } else if (dmabuf->count < (signed) dmabuf->fragsize) { @@ -1176,35 +1267,23 @@ static void trident_update_ptr(struct trident_state *state) if ((swptr + clear_cnt) > dmabuf->dmasize) clear_cnt = dmabuf->dmasize - swptr; memset (dmabuf->rawbuf + swptr, silence, clear_cnt); + if (state->chans_num == 6) { + clear_cnt = clear_cnt / 2; + swptr = swptr / 2; + memset (state->other_states[0]->dmabuf.rawbuf + swptr, + silence, clear_cnt); + memset (state->other_states[1]->dmabuf.rawbuf + swptr, + silence, clear_cnt); + memset (state->other_states[2]->dmabuf.rawbuf + swptr, + silence, clear_cnt); + memset (state->other_states[3]->dmabuf.rawbuf + swptr, + silence, clear_cnt); + } dmabuf->endcleared = 1; } } /* trident_update_ptr is called by interrupt handler or by process via ioctl/poll, we only wake up the waiting process when we have more - than 1/2 buffer of data to process (always true for interrupt handler) */ - if (dmabuf->count > (signed)dmabuf->dmasize/2) - wake_up(&dmabuf->wait); - } - } - - /* error handling and process wake up for DAC */ - if (dmabuf->enable == DAC_RUNNING) { - if (dmabuf->mapped) { - dmabuf->count += diff; - if (dmabuf->count >= (signed)dmabuf->fragsize) - wake_up(&dmabuf->wait); - } else { - dmabuf->count -= diff; - - if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) { - /* buffer underrun or buffer overrun, we have no way to recover - it here, just stop the machine and let the process force hwptr - and swptr to sync */ - __stop_dac(state); - dmabuf->error++; - } - /* trident_update_ptr is called by interrupt handler or by process via - ioctl/poll, we only wake up the waiting process when we have more than 1/2 buffer free (always true for interrupt handler) */ if (dmabuf->count < (signed)dmabuf->dmasize/2) wake_up(&dmabuf->wait); @@ -1235,55 +1314,6 @@ static void trident_address_interrupt(struct trident_card *card) } } -static void ali_address_interrupt(struct trident_card *card) -{ - int i; - u32 mask = trident_get_interrupt_mask (card, BANK_A); - -#ifdef DEBUG - /* Sanity check to make sure that every state has a channel - and vice versa. */ - u32 done = 0; - unsigned ns = 0; - unsigned nc = 0; - for (i = 0; i < NR_HW_CH; i++) { - if (card->banks[BANK_A].bitmap & (1<<i)) - nc ++; - - if (card->states[i]) { - u32 bit = 1 << card->states[i]->dmabuf.channel->num; - if (bit & done) - printk (KERN_ERR "trident: channel allocated to two states\n"); - ns++; - - done |= bit; - } - } - if (ns != nc) - printk (KERN_ERR "trident: number of states != number of channels\n"); -#endif - - for (i = 0; mask && i < NR_HW_CH; i++) { - struct trident_state *state = card->states[i]; - if (!state) - continue; - - trident_ack_channel_interrupt(card, state->dmabuf.channel->num); - mask &= ~ (1<<state->dmabuf.channel->num); - state->dmabuf.update_flag |= ALI_ADDRESS_INT_UPDATE; - trident_update_ptr(state); - } - - if (mask) - for (i = 0; i < NR_HW_CH; i++) - if (mask & (1<<i)) { - printk("ali: spurious channel irq %d.\n", i); - trident_stop_voice(card, i); - trident_disable_voice_irq(card, i); - } - -} - static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct trident_card *card = (struct trident_card *)dev_id; @@ -1337,10 +1367,6 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_ return -EFAULT; ret = 0; - if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451) - outl(inl(TRID_REG (state->card, ALI_GLOBAL_CONTROL)) | ALI_PCM_IN_ENABLE, - TRID_REG (state->card, ALI_GLOBAL_CONTROL)); - while (count > 0) { spin_lock_irqsave(&state->card->lock, flags); if (dmabuf->count > (signed) dmabuf->dmasize) { @@ -1424,11 +1450,11 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count unsigned long flags; unsigned swptr; int cnt; + unsigned int state_cnt; #ifdef DEBUG printk("trident: trident_write called, count = %d\n", count); #endif - VALIDATE_STATE(state); if (ppos != &file->f_pos) return -ESPIPE; @@ -1440,11 +1466,6 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count return -EFAULT; ret = 0; - if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451) - if (dmabuf->channel->num == ALI_PCM_IN_CHANNEL) - outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) & - ALI_PCM_IN_DISABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL)); - while (count > 0) { spin_lock_irqsave(&state->card->lock, flags); if (dmabuf->count < 0) { @@ -1497,21 +1518,28 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count } continue; } - if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) { - if (!ret) ret = -EFAULT; - return ret; + + if (state->chans_num == 6) { + state_cnt = ali_write_5_1(state, buffer, cnt); } - - swptr = (swptr + cnt) % dmabuf->dmasize; - + else { + if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) { + if (!ret) ret = -EFAULT; + return ret; + } + state_cnt = cnt; + } + + swptr = (swptr + state_cnt) % dmabuf->dmasize; + spin_lock_irqsave(&state->card->lock, flags); dmabuf->swptr = swptr; - dmabuf->count += cnt; + dmabuf->count += state_cnt; dmabuf->endcleared = 0; spin_unlock_irqrestore(&state->card->lock, flags); count -= cnt; - buffer += cnt; + buffer += cnt; ret += cnt; start_dac(state); } @@ -1720,22 +1748,38 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm if (file->f_mode & FMODE_WRITE) { stop_dac(state); dmabuf->ready = 0; - if (val >= 2) + if (val >= 2) { dmabuf->fmt |= TRIDENT_FMT_STEREO; + if (val == 6) { + val = ali_setup_multi_channels(state->card, 6); + if (val < 0) + return val; + down(&state->card->open_sem); + val = ali_allocate_multi_channels(state, 6); + up(&state->card->open_sem); + if (val < 0) + return val; + val = 6; + } + else val = 2; + } else dmabuf->fmt &= ~TRIDENT_FMT_STEREO; } if (file->f_mode & FMODE_READ) { stop_adc(state); dmabuf->ready = 0; - if (val >= 2) + if (val >= 2) { + if (val!=6) + val = 2; dmabuf->fmt |= TRIDENT_FMT_STEREO; + } else dmabuf->fmt &= ~TRIDENT_FMT_STEREO; } } - return put_user((dmabuf->fmt & TRIDENT_FMT_STEREO) ? 2 : 1, - (int *)arg); + state->chans_num = val; + return put_user(val, (int *)arg); case SNDCTL_DSP_POST: /* FIXME: the same as RESET ?? */ @@ -1982,11 +2026,6 @@ static int trident_open(struct inode *inode, struct file *file) } if (file->f_mode & FMODE_READ) { - if (card->pci_id == PCI_DEVICE_ID_ALI_5451) { - card->states[ALI_PCM_IN_CHANNEL] = state; - card->states[i] = NULL; - state->virt = ALI_PCM_IN_CHANNEL; - } /* FIXME: Trident 4d can only record in signed 16-bits stereo, 48kHz sample, to be dealed with in trident_set_adc_rate() ?? */ dmabuf->fmt &= ~TRIDENT_FMT_MASK; @@ -2036,6 +2075,24 @@ static int trident_release(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) { stop_dac(state); + if (state->chans_num == 6) { + dealloc_dmabuf(state->other_states[0]); + dealloc_dmabuf(state->other_states[1]); + dealloc_dmabuf(state->other_states[2]); + dealloc_dmabuf(state->other_states[3]); + state->card->free_pcm_channel(state->card, state->other_states[0]->dmabuf.channel->num); + state->card->free_pcm_channel(state->card, state->other_states[1]->dmabuf.channel->num); + state->card->free_pcm_channel(state->card, state->other_states[2]->dmabuf.channel->num); + state->card->free_pcm_channel(state->card, state->other_states[3]->dmabuf.channel->num); + card->states[state->other_states[0]->virt] = NULL; + kfree(state->other_states[0]); + card->states[state->other_states[1]->virt] = NULL; + kfree(state->other_states[1]); + card->states[state->other_states[2]->virt] = NULL; + kfree(state->other_states[2]); + card->states[state->other_states[3]->virt] = NULL; + kfree(state->other_states[3]); + } dealloc_dmabuf(state); state->card->free_pcm_channel(state->card, dmabuf->channel->num); } @@ -2189,7 +2246,7 @@ static void ali_ac97_set(struct ac97_codec *codec, u8 reg, u16 val) mask = ALI_AC97_WRITE_ACTION | ALI_AC97_AUDIO_BUSY; if (codec->id) mask |= ALI_AC97_SECONDARY; - if (card->revision == 0x02) + if (card->revision == ALI_5451_V02) mask |= ALI_AC97_WRITE_MIXER_REGISTER; spin_lock_irqsave(&card->lock, flags); @@ -2209,7 +2266,7 @@ static void ali_ac97_set(struct ac97_codec *codec, u8 reg, u16 val) spin_unlock_irqrestore(&card->lock, flags); return; //success } - inw(TRID_REG(card, address)); //wait a read cycle + inw(TRID_REG(card, address)); //wait for a read cycle } printk(KERN_ERR "ali: AC97 CODEC write timed out.\n"); @@ -2229,7 +2286,7 @@ static u16 ali_ac97_get(struct ac97_codec *codec, u8 reg) u32 data; address = ALI_AC97_READ; - if (card->revision == 0x02) { + if (card->revision == ALI_5451_V02) { address = ALI_AC97_WRITE; mask &= ALI_AC97_READ_MIXER_REGISTER; } @@ -2267,6 +2324,586 @@ static u16 ali_ac97_get(struct ac97_codec *codec, u8 reg) return 0; } +static void ali_enable_special_channel(struct trident_state *stat) +{ + struct trident_card *card = stat->card; + unsigned long s_channels; + + s_channels = inl(TRID_REG(card, ALI_GLOBAL_CONTROL)); + s_channels |= (1<<stat->dmabuf.channel->num); + outl(s_channels, TRID_REG(card, ALI_GLOBAL_CONTROL)); +} + +/* +flag: ALI_SPDIF_OUT_TO_SPDIF_OUT + ALI_PCM_TO_SPDIF_OUT +*/ +static void ali_setup_spdif_out(struct trident_card *card, int flag) +{ + unsigned long spdif; + unsigned char ch; + + ch = inb(TRID_REG(card, ALI_SCTRL)); + outb(ch | ALI_SPDIF_OUT_ENABLE, TRID_REG(card, ALI_SCTRL)); + ch = inb(TRID_REG(card, ALI_SPDIF_CTRL)); + outb(ch & ALI_SPDIF_OUT_CH_STATUS, TRID_REG(card, ALI_SPDIF_CTRL)); + + if (flag & ALI_SPDIF_OUT_TO_SPDIF_OUT) { + spdif = inw(TRID_REG(card, ALI_GLOBAL_CONTROL)); + spdif |= ALI_SPDIF_OUT_CH_ENABLE; + spdif &= ALI_SPDIF_OUT_SEL_SPDIF; + outw(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL)); + spdif = inw(TRID_REG(card, ALI_SPDIF_CS)); + if (flag & ALI_SPDIF_OUT_NON_PCM) + spdif |= 0x0002; + else spdif &= (~0x0002); + outw(spdif, TRID_REG(card, ALI_SPDIF_CS)); + } + else { + spdif = inw(TRID_REG(card, ALI_GLOBAL_CONTROL)); + spdif |= ALI_SPDIF_OUT_SEL_PCM; + outw(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL)); + } +} + +static void ali_disable_special_channel(struct trident_card *card, int ch) +{ + unsigned long sc; + + sc = inl(TRID_REG(card, ALI_GLOBAL_CONTROL)); + sc &= ~(1 << ch); + outl(sc, TRID_REG(card, ALI_GLOBAL_CONTROL)); +} + +static void ali_disable_spdif_in(struct trident_card *card) +{ + unsigned long spdif; + + spdif = inl(TRID_REG(card, ALI_GLOBAL_CONTROL)); + spdif &= (~ALI_SPDIF_IN_SUPPORT); + outl(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL)); + + ali_disable_special_channel(card, ALI_SPDIF_IN_CHANNEL); +} + +static void ali_setup_spdif_in(struct trident_card *card) +{ + unsigned long spdif; + + //Set SPDIF IN Supported + spdif = inl(TRID_REG(card, ALI_GLOBAL_CONTROL)); + spdif |= ALI_SPDIF_IN_SUPPORT; + outl(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL)); + + spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL)); + spdif |= ALI_SPDIF_IN_CH_STATUS; + outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL)); + + //Set SPDIF IN Rec + spdif = inl(TRID_REG(card, ALI_GLOBAL_CONTROL)); + spdif |= ALI_SPDIF_IN_CH_ENABLE; + outl(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL)); + + spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL)); + spdif |= ALI_SPDIF_IN_FUNC_ENABLE; + outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL)); +} + +static unsigned int ali_get_spdif_in_rate(struct trident_card *card) +{ + unsigned long spdif, time1, time2; + unsigned count1, count2, count3; + unsigned char R1, R2 = 0; + + outb(0xAA, TRID_REG(card, ALI_SPDIF_CTRL + 1)); + count1 = 0xFFFF; + while(--count1) + { + count2 = 0xffff; + do{ + count3 = 0xffff; + time1 = inl(TRID_REG(card, ALI_STIMER)); + + do{ + time2 = inl(TRID_REG(card, ALI_STIMER)); + }while((count3--) && (time2 <= (time1 + 5))); + if (!count3) { + printk("ali: STimer is stopped! Error!\n"); + return FALSE; + } + R1 = inb(TRID_REG(card, ALI_SPDIF_CTRL + 1)); + }while((count2--) && (!((R1 == 0x0B)||(R1 == 0x0C)||(R1 == 0x0D)||(R1 == 0x0E)||(R1 == 0x12)))); + if (!count2) + continue; + + count2 = 0xffff; + time1 = inl(TRID_REG(card, ALI_STIMER)); + do{ + time2 = inl(TRID_REG(card, ALI_STIMER)); + }while((count2--) && (time2 <= (time1 + 5))); + if (!count2) + continue; + + R2 = inb(TRID_REG(card, ALI_SPDIF_CTRL + 1)); + count2 = 0xffff; + while((--count2) && (R2 != R1)) + { + R1 = R2; + count3 = 0xffff; + time1 = inl(TRID_REG(card, ALI_STIMER)); + do{ + time2 = inl(TRID_REG(card, ALI_STIMER)); + }while((count3--) && (time2 <= (time1 + 5))); + if (!count3) { + printk("ali: STimer is stopped! Error!\n"); + return FALSE; + } + R2 = inb(TRID_REG(card, ALI_SPDIF_CTRL + 1)); + } + if(R2 == R1) + break; + } + + if(!count1) { + printk("ali: Can not Detect the sample rate from SPDIF IN!\n"); + return FALSE; + } + + spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL)) | ALI_SPDIF_IN_CH_STATUS; + outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL)); + + /* SPDIF only supprts 48k, 44.1k, 32k */ + switch(R2) { + case 0x12: + outw(0x0E08, TRID_REG(card, ALI_SPDIF_CTRL + 2)); + return 32000; + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + default: + outw(0x0905, TRID_REG(card, ALI_SPDIF_CTRL + 2)); + break; + } + + spdif = inb(TRID_REG(card, ALI_SPDIF_CS + 3)) & 0xf; + if (spdif == 0) + return 44100; + else return 48000; +} + +static int ali_setup_multi_channels(struct trident_card *card, int chan_nums) +{ + unsigned long dwValue; + if (chan_nums == 6) { + dwValue = inl(TRID_REG(card, ALI_SCTRL)) | 0x000f0000; + outl(dwValue, TRID_REG(card, ALI_SCTRL)); + dwValue = inl(TRID_REG(card, ALI_GLOBAL_CONTROL)) | 0x07800000; + outl(dwValue, TRID_REG(card, ALI_GLOBAL_CONTROL)); + } + return 1; +} + +static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel) +{ + int bank; + + if (channel > 31) + return; + + bank = channel >> 5; + channel = channel & 0x1f; + + card->banks[bank].bitmap &= ~(1 << (channel)); +} + +static int ali_allocate_multi_channels(struct trident_state *state, int chan_nums) +{ + struct trident_card *card = state->card; + struct trident_state *s; + int i, state_count = 0; + struct trident_pcm_bank *bank; + struct trident_channel *channel; + + bank = &card->banks[BANK_A]; + + if (chan_nums == 6) { + for(i = 0;(i < ALI_CHANNELS) && (state_count != 4); i++) { + if (!card->states[i]) { + if (!(bank->bitmap & (1 << ali_multi_channels[state_count]))) { + bank->bitmap |= (1 << ali_multi_channels[state_count]); + channel = &bank->channels[ali_multi_channels[state_count]]; + channel->num = ali_multi_channels[state_count]; + } + else { + state_count--; + for (; state_count >= 0; state_count--) { + kfree(state->other_states[state_count]); + ali_free_pcm_channel(card, ali_multi_channels[state_count]); + } + return -EBUSY; + } + s = card->states[i] = (struct trident_state *) + kmalloc(sizeof(struct trident_state), GFP_KERNEL); + if (!s) { + ali_free_pcm_channel(card, ali_multi_channels[state_count]); + state_count--; + for (; state_count >= 0; state_count--) { + ali_free_pcm_channel(card, ali_multi_channels[state_count]); + kfree(state->other_states[state_count]); + } + return -ENOMEM; + } + memset(s, 0, sizeof(struct trident_state)); + + s->dmabuf.channel = channel; + s->dmabuf.ossfragshift = s->dmabuf.ossmaxfrags = s->dmabuf.subdivision = 0; + init_waitqueue_head(&s->dmabuf.wait); + s->magic = card->magic; + s->card = card; + s->virt = i; + + state->other_states[state_count++] = s; + } + } + + if (state_count != 4) { + state_count--; + for (; state_count >= 0; state_count--) { + kfree(state->other_states[state_count]); + ali_free_pcm_channel(card, ali_multi_channels[state_count]); + } + return -EBUSY; + } + } + return 0; +} + +static void ali_save_regs(struct trident_card *card) +{ + unsigned long flags; + int i, j; + + save_flags(flags); + cli(); + + ali_registers.global_regs[0x2c] = inl(TRID_REG(card,T4D_MISCINT)); + //ali_registers.global_regs[0x20] = inl(TRID_REG(card,T4D_START_A)); + ali_registers.global_regs[0x21] = inl(TRID_REG(card,T4D_STOP_A)); + + //disable all IRQ bits + outl(ALI_DISABLE_ALL_IRQ, TRID_REG(card, T4D_MISCINT)); + + for (i = 1; i < ALI_MIXER_REGS; i++) + ali_registers.mixer_regs[i] = ali_ac97_get (card->ac97_codec[0], i*2); + + for (i = 0; i < ALI_GLOBAL_REGS; i++) + { + if ((i*4 == T4D_MISCINT) || (i*4 == T4D_STOP_A)) + continue; + ali_registers.global_regs[i] = inl(TRID_REG(card, i*4)); + } + + for (i = 0; i < ALI_CHANNELS; i++) + { + outb(i,TRID_REG(card, T4D_LFO_GC_CIR)); + for (j = 0; j < ALI_CHANNEL_REGS; j++) + ali_registers.channel_regs[i][j] = inl(TRID_REG(card, j*4 + 0xe0)); + } + + //Stop all HW channel + outl(ALI_STOP_ALL_CHANNELS, TRID_REG(card, T4D_STOP_A)); + + restore_flags(flags); +} + +static void ali_restore_regs(struct trident_card *card) +{ + unsigned long flags; + int i, j; + + save_flags(flags); + cli(); + + for (i = 1; i < ALI_MIXER_REGS; i++) + ali_ac97_set(card->ac97_codec[0], i*2, ali_registers.mixer_regs[i]); + + for (i = 0; i < ALI_CHANNELS; i++) + { + outb(i,TRID_REG(card, T4D_LFO_GC_CIR)); + for (j = 0; j < ALI_CHANNEL_REGS; j++) + outl(ali_registers.channel_regs[i][j], TRID_REG(card, j*4 + 0xe0)); + } + + for (i = 0; i < ALI_GLOBAL_REGS; i++) + { + if ((i*4 == T4D_MISCINT) || (i*4 == T4D_STOP_A) || (i*4 == T4D_START_A)) + continue; + ali_registers.global_regs[i] = inl(TRID_REG(card, i*4)); + } + + //start HW channel + outl(ali_registers.global_regs[0x20], TRID_REG(card,T4D_START_A)); + //restore IRQ enable bits + outl(ali_registers.global_regs[0x2c], TRID_REG(card,T4D_MISCINT)); + + restore_flags(flags); +} + +static int ali_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) +{ + struct trident_card *card = (struct trident_card *)dev->data; + + if (card) { + switch (rqst) { + case PM_SUSPEND: + ali_save_regs(card); + break; + case PM_RESUME: + ali_restore_regs(card); + break; + } + } + return 0; +} + +static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card) +{ + struct trident_pcm_bank *bank; + int idx; + + bank = &card->banks[BANK_A]; + + if (inl(TRID_REG(card, ALI_GLOBAL_CONTROL)) & (ALI_SPDIF_OUT_CH_ENABLE)) { + idx = ALI_SPDIF_OUT_CHANNEL; + if (!(bank->bitmap & (1 << idx))) { + struct trident_channel *channel = &bank->channels[idx]; + bank->bitmap |= 1 << idx; + channel->num = idx; + return channel; + } + } + + for (idx = ALI_PCM_OUT_CHANNEL_FIRST; idx <= ALI_PCM_OUT_CHANNEL_LAST ; idx++) { + if (!(bank->bitmap & (1 << idx))) { + struct trident_channel *channel = &bank->channels[idx]; + bank->bitmap |= 1 << idx; + channel->num = idx; + return channel; + } + } + + /* no more free channels avaliable */ + printk(KERN_ERR "ali: no more channels available on Bank A.\n"); + return NULL; +} + +static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *card) +{ + struct trident_pcm_bank *bank; + int idx; + + if (inl(TRID_REG(card, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT) + idx = ALI_SPDIF_IN_CHANNEL; + else idx = ALI_PCM_IN_CHANNEL; + + bank = &card->banks[BANK_A]; + + if (!(bank->bitmap & (1 << idx))) { + struct trident_channel *channel = &bank->channels[idx]; + bank->bitmap |= 1 << idx; + channel->num = idx; + return channel; + } + + /* no free recordable channels avaliable */ + printk(KERN_ERR "ali: no recordable channels available on Bank A.\n"); + return NULL; +} + +static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate) +{ + unsigned char ch_st_sel; + unsigned short status_rate; + +#ifdef DEBUG + printk("ali: spdif out rate =%d\n", rate); +#endif + switch(rate) { + case 44100: + status_rate = 0; + break; + case 32000: + status_rate = 0x300; + break; + case 48000: + default: + status_rate = 0x200; + break; + } + + ch_st_sel = inb(TRID_REG(card, ALI_SPDIF_CTRL)) & ALI_SPDIF_OUT_CH_STATUS; //select spdif_out + + ch_st_sel |= 0x80; //select right + outb(ch_st_sel, TRID_REG(card, ALI_SPDIF_CTRL)); + outb(status_rate | 0x20, TRID_REG(card, ALI_SPDIF_CS + 2)); + + ch_st_sel &= (~0x80); //select left + outb(ch_st_sel, TRID_REG(card, ALI_SPDIF_CTRL)); + outw(status_rate | 0x10, TRID_REG(card, ALI_SPDIF_CS + 2)); +#ifdef DEBUG + printk("ali: SPDIF_CS=%lxh\n", inl(TRID_REG(card, ALI_SPDIF_CS))); +#endif +} + +static void ali_address_interrupt(struct trident_card *card) +{ + int i, channel; + struct trident_state *state; + u32 mask, channel_mask; + + mask = trident_get_interrupt_mask (card, 0); + for (i = 0; i < NR_HW_CH; i++) { + if ((state = card->states[i]) == NULL) + continue; + channel = state->dmabuf.channel->num; + if ((channel_mask = 1 << channel) & mask) { + mask &= ~channel_mask; + trident_ack_channel_interrupt(card, channel); + state->dmabuf.update_flag |= ALI_ADDRESS_INT_UPDATE; + trident_update_ptr(state); + } + } + if (mask) { + for (i = 0; i < NR_HW_CH; i++) { + if (mask & (1 << i)) { + printk("ali: spurious channel irq %d.\n", i); + trident_ack_channel_interrupt(card, i); + trident_stop_voice(card, i); + trident_disable_voice_irq(card, i); + } + } + } +} + +/* Updating the values of counters of other_states' DMAs without lock +protection is no harm because all DMAs of multi-channels and interrupt +depend on a master state's DMA, and changing the counters of the master +state DMA is protected by a spinlock. +*/ +static unsigned int ali_write_5_1(struct trident_state *state, const char *buf, int cnt_for_multi_channel) +{ + + struct dmabuf *dmabuf = &state->dmabuf; + struct dmabuf *dmabuf_temp; + const char *buffer = buf; + unsigned swptr, other_dma_nums, sample_s; + unsigned int i, loop, state_cnt = 0; + + other_dma_nums = 4; + sample_s = sample_size[dmabuf->fmt] >> 1; + swptr = dmabuf->swptr; + + if ((i = state->multi_channels_adjust_count) > 0) { + if (i == 1) { + copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s); + seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s); + i--; + state_cnt += sample_s; + state->multi_channels_adjust_count++; + } + else i = i - (state->chans_num - other_dma_nums); + for (; (i < other_dma_nums) && (cnt_for_multi_channel > 0); i++) { + dmabuf_temp = &state->other_states[i]->dmabuf; + copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s); + seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s); + } + if (cnt_for_multi_channel == 0) + state->multi_channels_adjust_count += i; + } + if (cnt_for_multi_channel > 0) { + loop = cnt_for_multi_channel / (state->chans_num * sample_s); + for (i = 0; i < loop; i++) { + copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s * 2); + seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s * 2); + + dmabuf_temp = &state->other_states[0]->dmabuf; + copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s); + seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s); + + dmabuf_temp = &state->other_states[1]->dmabuf; + copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s); + seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s); + + dmabuf_temp = &state->other_states[2]->dmabuf; + copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s); + seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s); + + dmabuf_temp = &state->other_states[3]->dmabuf; + copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s); + seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s); + } + + state_cnt += (sample_s * 2 * loop); + + if (cnt_for_multi_channel > 0) { + state->multi_channels_adjust_count = cnt_for_multi_channel / sample_s; + + copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s); + seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s); + state_cnt += sample_s; + + if (cnt_for_multi_channel > 0) { + copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s); + seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s); + state_cnt += sample_s; + + if (cnt_for_multi_channel > 0) { + loop = state->multi_channels_adjust_count - (state->chans_num - other_dma_nums); + for (i = 0; i < loop; i++) { + dmabuf_temp = &state->other_states[i]->dmabuf; + copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s); + seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s); + } + } + } + } + else + state->multi_channels_adjust_count = 0; + } + for (i = 0; i < other_dma_nums; i++) { + dmabuf_temp = &state->other_states[i]->dmabuf; + dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize; + } + return state_cnt; +} + +#ifdef CONFIG_PROC_FS +struct proc_dir_entry *res = NULL; +static int ali_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + struct trident_card *card = (struct trident_card *)data; + unsigned long flags; + + spin_lock_irqsave(&card->lock, flags); + if (*buffer == '0') { //default + ali_setup_spdif_out(card, ALI_PCM_TO_SPDIF_OUT); + ali_disable_special_channel(card, ALI_SPDIF_OUT_CHANNEL); + } + else if (*buffer == '1') + ali_setup_spdif_out(card, ALI_SPDIF_OUT_TO_SPDIF_OUT|ALI_SPDIF_OUT_PCM); + else if (*buffer == '2') //AC3 data + ali_setup_spdif_out(card, ALI_SPDIF_OUT_TO_SPDIF_OUT|ALI_SPDIF_OUT_NON_PCM); + else if (*buffer == '3') + ali_disable_spdif_in(card); //default + else if (*buffer == '4') + ali_setup_spdif_in(card); + spin_unlock_irqrestore(&card->lock, flags); + + return count; +} +#endif + /* OSS /dev/mixer file operation methods */ static int trident_open_mixdev(struct inode *inode, struct file *file) { @@ -2309,7 +2946,7 @@ static /*const*/ struct file_operations trident_mixer_fops = { static int __init trident_ac97_init(struct trident_card *card) { int num_ac97 = 0; - int ready_2nd = 0; + unsigned long ready_2nd = 0; struct ac97_codec *codec; /* initialize controller side of AC link, and find out if secondary codes @@ -2317,8 +2954,9 @@ static int __init trident_ac97_init(struct trident_card *card) switch (card->pci_id) { case PCI_DEVICE_ID_ALI_5451: - outl(PCMOUT|SECONDARY_ID, TRID_REG(card, SI_SERIAL_INTF_CTRL)); - ready_2nd = inl(TRID_REG(card, SI_SERIAL_INTF_CTRL)); + ready_2nd = inl(TRID_REG(card, ALI_SCTRL)); + outl(ready_2nd | PCMOUT | SECONDARY_ID, TRID_REG(card, ALI_SCTRL)); + ready_2nd = inl(TRID_REG(card, ALI_SCTRL)); ready_2nd &= SI_AC97_SECONDARY_READY; break; case PCI_DEVICE_ID_SI_7018: @@ -2435,10 +3073,32 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device card_names[pci_id->driver_data], card->iobase, card->irq); if(card->pci_id == PCI_DEVICE_ID_ALI_5451) { + /* ALi Power Management */ + struct pm_dev *pmdev; + + pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pci_dev), + ali_pm_callback); + if (pmdev) + pmdev->data = card; + + /* ALi channel Management */ card->alloc_pcm_channel = ali_alloc_pcm_channel; card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel; card->free_pcm_channel = ali_free_pcm_channel; + card->address_interrupt = ali_address_interrupt; + + /* ALi SPDIF OUT function */ + if(card->revision == ALI_5451_V02) { + ali_setup_spdif_out(card, ALI_PCM_TO_SPDIF_OUT); +#ifdef CONFIG_PROC_FS + res = create_proc_entry("ALi5451", 0, NULL); + if (res) { + res->write_proc = ali_write_proc; + res->data = card; + } +#endif + } } else { card->alloc_pcm_channel = trident_alloc_pcm_channel; @@ -2477,9 +3137,9 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device if (card->pci_id == PCI_DEVICE_ID_ALI_5451) { /* edited by HMSEO for GT sound */ #ifdef CONFIG_ALPHA_NAUTILUS - u16 ac97_data = trident_ac97_get (card->ac97_codec[0], AC97_POWER_CONTROL); - trident_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL, - ac97_data | ALI_EAPD_POWER_DOWN); + u16 ac97_data; + ac97_data = ali_ac97_get (card->ac97_codec[0], AC97_POWER_CONTROL); + ali_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL, ac97_data | ALI_EAPD_POWER_DOWN); #endif /* edited by HMSEO for GT sound*/ } @@ -2498,6 +3158,17 @@ static void __exit trident_remove(struct pci_dev *pci_dev) int i; struct trident_card *card = pci_get_drvdata(pci_dev); + /* ALi S/PDIF and Power Management */ + if(card->pci_id == PCI_DEVICE_ID_ALI_5451) { + ali_setup_spdif_out(card, ALI_PCM_TO_SPDIF_OUT); + ali_disable_special_channel(card, ALI_SPDIF_OUT_CHANNEL); + ali_disable_spdif_in(card); +#ifdef CONFIG_PROC_FS + remove_proc_entry("ALi5451", NULL); +#endif + pm_unregister_all(ali_pm_callback); + } + /* Kill interrupts, and SP/DIF */ trident_disable_loop_interrupts(card); diff --git a/drivers/sound/trident.h b/drivers/sound/trident.h index a35563622..094910137 100644 --- a/drivers/sound/trident.h +++ b/drivers/sound/trident.h @@ -52,6 +52,10 @@ #define PCI_DEVICE_ID_ALI_5451 0x5451 #endif +#ifndef PCI_DEVICE_ID_ALI_1533 +#define PCI_DEVICE_ID_ALI_1533 0x1533 +#endif + #ifndef FALSE #define FALSE 0 #define TRUE 1 @@ -90,22 +94,65 @@ enum trident_op_registers { }; enum ali_op_registers { + ALI_SCTRL = 0x48, ALI_GLOBAL_CONTROL = 0xd4, - ALI_STIMER = 0xc8 + ALI_STIMER = 0xc8, + ALI_SPDIF_CS = 0x70, + ALI_SPDIF_CTRL = 0x74 +}; + +enum ali_registers_number { + ALI_GLOBAL_REGS = 56, + ALI_CHANNEL_REGS = 8, + ALI_MIXER_REGS = 20 +}; + +enum ali_sctrl_control_bit { + ALI_SPDIF_OUT_ENABLE = 0x20 }; enum ali_global_control_bit { + ALI_SPDIF_OUT_SEL_PCM = 0x00000400, + ALI_SPDIF_IN_SUPPORT = 0x00000800, + ALI_SPDIF_OUT_CH_ENABLE = 0x00008000, + ALI_SPDIF_IN_CH_ENABLE = 0x00080000, + ALI_PCM_IN_DISABLE = 0x7fffffff, ALI_PCM_IN_ENABLE = 0x80000000, - ALI_PCM_IN_DISABLE = 0x7fffffff + ALI_SPDIF_IN_CH_DISABLE = 0xfff7ffff, + ALI_SPDIF_OUT_CH_DISABLE = 0xffff7fff, + ALI_SPDIF_OUT_SEL_SPDIF = 0xfffffbff + +}; + +enum ali_spdif_control_bit { + ALI_SPDIF_IN_FUNC_ENABLE = 0x02, + ALI_SPDIF_IN_CH_STATUS = 0x40, + ALI_SPDIF_OUT_CH_STATUS = 0xbf + +}; + +enum ali_control_all { + ALI_DISABLE_ALL_IRQ = 0, + ALI_CHANNELS = 32, + ALI_STOP_ALL_CHANNELS = 0xffffffff, + ALI_MULTI_CHANNELS_START_STOP = 0x07800000 + }; enum ali_pcm_in_channel_num { + ALI_NORMAL_CHANNEL = 0, + ALI_SPDIF_OUT_CHANNEL = 15, + ALI_SPDIF_IN_CHANNEL = 19, + ALI_LEF_CHANNEL = 23, + ALI_CENTER_CHANNEL = 24, + ALI_SURR_RIGHT_CHANNEL = 25, + ALI_SURR_LEFT_CHANNEL = 26, ALI_PCM_IN_CHANNEL = 31 }; enum ali_pcm_out_channel_num { - ALI_PCM_OUT_CHANNEL_FIRST = 1, - ALI_PCM_OUT_CHANNEL_LAST = 30 + ALI_PCM_OUT_CHANNEL_FIRST = 0, + ALI_PCM_OUT_CHANNEL_LAST = 31 }; enum ali_ac97_power_control_bit { @@ -116,6 +163,17 @@ enum ali_update_ptr_flags { ALI_ADDRESS_INT_UPDATE = 0x01 }; +enum ali_revision { + ALI_5451_V02 = 0x02 +}; + +enum ali_spdif_out_control { + ALI_PCM_TO_SPDIF_OUT = 0, + ALI_SPDIF_OUT_TO_SPDIF_OUT = 1, + ALI_SPDIF_OUT_PCM = 0, + ALI_SPDIF_OUT_NON_PCM = 2 +}; + /* S/PDIF Operational Registers for 4D-NX */ enum nx_spdif_registers { NX_SPCTRL_SPCSO = 0x24, NX_SPLBA = 0x28, @@ -259,7 +317,6 @@ enum miscint_bits { #define VALIDATE_STATE(a) VALIDATE_MAGIC(a,TRIDENT_STATE_MAGIC) #define VALIDATE_CARD(a) VALIDATE_MAGIC(a,TRIDENT_CARD_MAGIC) - extern __inline__ unsigned ld2(unsigned int x) { unsigned r = 0; diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c index a58b333fd..7470ffb03 100644 --- a/drivers/sound/via82cxxx_audio.c +++ b/drivers/sound/via82cxxx_audio.c @@ -13,15 +13,16 @@ * http://gtf.org/garzik/drivers/via82cxxx/ * */ - -#define VIA_VERSION "1.1.8" + +#define VIA_VERSION "1.1.14" #include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> +#include <linux/mm.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/proc_fs.h> @@ -31,10 +32,13 @@ #include <linux/soundcard.h> #include <linux/ac97_codec.h> #include <linux/smp_lock.h> +#include <linux/ioport.h> +#include <linux/wrapper.h> #include <asm/io.h> #include <asm/delay.h> #include <asm/uaccess.h> #include <asm/hardirq.h> +#include <asm/semaphore.h> #undef VIA_DEBUG /* define to enable debugging output and checks */ @@ -45,7 +49,7 @@ #define DPRINTK(fmt, args...) #endif -#define VIA_NDEBUG /* define to disable lightweight runtime checks */ +#undef VIA_NDEBUG /* define to disable lightweight runtime checks */ #ifdef VIA_NDEBUG #define assert(expr) #else @@ -56,20 +60,15 @@ } #endif -/* user switch: undefine to exclude /proc data */ +#if defined(CONFIG_PROC_FS) && \ + defined(CONFIG_SOUND_VIA82CXXX_PROCFS) #define VIA_PROC_FS 1 - -/* don't mess with this */ -#ifndef CONFIG_PROC_FS -#undef VIA_PROC_FS #endif -#define arraysize(x) (sizeof(x)/sizeof(*(x))) +#define VIA_SUPPORT_MMAP 1 /* buggy, for now... */ #define MAX_CARDS 1 -#define LINE_SIZE 10 - #define VIA_CARD_NAME "VIA 82Cxxx Audio driver " VIA_VERSION #define VIA_MODULE_NAME "via82cxxx" #define PFX VIA_MODULE_NAME ": " @@ -80,6 +79,10 @@ #define VIA_DMA_BUFFERS 16 #define VIA_DMA_BUF_SIZE PAGE_SIZE +#ifndef AC97_PCM_LR_ADC_RATE +# define AC97_PCM_LR_ADC_RATE AC97_PCM_LR_DAC_RATE +#endif + /* 82C686 function 5 (audio codec) PCI configuration registers */ #define VIA_ACLINK_CTRL 0x41 #define VIA_FUNC_ENABLE 0x42 @@ -121,6 +124,10 @@ #define VIA_BASE0_AC97_CTRL 0x80 #define VIA_BASE0_SGD_STATUS_SHADOW 0x84 #define VIA_BASE0_GPI_INT_ENABLE 0x8C +#define VIA_INTR_OUT ((1<<0) | (1<<4) | (1<<8)) +#define VIA_INTR_IN ((1<<1) | (1<<5) | (1<<9)) +#define VIA_INTR_FM ((1<<2) | (1<<6) | (1<<10)) +#define VIA_INTR_MASK (VIA_INTR_OUT | VIA_INTR_IN | VIA_INTR_FM) /* VIA_BASE0_AUDIO_xxx_CHAN_TYPE bits */ #define VIA_IRQ_ON_FLAG (1<<0) /* int on each flagged scatter block */ @@ -130,11 +137,10 @@ #define VIA_INT_SEL_ONE_LINE_LEFT (1<<3) /* int at less than one line to send */ #define VIA_PCM_FMT_STEREO (1<<4) /* PCM stereo format (bit clear == mono) */ #define VIA_PCM_FMT_16BIT (1<<5) /* PCM 16-bit format (bit clear == 8-bit) */ -#define VIA_PCM_FIFO (1<<6) /* enable FIFO? documented as "reserved" */ +#define VIA_PCM_REC_FIFO (1<<6) /* PCM Recording FIFO */ #define VIA_RESTART_SGD_ON_EOL (1<<7) /* restart scatter-gather at EOL */ #define VIA_PCM_FMT_MASK (VIA_PCM_FMT_STEREO|VIA_PCM_FMT_16BIT) #define VIA_CHAN_TYPE_MASK (VIA_RESTART_SGD_ON_EOL | \ - VIA_PCM_FIFO | \ VIA_IRQ_ON_FLAG | \ VIA_IRQ_ON_EOL) #define VIA_CHAN_TYPE_INT_SELECT (VIA_INT_SEL_LAST_SAMPLE_SENT) @@ -191,25 +197,24 @@ #define VIA_CR80_WRITE_MODE 0 #define VIA_CR80_REG_IDX(idx) ((((idx) & 0xFF) >> 1) << 16) -/* h r puff n stuff */ -#define VIA_FMT_STEREO 0x01 -#define VIA_FMT_16BIT 0x02 -#define VIA_FMT_MASK 0x03 -#define VIA_DAC_SHIFT 0 -#define VIA_ADC_SHIFT 4 - -/* undocumented(?) values for setting rate, from Via's source */ -#define VIA_SET_RATE_IN 0x00320000 /* set input rate */ -#define VIA_SET_RATE_OUT 0x002c0000 /* set output rate */ - +/* capabilities we announce */ +#ifdef VIA_SUPPORT_MMAP +#define VIA_DSP_CAP (DSP_CAP_REVISION | DSP_CAP_DUPLEX | DSP_CAP_MMAP | \ + DSP_CAP_TRIGGER | DSP_CAP_REALTIME) +#else +#define VIA_DSP_CAP (DSP_CAP_REVISION | DSP_CAP_DUPLEX | \ + DSP_CAP_TRIGGER | DSP_CAP_REALTIME) +#endif /* scatter-gather DMA table entry, exactly as passed to hardware */ struct via_sgd_table { u32 addr; - u32 count; /* includes additional bits also */ + u32 count; /* includes additional VIA_xxx bits also */ }; + #define VIA_EOL (1 << 31) #define VIA_FLAG (1 << 30) +#define VIA_STOP (1 << 29) enum via_channel_states { @@ -220,27 +225,36 @@ enum via_channel_states { struct via_sgd_data { dma_addr_t handle; - volatile void *cpuaddr; + void *cpuaddr; }; struct via_channel { - unsigned rate; /* sample rate */ + atomic_t n_bufs; + atomic_t hw_ptr; + wait_queue_head_t wait; + + unsigned int sw_ptr; + unsigned int slop_len; + unsigned int n_irqs; + int bytes; + unsigned is_active : 1; + unsigned is_record : 1; + unsigned is_mapped : 1; + unsigned is_enabled : 1; u8 pcm_fmt; /* VIA_PCM_FMT_xxx */ - - atomic_t state; - atomic_t buf_in_use; - atomic_t next_buf; - + + unsigned rate; /* sample rate */ + volatile struct via_sgd_table *sgtable; dma_addr_t sgt_handle; - + struct via_sgd_data sgbuf [VIA_DMA_BUFFERS]; - - wait_queue_head_t wait; - + long iobase; + + const char *name; }; @@ -248,20 +262,21 @@ struct via_channel { struct via_info { struct pci_dev *pdev; long baseaddr; - + struct ac97_codec ac97; spinlock_t lock; int card_num; /* unique card number, from 0 */ int dev_dsp; /* /dev/dsp index from register_sound_dsp() */ - + unsigned rev_h : 1; - wait_queue_head_t open_wait; - int open_mode; - + struct semaphore syscall_sem; + struct semaphore open_sem; + struct via_channel ch_in; struct via_channel ch_out; + struct via_channel ch_fm; }; @@ -269,6 +284,7 @@ struct via_info { static unsigned via_num_cards = 0; + /**************************************************************** * * prototypes @@ -285,6 +301,9 @@ static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wa static int via_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static int via_dsp_open (struct inode *inode, struct file *file); static int via_dsp_release(struct inode *inode, struct file *file); +#ifdef VIA_SUPPORT_MMAP +static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma); +#endif static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg); static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value); @@ -292,8 +311,19 @@ static u8 via_ac97_wait_idle (struct via_info *card); static void via_chan_free (struct via_info *card, struct via_channel *chan); static void via_chan_clear (struct via_channel *chan); -static void via_chan_pcm_fmt (struct via_info *card, - struct via_channel *chan, int reset); +static void via_chan_pcm_fmt (struct via_channel *chan, int reset); + +#ifdef VIA_PROC_FS +static int via_init_proc (void); +static void via_cleanup_proc (void); +static int via_card_init_proc (struct via_info *card); +static void via_card_cleanup_proc (struct via_info *card); +#else +static inline int via_init_proc (void) { return 0; } +static inline void via_cleanup_proc (void) {} +static inline int via_card_init_proc (struct via_info *card) { return 0; } +static inline void via_card_cleanup_proc (struct via_info *card) {} +#endif /**************************************************************** @@ -338,7 +368,7 @@ static struct pci_driver via_driver = { * one of three PCM channels supported by the chip. * */ - + static inline void via_chan_stop (int iobase) { if (inb (iobase + VIA_PCM_STATUS) & VIA_SGD_ACTIVE) @@ -359,11 +389,11 @@ static inline void via_chan_stop (int iobase) * one of three PCM channels supported by the chip. * */ - + static inline void via_chan_status_clear (int iobase) { u8 tmp = inb (iobase + VIA_PCM_STATUS); - + if (tmp != 0) outb (tmp, iobase + VIA_PCM_STATUS); } @@ -376,70 +406,43 @@ static inline void via_chan_status_clear (int iobase) * Start scatter-gather DMA for the given channel. * */ - + static inline void sg_begin (struct via_channel *chan) { outb (VIA_SGD_START, chan->iobase + VIA_PCM_CONTROL); } -/** - * via_chan_bufs_in_use - Number of buffers waiting to be consumed - * @chan: Channel for which DMA buffers will be counted - * - * Count the number of buffers waiting to be consumed. For a - * playback operation, this is the number of buffers which have - * yet to be sent to the DAC. For a recording operation, this - * is the number of buffers waiting to be consumed by software - * calling read() system call. +/**************************************************************** * - */ - -static inline int via_chan_bufs_in_use (struct via_channel *chan) -{ - return atomic_read(&chan->next_buf) - - atomic_read(&chan->buf_in_use); -} - - -/** - * via_chan_full - Check for no-free-buffers condition - * @chan: Channel for which DMA full condition will be checked + * Miscellaneous debris * - * Count the number of buffers waiting to be consumed, and return - * true (non-zero) if no buffers are available to be filled on the - * given DMA channel. * */ - -static inline int via_chan_full (struct via_channel *chan) -{ - return (via_chan_bufs_in_use (chan) == VIA_DMA_BUFFERS); -} /** - * via_chan_empty - Check for no-buffers-in-use condition - * @chan: Channel for which DMA empty condition will be checked + * via_syscall_down - down the card-specific syscell semaphore + * @card: Private info for specified board + * @nonblock: boolean, non-zero if O_NONBLOCK is set * - * Count the number of buffers waiting to be consumed, and return - * true (non-zero) if no buffers are currently in use. + * Encapsulates standard method of acquiring the syscall sem. * + * Returns negative errno on error, or zero for success. */ - -static inline int via_chan_empty (struct via_channel *chan) -{ - return (atomic_read(&chan->next_buf) == - atomic_read(&chan->buf_in_use)); -} +static inline int via_syscall_down (struct via_info *card, int nonblock) +{ + if (nonblock) { + if (down_trylock (&card->syscall_sem)) + return -EAGAIN; + } else { + if (down_interruptible (&card->syscall_sem)) + return -ERESTARTSYS; + } -/**************************************************************** - * - * Miscellaneous debris - * - * - */ + return 0; +} /** @@ -469,101 +472,115 @@ static void via_stop_everything (struct via_info *card) via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN); via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_IN_CHAN); via_chan_status_clear (card->baseaddr + VIA_BASE0_FM_OUT_CHAN); - + /* * clear any enabled interrupt bits, reset to 8-bit mono PCM mode */ - outb (0, card->baseaddr + VIA_BASE0_PCM_OUT_CHAN); - outb (0, card->baseaddr + VIA_BASE0_PCM_IN_CHAN); - outb (0, card->baseaddr + VIA_BASE0_FM_OUT_CHAN); + outb (0, card->baseaddr + VIA_BASE0_PCM_OUT_CHAN_TYPE); + outb (0, card->baseaddr + VIA_BASE0_PCM_IN_CHAN_TYPE); + outb (0, card->baseaddr + VIA_BASE0_FM_OUT_CHAN_TYPE); DPRINTK ("EXIT\n"); } /** * via_set_rate - Set PCM rate for given channel - * @card: Private info for specified board + * @ac97: Pointer to generic codec info struct + * @chan: Private info for specified channel * @rate: Desired PCM sample rate, in Khz - * @inhale_deeply: Boolean. If non-zero (true), the recording sample rate - * is set. If zero (false), the playback sample rate - * is set. * * Sets the PCM sample rate for a channel. * * Values for @rate are clamped to a range of 4000 Khz through 48000 Khz, * due to hardware constraints. - * - * FIXME: @inhale_deeply argument is ignored, and %AC97_PCM_FRONT_DAC_RATE - * is the only rate which is really set. This needs to be fixed when - * recording support is added. */ -static int via_set_rate (struct via_info *card, unsigned rate, int inhale_deeply) +static int via_set_rate (struct ac97_codec *ac97, + struct via_channel *chan, unsigned rate) { + int rate_reg; - DPRINTK ("ENTER, rate = %d, inhale = %s\n", - rate, inhale_deeply ? "yes" : "no"); + DPRINTK ("ENTER, rate = %d\n", rate); if (rate > 48000) rate = 48000; if (rate < 4000) rate = 4000; - - via_ac97_write_reg (&card->ac97, AC97_POWER_CONTROL, - (via_ac97_read_reg (&card->ac97, AC97_POWER_CONTROL) & ~0x0200) | + + rate_reg = chan->is_record ? AC97_PCM_LR_ADC_RATE : + AC97_PCM_FRONT_DAC_RATE; + + via_ac97_write_reg (ac97, AC97_POWER_CONTROL, + (via_ac97_read_reg (ac97, AC97_POWER_CONTROL) & ~0x0200) | 0x0200); - via_ac97_write_reg (&card->ac97, AC97_PCM_FRONT_DAC_RATE, rate); - via_ac97_write_reg (&card->ac97, AC97_POWER_CONTROL, - via_ac97_read_reg (&card->ac97, AC97_POWER_CONTROL) & ~0x0200); - DPRINTK ("EXIT, returning 0\n"); - return rate; + via_ac97_write_reg (ac97, rate_reg, rate); + + via_ac97_write_reg (ac97, AC97_POWER_CONTROL, + via_ac97_read_reg (ac97, AC97_POWER_CONTROL) & ~0x0200); + + udelay (10); + + /* the hardware might return a value different than what we + * passed to it, so read the rate value back from hardware + * to see what we came up with + */ + chan->rate = via_ac97_read_reg (ac97, rate_reg); + + DPRINTK ("EXIT, returning rate %d Hz\n", chan->rate); + return chan->rate; } -/** - * via_set_adc_rate - Set PCM rate for recording channel - * @card: Private info for specified board - * @rate: Desired PCM sample rate, in Khz +/**************************************************************** + * + * Channel-specific operations * - * Sets the PCM sample rate for a recording channel. * - * FIXME: @inhale_deeply argument to via_set_rate is ignored, and %AC97_PCM_FRONT_DAC_RATE - * is the only rate which is really set. Thus, this function will - * not work until via_set_rate is fixed. */ -static inline int via_set_adc_rate (struct via_info *card, int rate) -{ - return via_set_rate (card, rate, 1); -} - /** - * via_set_dac_rate - Set PCM rate for playback channel - * @card: Private info for specified board - * @rate: Desired PCM sample rate, in Khz + * via_chan_init_defaults - Initialize a struct via_channel + * @card: Private audio chip info + * @chan: Channel to be initialized * - * Sets the PCM sample rate for a playback channel. + * Zero @chan, and then set all static defaults for the structure. */ -static inline int via_set_dac_rate (struct via_info *card, int rate) +static void via_chan_init_defaults (struct via_info *card, struct via_channel *chan) { - return via_set_rate (card, rate, 0); + memset (chan, 0, sizeof (*chan)); + + if (chan == &card->ch_out) { + chan->name = "PCM-OUT"; + chan->iobase = card->baseaddr + VIA_BASE0_PCM_OUT_CHAN; + } else if (chan == &card->ch_in) { + chan->name = "PCM-IN"; + chan->iobase = card->baseaddr + VIA_BASE0_PCM_IN_CHAN; + chan->is_record = 1; + } else if (chan == &card->ch_fm) { + chan->name = "PCM-OUT-FM"; + chan->iobase = card->baseaddr + VIA_BASE0_FM_OUT_CHAN; + } else { + BUG(); + } + + init_waitqueue_head (&chan->wait); + + chan->pcm_fmt = VIA_PCM_FMT_MASK; + chan->is_enabled = 1; + + if (chan->is_record) + atomic_set (&chan->n_bufs, 0); + else + atomic_set (&chan->n_bufs, VIA_DMA_BUFFERS); + atomic_set (&chan->hw_ptr, 0); } -/**************************************************************** - * - * Channel-specific operations - * - * - */ - /** * via_chan_init - Initialize PCM channel * @card: Private audio chip info * @chan: Channel to be initialized - * @chan_ofs: Offset from PCI address, which determines the - * set of SGD registers to use. * * Performs all the preparations necessary to begin * using a PCM channel. @@ -579,15 +596,14 @@ static inline int via_set_dac_rate (struct via_info *card, int rate) * always "take" the address. */ -static int via_chan_init (struct via_info *card, - struct via_channel *chan, long chan_ofs) +static int via_chan_init (struct via_info *card, struct via_channel *chan) { int i; - unsigned long flags; - + DPRINTK ("ENTER\n"); - memset (chan, 0, sizeof (*chan)); + /* bzero channel structure, and init members to defaults */ + via_chan_init_defaults (card, chan); /* alloc DMA-able memory for scatter-gather table */ chan->sgtable = pci_alloc_consistent (card->pdev, @@ -598,8 +614,8 @@ static int via_chan_init (struct via_info *card, DPRINTK ("EXIT\n"); return -ENOMEM; } - - memset ((void*)chan->sgtable, 0, + + memset ((void*)chan->sgtable, 0, (sizeof (struct via_sgd_table) * VIA_DMA_BUFFERS)); /* alloc DMA-able memory for scatter-gather buffers */ @@ -628,33 +644,26 @@ static int via_chan_init (struct via_info *card, virt_to_phys(chan->sgbuf[i].cpuaddr), chan->sgbuf[i].cpuaddr); #endif - } - - init_waitqueue_head (&chan->wait); - chan->pcm_fmt = VIA_PCM_FMT_MASK; - chan->iobase = card->baseaddr + chan_ofs; - - spin_lock_irqsave (&card->lock, flags); + assert ((VIA_DMA_BUF_SIZE % PAGE_SIZE) == 0); + } /* stop any existing channel output */ via_chan_clear (chan); via_chan_status_clear (chan->iobase); - via_chan_pcm_fmt (card, chan, 1); - - spin_unlock_irqrestore (&card->lock, flags); + via_chan_pcm_fmt (chan, 1); /* set location of DMA-able scatter-gather info table */ DPRINTK("outl (0x%X, 0x%04lX)\n", cpu_to_le32 (chan->sgt_handle), - card->baseaddr + chan_ofs + VIA_PCM_TABLE_ADDR); + chan->iobase + VIA_PCM_TABLE_ADDR); via_ac97_wait_idle (card); outl (cpu_to_le32 (chan->sgt_handle), - card->baseaddr + chan_ofs + VIA_PCM_TABLE_ADDR); + chan->iobase + VIA_PCM_TABLE_ADDR); udelay (20); via_ac97_wait_idle (card); - + DPRINTK("inl (0x%lX) = %x\n", chan->iobase + VIA_PCM_TABLE_ADDR, inl(chan->iobase + VIA_PCM_TABLE_ADDR)); @@ -683,24 +692,23 @@ err_out_nomem: * back to a known state, and releasing any allocated * sound buffers. */ - + static void via_chan_free (struct via_info *card, struct via_channel *chan) { int i; - unsigned long flags; - + DPRINTK ("ENTER\n"); - + synchronize_irq(); - spin_lock_irqsave (&card->lock, flags); + spin_lock_irq (&card->lock); /* stop any existing channel output */ via_chan_stop (chan->iobase); via_chan_status_clear (chan->iobase); - via_chan_pcm_fmt (card, chan, 1); + via_chan_pcm_fmt (chan, 1); - spin_unlock_irqrestore (&card->lock, flags); + spin_unlock_irq (&card->lock); /* zero location of DMA-able scatter-gather info table */ via_ac97_wait_idle(card); @@ -708,15 +716,16 @@ static void via_chan_free (struct via_info *card, struct via_channel *chan) for (i = 0; i < VIA_DMA_BUFFERS; i++) if (chan->sgbuf[i].cpuaddr) { + assert ((VIA_DMA_BUF_SIZE % PAGE_SIZE) == 0); pci_free_consistent (card->pdev, VIA_DMA_BUF_SIZE, - (void*)chan->sgbuf[i].cpuaddr, + chan->sgbuf[i].cpuaddr, chan->sgbuf[i].handle); chan->sgbuf[i].cpuaddr = NULL; chan->sgbuf[i].handle = 0; } if (chan->sgtable) { - pci_free_consistent (card->pdev, + pci_free_consistent (card->pdev, (sizeof (struct via_sgd_table) * VIA_DMA_BUFFERS), (void*)chan->sgtable, chan->sgt_handle); chan->sgtable = NULL; @@ -728,7 +737,6 @@ static void via_chan_free (struct via_info *card, struct via_channel *chan) /** * via_chan_pcm_fmt - Update PCM channel settings - * @card: Private audio chip info * @chan: Channel to be updated * @reset: Boolean. If non-zero, channel will be reset * to 8-bit mono mode. @@ -741,25 +749,26 @@ static void via_chan_free (struct via_info *card, struct via_channel *chan) * is set to the values stored in the channel * information struct @chan. */ - -static void via_chan_pcm_fmt (struct via_info *card, - struct via_channel *chan, int reset) + +static void via_chan_pcm_fmt (struct via_channel *chan, int reset) { DPRINTK ("ENTER, pcm_fmt=0x%02X, reset=%s\n", chan->pcm_fmt, reset ? "yes" : "no"); - assert (card != NULL); assert (chan != NULL); if (reset) /* reset to 8-bit mono mode */ chan->pcm_fmt = 0; - + /* enable interrupts on FLAG and EOL */ chan->pcm_fmt |= VIA_CHAN_TYPE_MASK; - + + /* if we are recording, enable recording fifo bit */ + if (chan->is_record) + chan->pcm_fmt |= VIA_PCM_REC_FIFO; /* set interrupt select bits where applicable (PCM & FM out channels) */ - if (chan == &card->ch_out) + if (!chan->is_record) chan->pcm_fmt |= VIA_CHAN_TYPE_INT_SELECT; outb (chan->pcm_fmt, chan->iobase + 2); @@ -780,10 +789,20 @@ static void via_chan_pcm_fmt (struct via_info *card, static void via_chan_clear (struct via_channel *chan) { + DPRINTK ("ENTER\n"); via_chan_stop (chan->iobase); - atomic_set (&chan->state, sgd_stopped); - atomic_set (&chan->buf_in_use, 0); - atomic_set (&chan->next_buf, 0); + chan->is_active = 0; + chan->is_mapped = 0; + chan->is_enabled = 1; + chan->slop_len = 0; + chan->sw_ptr = 0; + chan->n_irqs = 0; + atomic_set (&chan->hw_ptr, 0); + if (chan->is_record) + atomic_set (&chan->n_bufs, 0); + else + atomic_set (&chan->n_bufs, VIA_DMA_BUFFERS); + DPRINTK ("EXIT\n"); } @@ -809,8 +828,8 @@ static int via_chan_set_speed (struct via_info *card, via_chan_clear (chan); - val = via_set_rate (card, val, chan == &card->ch_in); - + val = via_set_rate (&card->ac97, chan, val); + DPRINTK ("EXIT, returning %d\n", val); return val; } @@ -840,23 +859,30 @@ static int via_chan_set_fmt (struct via_info *card, "unknown"); via_chan_clear (chan); - + + assert (val != AFMT_QUERY); /* this case is handled elsewhere */ + switch (val) { - case AFMT_U8: - chan->pcm_fmt &= ~VIA_PCM_FMT_16BIT; - via_chan_pcm_fmt (card, chan, 0); - break; case AFMT_S16_LE: - chan->pcm_fmt |= VIA_PCM_FMT_16BIT; - via_chan_pcm_fmt (card, chan, 0); + if ((chan->pcm_fmt & VIA_PCM_FMT_16BIT) == 0) { + chan->pcm_fmt |= VIA_PCM_FMT_16BIT; + via_chan_pcm_fmt (chan, 0); + } break; - default: - printk (KERN_WARNING PFX "unknown AFMT\n"); - val = -EINVAL; + + case AFMT_U8: + if (chan->pcm_fmt & VIA_PCM_FMT_16BIT) { + chan->pcm_fmt &= ~VIA_PCM_FMT_16BIT; + via_chan_pcm_fmt (chan, 0); + } break; + + default: + DPRINTK ("unknown AFMT: 0x%X\n", val); + val = AFMT_S16_LE; } - - DPRINTK ("EXIT, returning %d\n", val); + + DPRINTK ("EXIT\n"); return val; } @@ -882,19 +908,19 @@ static int via_chan_set_stereo (struct via_info *card, DPRINTK ("ENTER, channels = %d\n", val); via_chan_clear (chan); - + switch (val) { /* mono */ case 1: chan->pcm_fmt &= ~VIA_PCM_FMT_STEREO; - via_chan_pcm_fmt (card, chan, 0); + via_chan_pcm_fmt (chan, 0); break; /* stereo */ case 2: chan->pcm_fmt |= VIA_PCM_FMT_STEREO; - via_chan_pcm_fmt (card, chan, 0); + via_chan_pcm_fmt (chan, 0); break; /* unknown */ @@ -903,13 +929,13 @@ static int via_chan_set_stereo (struct via_info *card, val = -EINVAL; break; } - + DPRINTK ("EXIT, returning %d\n", val); return val; } -#if 0 +#ifdef VIA_CHAN_DUMP_BUFS /** * via_chan_dump_bufs - Display DMA table contents * @chan: Channel whose DMA table will be displayed @@ -921,7 +947,7 @@ static int via_chan_set_stereo (struct via_info *card, static void via_chan_dump_bufs (struct via_channel *chan) { int i; - + for (i = 0; i < VIA_DMA_BUFFERS; i++) { DPRINTK ("#%02d: addr=%x, count=%u, flag=%d, eol=%d\n", i, chan->sgtable[i].addr, @@ -931,9 +957,55 @@ static void via_chan_dump_bufs (struct via_channel *chan) } DPRINTK ("buf_in_use = %d, nextbuf = %d\n", atomic_read (&chan->buf_in_use), - atomic_read (&chan->next_buf)); + atomic_read (&chan->sw_ptr)); +} +#endif /* VIA_CHAN_DUMP_BUFS */ + + +/** + * via_chan_flush_frag - Flush partially-full playback buffer to hardware + * @chan: Channel whose DMA table will be displayed + * + * Flushes partially-full playback buffer to hardware. + */ + +static void via_chan_flush_frag (struct via_channel *chan) +{ + DPRINTK ("ENTER\n"); + + assert (chan->slop_len > 0); + + if (chan->sw_ptr == (VIA_DMA_BUFFERS - 1)) + chan->sw_ptr = 0; + else + chan->sw_ptr++; + + chan->slop_len = 0; + + assert (atomic_read (&chan->n_bufs) > 0); + atomic_dec (&chan->n_bufs); + + DPRINTK ("EXIT\n"); +} + + + +/** + * via_chan_maybe_start - Initiate audio hardware DMA operation + * @chan: Channel whose DMA is to be started + * + * Initiate DMA operation, if the DMA engine for the given + * channel @chan is not already active. + */ + +static inline void via_chan_maybe_start (struct via_channel *chan) +{ + if (!chan->is_active && chan->is_enabled) { + chan->is_active = 1; + sg_begin (chan); + DPRINTK("starting channel %s\n", chan->name); + } } -#endif /**************************************************************** @@ -942,7 +1014,7 @@ static void via_chan_dump_bufs (struct via_channel *chan) * * */ - + /** * via_ac97_wait_idle - Wait until AC97 codec is not busy * @card: Private info for specified board @@ -956,23 +1028,20 @@ static u8 via_ac97_wait_idle (struct via_info *card) { u8 tmp8; int counter = VIA_COUNTER_LIMIT; - + DPRINTK ("ENTER/EXIT\n"); assert (card != NULL); assert (card->pdev != NULL); - + do { - if (current->need_resched) - schedule (); - else - udelay (10); + udelay (15); - spin_lock_irq (&card->lock); tmp8 = inb (card->baseaddr + 0x83); - spin_unlock_irq (&card->lock); } while ((tmp8 & VIA_CR83_BUSY) && (counter-- > 0)); + if (tmp8 & VIA_CR83_BUSY) + printk (KERN_WARNING PFX "timeout waiting on AC97 codec\n"); return tmp8; } @@ -994,10 +1063,10 @@ static u8 via_ac97_wait_idle (struct via_info *card) static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg) { - u32 data; + unsigned long data; struct via_info *card; int counter; - + DPRINTK ("ENTER\n"); assert (codec != NULL); @@ -1013,26 +1082,25 @@ static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg) for (counter = VIA_COUNTER_LIMIT; counter > 0; counter--) { if (inl (card->baseaddr + 0x80) & VIA_CR80_VALID) goto out; - udelay(10); - if (current->need_resched) - schedule (); + + udelay (15); } - printk (KERN_WARNING PFX "timeout while reading AC97 codec\n"); + printk (KERN_WARNING PFX "timeout while reading AC97 codec (0x%lX)\n", data); goto err_out; out: - data = inl (card->baseaddr + 0x80); + data = (unsigned long) inl (card->baseaddr + 0x80); outb (0x02, card->baseaddr + 0x83); if (((data & 0x007F0000) >> 16) == reg) { - DPRINTK ("EXIT, success, data=0x%x, retval=0x%x\n", + DPRINTK ("EXIT, success, data=0x%lx, retval=0x%lx\n", data, data & 0x0000FFFF); return data & 0x0000FFFF; } - DPRINTK ("WARNING: not our index: reg=0x%x, newreg=0x%x\n", - reg, ((data & 0x007F0000) >> 16)); + printk (KERN_WARNING "via82cxxx_audio: not our index: reg=0x%x, newreg=0x%lx\n", + reg, ((data & 0x007F0000) >> 16)); err_out: DPRINTK ("EXIT, returning 0\n"); @@ -1058,7 +1126,7 @@ static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value) u32 data; struct via_info *card; int counter; - + DPRINTK ("ENTER\n"); assert (codec != NULL); @@ -1068,17 +1136,16 @@ static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value) data = (reg << 16) + value; outl (data, card->baseaddr + VIA_BASE0_AC97_CTRL); - udelay (20); + udelay (10); for (counter = VIA_COUNTER_LIMIT; counter > 0; counter--) { if ((inb (card->baseaddr + 0x83) & VIA_CR83_BUSY) == 0) goto out; - udelay(10); - if (current->need_resched) - schedule (); + + udelay (15); } - - printk (KERN_WARNING PFX "timeout after AC97 codec write\n"); + + printk (KERN_WARNING PFX "timeout after AC97 codec write (0x%X, 0x%X)\n", reg, value); out: DPRINTK ("EXIT\n"); @@ -1091,15 +1158,15 @@ static int via_mixer_open (struct inode *inode, struct file *file) struct via_info *card; struct pci_dev *pdev; struct pci_driver *drvr; - + DPRINTK ("ENTER\n"); pci_for_each_dev(pdev) { drvr = pci_dev_driver (pdev); if (drvr == &via_driver) { - assert (pdev->driver_data != NULL); - - card = pdev->driver_data; + assert (pci_get_drvdata (pdev) != NULL); + + card = pci_get_drvdata (pdev); if (card->ac97.dev_mixer == minor) goto match; } @@ -1119,12 +1186,25 @@ static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int unsigned long arg) { struct ac97_codec *codec = file->private_data; + struct via_info *card; + int nonblock = (file->f_flags & O_NONBLOCK); int rc; + DPRINTK ("ENTER\n"); + assert (codec != NULL); - + card = codec->private_data; + assert (card != NULL); + + rc = via_syscall_down (card, nonblock); + if (rc) goto out; + rc = codec->mixer_ioctl(codec, cmd, arg); - + + up (&card->syscall_sem); + +out: + DPRINTK ("EXIT, returning %d\n", rc); return rc; } @@ -1146,39 +1226,16 @@ static struct file_operations via_mixer_fops = { }; -#if 0 /* values reasoned from debugging dumps of via's driver */ -static struct { - u8 reg; - u16 data; -} mixer_init_vals[] __devinitdata = { - { 0x2, 0x404 }, - { 0x4, 0x404 }, - { 0x6, 0x404 }, - { 0x18, 0x404 }, - { 0x10, 0x404 }, - { 0x1a, 0x404 }, - { 0x1c, 0x404 }, - { 0x1a, 0x404 }, - { 0x1c, 0xc0c }, - { 0x12, 0x808 }, - { 0x10, 0x808 }, - { 0xe, 0x2 }, - { 0x2, 0x808 }, - { 0x18, 0x808 }, -}; -#endif - - static int __init via_ac97_reset (struct via_info *card) { struct pci_dev *pdev = card->pdev; u8 tmp8; u16 tmp16; - + DPRINTK ("ENTER\n"); assert (pdev != NULL); - + #ifndef NDEBUG { u8 r40,r41,r42,r43,r44,r48; @@ -1201,7 +1258,7 @@ static int __init via_ac97_reset (struct via_info *card) inl (card->baseaddr + 0x80), inl (card->baseaddr + 0x84)); spin_unlock_irq (&card->lock); - + } #endif @@ -1212,10 +1269,10 @@ static int __init via_ac97_reset (struct via_info *card) pci_write_config_byte (pdev, VIA_ACLINK_CTRL, VIA_CR41_AC97_ENABLE | VIA_CR41_AC97_RESET | VIA_CR41_AC97_WAKEUP); udelay (100); - + pci_write_config_byte (pdev, VIA_ACLINK_CTRL, 0); udelay (100); - + pci_write_config_byte (pdev, VIA_ACLINK_CTRL, VIA_CR41_AC97_ENABLE | VIA_CR41_PCM_ENABLE | VIA_CR41_VRA | VIA_CR41_AC97_RESET); @@ -1230,45 +1287,50 @@ static int __init via_ac97_reset (struct via_info *card) /* route FM trap to IRQ, disable FM trap */ pci_write_config_byte (pdev, 0x48, 0x05); udelay(10); - + /* disable all codec GPI interrupts */ outl (0, pci_resource_start (pdev, 0) + 0x8C); - /* enable variable rate */ + /* WARNING: this line is magic. Remove this + * and things break. */ + /* enable variable rate, variable rate MIC ADC */ tmp16 = via_ac97_read_reg (&card->ac97, 0x2A); - via_ac97_write_reg (&card->ac97, 0x2A, tmp16 | 0x01); - - /* boost headphone vol if disabled */ - tmp16 = via_ac97_read_reg (&card->ac97, AC97_HEADPHONE_VOL); - if (tmp16 == 0) - via_ac97_write_reg (&card->ac97, AC97_HEADPHONE_VOL, 0x1F1F); - + via_ac97_write_reg (&card->ac97, 0x2A, tmp16 | (1<<0)); + pci_read_config_byte (pdev, VIA_ACLINK_CTRL, &tmp8); if ((tmp8 & (VIA_CR41_AC97_ENABLE | VIA_CR41_AC97_RESET)) == 0) { printk (KERN_ERR PFX "cannot enable AC97 controller, aborting\n"); DPRINTK ("EXIT, tmp8=%X, returning -ENODEV\n", tmp8); return -ENODEV; } - + DPRINTK ("EXIT, returning 0\n"); return 0; } +static void via_ac97_codec_wait (struct ac97_codec *codec) +{ + assert (codec->private_data != NULL); + via_ac97_wait_idle (codec->private_data); +} + + static int __init via_ac97_init (struct via_info *card) { int rc; u16 tmp16; - + DPRINTK ("ENTER\n"); assert (card != NULL); - memset (&card->ac97, 0, sizeof (card->ac97)); + memset (&card->ac97, 0, sizeof (card->ac97)); card->ac97.private_data = card; card->ac97.codec_read = via_ac97_read_reg; card->ac97.codec_write = via_ac97_write_reg; - + card->ac97.codec_wait = via_ac97_codec_wait; + card->ac97.dev_mixer = register_sound_mixer (&via_mixer_fops, -1); if (card->ac97.dev_mixer < 0) { printk (KERN_ERR PFX "unable to register AC97 mixer, aborting\n"); @@ -1288,9 +1350,10 @@ static int __init via_ac97_init (struct via_info *card) goto err_out; } + /* enable variable rate, variable rate MIC ADC */ tmp16 = via_ac97_read_reg (&card->ac97, 0x2A); - via_ac97_write_reg (&card->ac97, 0x2A, tmp16 | 0x01); - + via_ac97_write_reg (&card->ac97, 0x2A, tmp16 | (1<<0)); + DPRINTK ("EXIT, returning 0\n"); return 0; @@ -1304,10 +1367,10 @@ err_out: static void via_ac97_cleanup (struct via_info *card) { DPRINTK("ENTER\n"); - + assert (card != NULL); assert (card->ac97.dev_mixer >= 0); - + unregister_sound_mixer (card->ac97.dev_mixer); DPRINTK("EXIT\n"); @@ -1320,68 +1383,130 @@ static void via_ac97_cleanup (struct via_info *card) * Interrupt-related code * */ - -static inline void via_interrupt_write (struct via_channel *chan) + +/** + * via_intr_channel - handle an interrupt for a single channel + * @chan: handle interrupt for this channel + * + * This is the "meat" of the interrupt handler, + * containing the actions taken each time an interrupt + * occurs. All communication and coordination with + * userspace takes place here. + * + * Locking: inside card->lock + */ + +static void via_intr_channel (struct via_channel *chan) { - assert (atomic_read(&chan->buf_in_use) < - atomic_read(&chan->next_buf)); + u8 status; + int n; - /* XXX sanity check: read h/w counter to - * ensure no lost frames */ + /* check pertinent bits of status register for action bits */ + status = inb (chan->iobase) & (VIA_SGD_FLAG | VIA_SGD_EOL | VIA_SGD_STOPPED); + if (!status) + return; - atomic_inc (&chan->buf_in_use); + /* acknowledge any flagged bits ASAP */ + outb (status, chan->iobase); - /* if SG ptr catches up with userland ptr, stop playback */ - if (atomic_read(&chan->buf_in_use) == atomic_read(&chan->next_buf)) { - atomic_set (&chan->state, sgd_stopped); - via_chan_stop (chan->iobase); + /* grab current h/w ptr value */ + n = atomic_read (&chan->hw_ptr); + + /* sanity check: make sure our h/w ptr doesn't have a weird value */ + assert (n >= 0); + assert (n < VIA_DMA_BUFFERS); + + /* reset SGD data structure in memory to reflect a full buffer, + * and advance the h/w ptr, wrapping around to zero if needed + */ + if (n == (VIA_DMA_BUFFERS - 1)) { + chan->sgtable[n].count = (VIA_DMA_BUF_SIZE | VIA_EOL); + atomic_set (&chan->hw_ptr, 0); + } else { + chan->sgtable[n].count = (VIA_DMA_BUF_SIZE | VIA_FLAG); + atomic_inc (&chan->hw_ptr); } - /* wake up anybody listening */ + /* accounting crap for SNDCTL_DSP_GETxPTR */ + chan->n_irqs++; + chan->bytes += VIA_DMA_BUF_SIZE; + if (chan->bytes < 0) /* handle overflow of 31-bit value */ + chan->bytes = VIA_DMA_BUF_SIZE; + + /* wake up anyone listening to see when interrupts occur */ if (waitqueue_active (&chan->wait)) - wake_up (&chan->wait); -} + wake_up_all (&chan->wait); + + DPRINTK ("%s intr, status=0x%02X, hwptr=0x%lX, chan->hw_ptr=%d\n", + chan->name, status, (long) inl (chan->iobase + 0x04), + atomic_read (&chan->hw_ptr)); + + /* all following checks only occur when not in mmap(2) mode */ + if (chan->is_mapped) + return; + + /* If we are recording, then n_bufs represents the number + * of buffers waiting to be handled by userspace. + * If we are playback, then n_bufs represents the number + * of buffers remaining to be filled by userspace. + * We increment here. If we reach max buffers (VIA_DMA_BUFFERS), + * this indicates an underrun/overrun. For this case under OSS, + * we stop the record/playback process. + */ + if (atomic_read (&chan->n_bufs) < VIA_DMA_BUFFERS) + atomic_inc (&chan->n_bufs); + assert (atomic_read (&chan->n_bufs) <= VIA_DMA_BUFFERS); + + if (atomic_read (&chan->n_bufs) == VIA_DMA_BUFFERS) { + chan->is_active = 0; + via_chan_stop (chan->iobase); + } + DPRINTK ("%s intr, channel n_bufs == %d\n", chan->name, + atomic_read (&chan->n_bufs)); +} static void via_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct via_info *card = dev_id; - struct via_channel *chan; - u8 status; + u32 status32; - status = inb (card->baseaddr + 0x00); - if (status) { - assert (card->open_mode & FMODE_WRITE); - - chan = &card->ch_out; - - if (status & VIA_SGD_FLAG) { - assert ((status & VIA_SGD_EOL) == 0); - outb (VIA_SGD_FLAG, chan->iobase + 0x00); - DPRINTK("FLAG intr, status=0x%02X\n", status); - via_interrupt_write (chan); - } - - if (status & VIA_SGD_EOL) { - assert ((status & VIA_SGD_FLAG) == 0); - outb (VIA_SGD_EOL, chan->iobase + 0x00); - DPRINTK("EOL intr, status=0x%02X\n", status); - via_interrupt_write (chan); - } - - if (status & VIA_SGD_STOPPED) { - outb (VIA_SGD_STOPPED, chan->iobase + 0x00); - DPRINTK("STOPPED intr, status=0x%02X\n", status); - } + /* to minimize interrupt sharing costs, we use the SGD status + * shadow register to check the status of all inputs and + * outputs with a single 32-bit bus read. If no interrupt + * conditions are flagged, we exit immediately + */ + status32 = inl (card->baseaddr + VIA_BASE0_SGD_STATUS_SHADOW); + if (!(status32 & VIA_INTR_MASK)) + return; -#if 0 - via_chan_dump_bufs (&card->ch_out); -#endif - } + DPRINTK ("intr, status32 == 0x%08X\n", status32); + + /* synchronize interrupt handling under SMP. this spinlock + * goes away completely on UP + */ + spin_lock (&card->lock); + + if (status32 & VIA_INTR_OUT) + via_intr_channel (&card->ch_out); + if (status32 & VIA_INTR_IN) + via_intr_channel (&card->ch_in); + if (status32 & VIA_INTR_FM) + via_intr_channel (&card->ch_fm); + + spin_unlock (&card->lock); } +/** + * via_interrupt_disable - Disable all interrupt-generating sources + * @card: Private info for specified board + * + * Disables all interrupt-generation flags in the Via + * audio hardware registers. + */ + static void via_interrupt_disable (struct via_info *card) { u8 tmp8; @@ -1390,7 +1515,7 @@ static void via_interrupt_disable (struct via_info *card) DPRINTK ("ENTER\n"); assert (card != NULL); - + spin_lock_irqsave (&card->lock, flags); pci_read_config_byte (card->pdev, VIA_FM_NMI_CTRL, &tmp8); @@ -1415,13 +1540,22 @@ static void via_interrupt_disable (struct via_info *card) } +/** + * via_interrupt_init - Initialize interrupt handling + * @card: Private info for specified board + * + * Obtain and reserve IRQ for using in handling audio events. + * Also, disable any IRQ-generating resources, to make sure + * we don't get interrupts before we want them. + */ + static int via_interrupt_init (struct via_info *card) { DPRINTK ("ENTER\n"); assert (card != NULL); assert (card->pdev != NULL); - + /* check for sane IRQ number. can this ever happen? */ if (card->pdev->irq < 2) { printk (KERN_ERR PFX "insane IRQ %d, aborting\n", @@ -1429,7 +1563,7 @@ static int via_interrupt_init (struct via_info *card) DPRINTK ("EXIT, returning -EIO\n"); return -EIO; } - + if (request_irq (card->pdev->irq, via_interrupt, SA_SHIRQ, VIA_MODULE_NAME, card)) { printk (KERN_ERR PFX "unable to obtain IRQ %d, aborting\n", card->pdev->irq); @@ -1445,6 +1579,15 @@ static int via_interrupt_init (struct via_info *card) } +/** + * via_interrupt_cleanup - Shutdown driver interrupt handling + * @card: Private info for specified board + * + * Disable any potential interrupt sources in the Via audio + * hardware, and then release (un-reserve) the IRQ line + * in the kernel core. + */ + static void via_interrupt_cleanup (struct via_info *card) { DPRINTK ("ENTER\n"); @@ -1465,7 +1608,7 @@ static void via_interrupt_cleanup (struct via_info *card) * OSS DSP device * */ - + static struct file_operations via_dsp_fops = { owner: THIS_MODULE, open: via_dsp_open, @@ -1475,22 +1618,28 @@ static struct file_operations via_dsp_fops = { poll: via_dsp_poll, llseek: via_llseek, ioctl: via_dsp_ioctl, +#ifdef VIA_SUPPORT_MMAP + mmap: via_dsp_mmap, +#endif }; static int __init via_dsp_init (struct via_info *card) { u8 tmp8; - + DPRINTK ("ENTER\n"); assert (card != NULL); /* turn off legacy features, if not already */ pci_read_config_byte (card->pdev, VIA_FUNC_ENABLE, &tmp8); - tmp8 &= ~(VIA_CR42_SB_ENABLE | VIA_CR42_MIDI_ENABLE | - VIA_CR42_FM_ENABLE); - pci_write_config_byte (card->pdev, VIA_FUNC_ENABLE, tmp8); + if (tmp8 & (VIA_CR42_SB_ENABLE | VIA_CR42_MIDI_ENABLE | + VIA_CR42_FM_ENABLE)) { + tmp8 &= ~(VIA_CR42_SB_ENABLE | VIA_CR42_MIDI_ENABLE | + VIA_CR42_FM_ENABLE); + pci_write_config_byte (card->pdev, VIA_FUNC_ENABLE, tmp8); + } via_stop_everything (card); @@ -1519,232 +1668,413 @@ static void via_dsp_cleanup (struct via_info *card) } +#ifdef VIA_SUPPORT_MMAP +static struct page * via_mm_nopage (struct vm_area_struct * vma, + unsigned long address, int write_access) +{ + struct via_info *card = vma->vm_private_data; + struct via_channel *chan = &card->ch_out; + struct page *dmapage; + unsigned long pgoff; + int rd, wr; + + DPRINTK ("ENTER, start %lXh, ofs %lXh, pgoff %ld, addr %lXh, wr %d\n", + vma->vm_start, + address - vma->vm_start, + (address - vma->vm_start) >> PAGE_SHIFT, + address, + write_access); + + assert (VIA_DMA_BUF_SIZE == PAGE_SIZE); + + if (address > vma->vm_end) { + DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n"); + return NOPAGE_SIGBUS; /* Disallow mremap */ + } + if (!card) { + DPRINTK ("EXIT, returning NOPAGE_OOM\n"); + return NOPAGE_OOM; /* Nothing allocated */ + } + + pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT); + rd = card->ch_in.is_mapped; + wr = card->ch_out.is_mapped; + +#ifndef VIA_NDEBUG + { + unsigned long max_bufs = VIA_DMA_BUFFERS; + if (rd && wr) max_bufs *= 2; + /* via_dsp_mmap() should ensure this */ + assert (pgoff < max_bufs); + } +#endif + + /* if full-duplex (read+write) and we have two sets of bufs, + * then the playback buffers come first, sez soundcard.c */ + if (pgoff >= VIA_DMA_BUFFERS) { + pgoff -= VIA_DMA_BUFFERS; + chan = &card->ch_in; + } else if (!wr) + chan = &card->ch_in; + + assert ((((unsigned long)chan->sgbuf[pgoff].cpuaddr) % PAGE_SIZE) == 0); + + dmapage = virt_to_page (chan->sgbuf[pgoff].cpuaddr); + DPRINTK ("EXIT, returning page %p for cpuaddr %lXh\n", + dmapage, (unsigned long) chan->sgbuf[pgoff].cpuaddr); + get_page (dmapage); + return dmapage; +} + + +#ifndef VM_RESERVE +static int via_mm_swapout (struct page *page, struct file *filp) +{ + return 0; +} +#endif /* VM_RESERVE */ + + +struct vm_operations_struct via_mm_ops = { + nopage: via_mm_nopage, + +#ifndef VM_RESERVE + swapout: via_mm_swapout, +#endif +}; + + +static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct via_info *card; + int nonblock = (file->f_flags & O_NONBLOCK); + int rc = -EINVAL, rd=0, wr=0; + unsigned long max_size, size, start, offset; + + assert (file != NULL); + assert (vma != NULL); + card = file->private_data; + assert (card != NULL); + + DPRINTK ("ENTER, start %lXh, size %ld, pgoff %ld\n", + vma->vm_start, + vma->vm_end - vma->vm_start, + vma->vm_pgoff); + + assert (VIA_DMA_BUF_SIZE == PAGE_SIZE); + + max_size = 0; + if (file->f_mode & FMODE_READ) { + rd = 1; + max_size += (VIA_DMA_BUFFERS * VIA_DMA_BUF_SIZE); + } + if (file->f_mode & FMODE_WRITE) { + wr = 1; + max_size += (VIA_DMA_BUFFERS * VIA_DMA_BUF_SIZE); + } + + start = vma->vm_start; + offset = (vma->vm_pgoff << PAGE_SHIFT); + size = vma->vm_end - vma->vm_start; + + /* some basic size/offset sanity checks */ + if (size > max_size) + goto out; + if (offset > max_size - size) + goto out; + + rc = via_syscall_down (card, nonblock); + if (rc) goto out; + + vma->vm_ops = &via_mm_ops; + vma->vm_private_data = card; + +#ifdef VM_RESERVE + vma->vm_flags |= VM_RESERVE; +#endif + + if (rd) + card->ch_in.is_mapped = 1; + if (wr) + card->ch_out.is_mapped = 1; + + up (&card->syscall_sem); + rc = 0; + +out: + DPRINTK("EXIT, returning %d\n", rc); + return rc; +} +#endif /* VIA_SUPPORT_MMAP */ + + +static ssize_t via_dsp_do_read (struct via_info *card, + char *userbuf, size_t count, + int nonblock) +{ + const char *orig_userbuf = userbuf; + struct via_channel *chan = &card->ch_in; + size_t size; + int n, tmp; + + /* if SGD has not yet been started, start it */ + via_chan_maybe_start (chan); + +handle_one_block: + /* just to be a nice neighbor */ + if (current->need_resched) + schedule (); + + /* grab current channel software pointer. In the case of + * recording, this is pointing to the next buffer that + * will receive data from the audio hardware. + */ + n = chan->sw_ptr; + + /* n_bufs represents the number of buffers waiting + * to be copied to userland. sleep until at least + * one buffer has been read from the audio hardware. + */ + tmp = atomic_read (&chan->n_bufs); + assert (tmp >= 0); + assert (tmp <= VIA_DMA_BUFFERS); + while (tmp == 0) { + if (nonblock || !chan->is_active) + return -EAGAIN; + + DPRINTK ("Sleeping on block %d\n", n); + interruptible_sleep_on (&chan->wait); + + if (signal_pending (current)) + return -ERESTARTSYS; + + tmp = atomic_read (&chan->n_bufs); + } + + /* Now that we have a buffer we can read from, send + * as much as sample data possible to userspace. + */ + while ((count > 0) && (chan->slop_len < VIA_DMA_BUF_SIZE)) { + size_t slop_left = VIA_DMA_BUF_SIZE - chan->slop_len; + + size = (count < slop_left) ? count : slop_left; + if (copy_to_user (userbuf, + chan->sgbuf[n].cpuaddr + chan->slop_len, + size)) + return -EFAULT; + + count -= size; + chan->slop_len += size; + userbuf += size; + } + + /* If we didn't copy the buffer completely to userspace, + * stop now. + */ + if (chan->slop_len < VIA_DMA_BUF_SIZE) + goto out; + + /* + * If we get to this point, we copied one buffer completely + * to userspace, give the buffer back to the hardware. + */ + + /* advance channel software pointer to point to + * the next buffer from which we will copy + */ + if (chan->sw_ptr == (VIA_DMA_BUFFERS - 1)) + chan->sw_ptr = 0; + else + chan->sw_ptr++; + + /* mark one less buffer waiting to be processed */ + assert (atomic_read (&chan->n_bufs) > 0); + atomic_dec (&chan->n_bufs); + + /* we are at a block boundary, there is no fragment data */ + chan->slop_len = 0; + + DPRINTK("Flushed block %u, sw_ptr now %u, n_bufs now %d\n", + n, chan->sw_ptr, atomic_read (&chan->n_bufs)); + + DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", + inb (card->baseaddr + 0x00), + inb (card->baseaddr + 0x01), + inb (card->baseaddr + 0x02), + inl (card->baseaddr + 0x04), + inl (card->baseaddr + 0x0C), + inl (card->baseaddr + 0x80), + inl (card->baseaddr + 0x84)); + + if (count > 0) + goto handle_one_block; + +out: + return userbuf - orig_userbuf; +} + + static ssize_t via_dsp_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct via_info *card; + int nonblock = (file->f_flags & O_NONBLOCK); + int rc; + + DPRINTK ("ENTER, file=%p, buffer=%p, count=%u, ppos=%lu\n", + file, buffer, count, ppos ? ((unsigned long)*ppos) : 0); - DPRINTK ("ENTER\n"); - assert (file != NULL); assert (buffer != NULL); card = file->private_data; assert (card != NULL); - DPRINTK("EXIT, returning -EINVAL\n"); - return -EINVAL; -} + if (ppos != &file->f_pos) { + DPRINTK ("EXIT, returning -ESPIPE\n"); + return -ESPIPE; + } + + rc = via_syscall_down (card, nonblock); + if (rc) goto out; + + if (card->ch_in.is_mapped) { + rc = -ENXIO; + goto out_up; + } + + rc = via_dsp_do_read (card, buffer, count, nonblock); +out_up: + up (&card->syscall_sem); +out: + DPRINTK("EXIT, returning %ld\n",(long) rc); + return rc; +} -#define sgcount(n) (sgtable[(n)].count & 0x00FFFFFF) -#define NEXTBUF (atomic_read(&chan->next_buf) % VIA_DMA_BUFFERS) -#define BUF_IN_USE (atomic_read(&chan->buf_in_use) % VIA_DMA_BUFFERS) -#define STATE_STOPPED (atomic_read (state) == sgd_stopped) -#define STATE_STARTED (atomic_read (state) == sgd_in_progress) static ssize_t via_dsp_do_write (struct via_info *card, const char *userbuf, size_t count, - int non_blocking) + int nonblock) { const char *orig_userbuf = userbuf; struct via_channel *chan = &card->ch_out; volatile struct via_sgd_table *sgtable = chan->sgtable; - atomic_t *state = &chan->state; size_t size; - int nextbuf, prevbuf, n, realcount; - ssize_t rc; - - while (count > 0) { - if (current->need_resched) - schedule (); - - spin_lock_irq (&card->lock); - DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", - inb (card->baseaddr + 0x00), - inb (card->baseaddr + 0x01), - inb (card->baseaddr + 0x02), - inl (card->baseaddr + 0x04), - inl (card->baseaddr + 0x0C), - inl (card->baseaddr + 0x80), - inl (card->baseaddr + 0x84)); - spin_unlock_irq (&card->lock); - - size = (count < VIA_DMA_BUF_SIZE) ? count : VIA_DMA_BUF_SIZE; + int n, tmp; - /* case 1: SGD not active, list is ours for the mangling */ +handle_one_block: + /* just to be a nice neighbor */ + if (current->need_resched) + schedule (); - if (STATE_STOPPED) { - DPRINTK ("case 1\n"); + /* grab current channel software pointer. In the case of + * playback, this is pointing to the next buffer that + * should receive data from userland. + */ + n = chan->sw_ptr; - if (copy_from_user ((void*)chan->sgbuf[0].cpuaddr, - userbuf, size)) - return -EFAULT; + /* n_bufs represents the number of buffers remaining + * to be filled by userspace. Sleep until + * at least one buffer is available for our use. + */ + tmp = atomic_read (&chan->n_bufs); + assert (tmp >= 0); + assert (tmp <= VIA_DMA_BUFFERS); + while (tmp == 0) { + if (nonblock || !chan->is_enabled) + return -EAGAIN; - assert (sgtable[0].addr == cpu_to_le32 (chan->sgbuf[0].handle)); - sgtable[0].count = size | VIA_FLAG; + DPRINTK ("Sleeping on block %d, tmp==%d, ir==%d\n", n, tmp, chan->is_record); + interruptible_sleep_on (&chan->wait); - atomic_set (state, sgd_in_progress); - atomic_set (&chan->buf_in_use, 0); - atomic_set (&chan->next_buf, 1); - - count -= size; - userbuf += size; + if (signal_pending (current)) + return -ERESTARTSYS; - spin_lock_irq (&card->lock); - sg_begin (chan); - spin_unlock_irq (&card->lock); + tmp = atomic_read (&chan->n_bufs); + } - continue; - } + /* Now that we have a buffer we can write to, fill it up + * as much as possible with data from userspace. + */ + while ((count > 0) && (chan->slop_len < VIA_DMA_BUF_SIZE)) { + size_t slop_left = VIA_DMA_BUF_SIZE - chan->slop_len; - nextbuf = NEXTBUF; - if (nextbuf) - prevbuf = nextbuf - 1; - else - prevbuf = VIA_DMA_BUFFERS - 1; - - /* case 2: if final buffer is (a) a fragment, and (b) not - * currently being consumed by the SGD engine, then append - * as much data as possible to the fragment. */ - - realcount = sgcount(prevbuf); - if (STATE_STARTED && (prevbuf != BUF_IN_USE) && - (realcount < VIA_DMA_BUF_SIZE)) { - DPRINTK ("case 2\n"); - DPRINTK ("st=%d, fb=%d -- nb=%d, pb=%d, n=%d, rc=%d\n", - atomic_read (state), - BUF_IN_USE, - nextbuf, - prevbuf, - prevbuf /* n */, - realcount); - - n = prevbuf; - - if ((VIA_DMA_BUF_SIZE - realcount) < size) - size = VIA_DMA_BUF_SIZE - realcount; - - if (copy_from_user ((void*)(chan->sgbuf[n].cpuaddr + - realcount), - userbuf, size)) - return -EFAULT; - - /* slack way to try and prevent races */ - if (prevbuf == BUF_IN_USE || !STATE_STARTED) - continue; - - assert (sgtable[n].addr == cpu_to_le32 (chan->sgbuf[n].handle)); - if (n == (VIA_DMA_BUFFERS - 1)) - sgtable[n].count = (realcount + size) | VIA_EOL; - else - sgtable[n].count = (realcount + size) | VIA_FLAG; + size = (count < slop_left) ? count : slop_left; + if (copy_from_user (chan->sgbuf[n].cpuaddr + chan->slop_len, + userbuf, size)) + return -EFAULT; - count -= size; - userbuf += size; - continue; - } + count -= size; + chan->slop_len += size; + userbuf += size; + } - /* case 3: if there are buffers left, use one - * XXX needs more review for possible races */ + /* If we didn't fill up the buffer with data, stop now. + * Put a 'stop' marker in the DMA table too, to tell the + * audio hardware to stop if it gets here. + */ + if (chan->slop_len < VIA_DMA_BUF_SIZE) { + sgtable[n].count = cpu_to_le32 (chan->slop_len | VIA_EOL | VIA_STOP); + goto out; + } - else if (STATE_STARTED && !via_chan_full (chan)) { - DPRINTK ("case 3\n"); - DPRINTK ("st=%d, fb=%d -- nb=%d, pb=%d, n=%d\n", - atomic_read (state), - BUF_IN_USE, - nextbuf, - prevbuf, - nextbuf /* n */); + /* + * If we get to this point, we have filled a buffer with + * audio data, flush the buffer to audio hardware. + */ - n = nextbuf; + /* Record the true size for the audio hardware to notice */ + if (n == (VIA_DMA_BUFFERS - 1)) + sgtable[n].count = cpu_to_le32 (VIA_DMA_BUF_SIZE | VIA_EOL); + else + sgtable[n].count = cpu_to_le32 (VIA_DMA_BUF_SIZE | VIA_FLAG); - if (copy_from_user ((void*)chan->sgbuf[n].cpuaddr, - userbuf, size)) - return -EFAULT; + /* advance channel software pointer to point to + * the next buffer we will fill with data + */ + if (chan->sw_ptr == (VIA_DMA_BUFFERS - 1)) + chan->sw_ptr = 0; + else + chan->sw_ptr++; - if (n == (VIA_DMA_BUFFERS - 1)) - sgtable[n].count = size | VIA_EOL; - else - sgtable[n].count = size | VIA_FLAG; + /* mark one less buffer as being available for userspace consumption */ + assert (atomic_read (&chan->n_bufs) > 0); + atomic_dec (&chan->n_bufs); - /* if SGD stopped during data copy or SG table update, - * then loop back to the beginning without updating - * any pointers. - * ie. slack way to prevent race */ - if (!STATE_STARTED) - continue; + /* we are at a block boundary, there is no fragment data */ + chan->slop_len = 0; - atomic_inc (&chan->next_buf); + /* if SGD has not yet been started, start it */ + via_chan_maybe_start (chan); - count -= size; - userbuf += size; - continue; - } + DPRINTK("Flushed block %u, sw_ptr now %u, n_bufs now %d\n", + n, chan->sw_ptr, atomic_read (&chan->n_bufs)); - /* case 4, final SGT active case: no free buffers, wait for one */ - - else { - DPRINTK ("case 4\n"); - DPRINTK ("st=%d, fb=%d -- nb=%d, pb=%d\n", - atomic_read (state), - BUF_IN_USE, - nextbuf, - prevbuf); - - /* if playback stopped, no need to sleep */ - if (!STATE_STARTED) - continue; - - /* if buffer free, no need to sleep */ - if (!via_chan_full (chan)) - continue; - - if (non_blocking) { - rc = userbuf - orig_userbuf; - if (rc == 0) - rc = -EAGAIN; - return rc; - } + DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", + inb (card->baseaddr + 0x00), + inb (card->baseaddr + 0x01), + inb (card->baseaddr + 0x02), + inl (card->baseaddr + 0x04), + inl (card->baseaddr + 0x0C), + inl (card->baseaddr + 0x80), + inl (card->baseaddr + 0x84)); - DPRINTK ("sleeping\n"); - interruptible_sleep_on (&chan->wait); - if (signal_pending (current)) - return -ERESTARTSYS; - } - } + if (count > 0) + goto handle_one_block; -#if 0 - { - u8 r40,r41,r42,r43,r44,r48; - pci_read_config_byte (card->pdev, 0x40, &r40); - pci_read_config_byte (card->pdev, 0x41, &r41); - pci_read_config_byte (card->pdev, 0x42, &r42); - pci_read_config_byte (card->pdev, 0x43, &r43); - pci_read_config_byte (card->pdev, 0x44, &r44); - pci_read_config_byte (card->pdev, 0x48, &r48); - DPRINTK("PCI config: %02X %02X %02X %02X %02X %02X\n", - r40,r41,r42,r43,r44,r48); - } -#endif - - DPRINTK ("EXIT, returning %d\n", - userbuf - orig_userbuf); +out: return userbuf - orig_userbuf; } -#undef sgcount -#undef NEXTBUF -#undef BUF_IN_USE -#undef STATE_STOPPED -#undef STATE_STARTED static ssize_t via_dsp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct via_info *card; ssize_t rc; + int nonblock = (file->f_flags & O_NONBLOCK); DPRINTK ("ENTER, file=%p, buffer=%p, count=%u, ppos=%lu\n", file, buffer, count, ppos ? ((unsigned long)*ppos) : 0); - + assert (file != NULL); assert (buffer != NULL); card = file->private_data; @@ -1755,8 +2085,19 @@ static ssize_t via_dsp_write(struct file *file, const char *buffer, size_t count return -ESPIPE; } - rc = via_dsp_do_write (card, buffer, count, (file->f_flags & O_NONBLOCK)); + rc = via_syscall_down (card, nonblock); + if (rc) goto out; + + if (card->ch_out.is_mapped) { + rc = -ENXIO; + goto out_up; + } + + rc = via_dsp_do_write (card, buffer, count, nonblock); +out_up: + up (&card->syscall_sem); +out: DPRINTK("EXIT, returning %ld\n",(long) rc); return rc; } @@ -1765,45 +2106,105 @@ static ssize_t via_dsp_write(struct file *file, const char *buffer, size_t count static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wait) { struct via_info *card; - unsigned int mask = 0; + unsigned int mask = 0, rd, wr; DPRINTK ("ENTER\n"); assert (file != NULL); - assert (wait != NULL); card = file->private_data; assert (card != NULL); - if ((file->f_mode & FMODE_WRITE) && - (atomic_read (&card->ch_out.state) != sgd_stopped)) { - poll_wait(file, &card->ch_out.wait, wait); - - /* XXX is this correct */ - if (atomic_read (&card->ch_out.buf_in_use) < - atomic_read (&card->ch_out.next_buf)) - mask |= POLLOUT | POLLWRNORM; + rd = (file->f_mode & FMODE_READ); + wr = (file->f_mode & FMODE_WRITE); + + if (wr && (atomic_read (&card->ch_out.n_bufs) == 0)) { + assert (card->ch_out.is_active); + poll_wait(file, &card->ch_out.wait, wait); + } + if (rd) { + /* XXX is it ok, spec-wise, to start DMA here? */ + via_chan_maybe_start (&card->ch_in); + if (atomic_read (&card->ch_in.n_bufs) == 0) + poll_wait(file, &card->ch_in.wait, wait); } + if (wr && (atomic_read (&card->ch_out.n_bufs) > 0)) + mask |= POLLOUT | POLLWRNORM; + if (rd && (atomic_read (&card->ch_in.n_bufs) > 0)) + mask |= POLLIN | POLLRDNORM; + DPRINTK("EXIT, returning %u\n", mask); return mask; } -static int via_dsp_drain_dac (struct via_info *card, int non_block) +/** + * via_dsp_drain_playback - sleep until all playback samples are flushed + * @card: Private info for specified board + * @chan: Channel to drain + * @nonblock: boolean, non-zero if O_NONBLOCK is set + * + * Sleeps until all playback has been flushed to the audio + * hardware. + * + * Locking: inside card->syscall_sem + */ + +static int via_dsp_drain_playback (struct via_info *card, + struct via_channel *chan, int nonblock) { - DPRINTK ("ENTER, non_block = %d\n", non_block); + DPRINTK ("ENTER, nonblock = %d\n", nonblock); + + if (chan->slop_len > 0) + via_chan_flush_frag (chan); + + if (atomic_read (&chan->n_bufs) == VIA_DMA_BUFFERS) + goto out; + + via_chan_maybe_start (chan); + + while (atomic_read (&chan->n_bufs) < VIA_DMA_BUFFERS) { + if (nonblock) { + DPRINTK ("EXIT, returning -EAGAIN\n"); + return -EAGAIN; + } - while (!via_chan_empty (&card->ch_out)) { - if (non_block) { - DPRINTK ("EXIT, returning -EBUSY\n"); - return -EBUSY; +#ifdef VIA_DEBUG + { + u8 r40,r41,r42,r43,r44,r48; + pci_read_config_byte (card->pdev, 0x40, &r40); + pci_read_config_byte (card->pdev, 0x41, &r41); + pci_read_config_byte (card->pdev, 0x42, &r42); + pci_read_config_byte (card->pdev, 0x43, &r43); + pci_read_config_byte (card->pdev, 0x44, &r44); + pci_read_config_byte (card->pdev, 0x48, &r48); + DPRINTK("PCI config: %02X %02X %02X %02X %02X %02X\n", + r40,r41,r42,r43,r44,r48); + + DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", + inb (card->baseaddr + 0x00), + inb (card->baseaddr + 0x01), + inb (card->baseaddr + 0x02), + inl (card->baseaddr + 0x04), + inl (card->baseaddr + 0x0C), + inl (card->baseaddr + 0x80), + inl (card->baseaddr + 0x84)); } + + if (!chan->is_active) + printk (KERN_ERR "sleeping but not active\n"); +#endif + + DPRINTK ("sleeping, nbufs=%d\n", atomic_read (&chan->n_bufs)); + interruptible_sleep_on (&chan->wait); + if (signal_pending (current)) { DPRINTK ("EXIT, returning -ERESTARTSYS\n"); return -ERESTARTSYS; } + } -#ifndef NDEBUG +#ifdef VIA_DEBUG { u8 r40,r41,r42,r43,r44,r48; pci_read_config_byte (card->pdev, 0x40, &r40); @@ -1815,7 +2216,6 @@ static int via_dsp_drain_dac (struct via_info *card, int non_block) DPRINTK("PCI config: %02X %02X %02X %02X %02X %02X\n", r40,r41,r42,r43,r44,r48); - spin_lock_irq (&card->lock); DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", inb (card->baseaddr + 0x00), inb (card->baseaddr + 0x01), @@ -1824,39 +2224,49 @@ static int via_dsp_drain_dac (struct via_info *card, int non_block) inl (card->baseaddr + 0x0C), inl (card->baseaddr + 0x80), inl (card->baseaddr + 0x84)); - spin_unlock_irq (&card->lock); - + + DPRINTK ("final nbufs=%d\n", atomic_read (&chan->n_bufs)); } #endif - DPRINTK ("sleeping\n"); - interruptible_sleep_on (&card->ch_out.wait); - } - - DPRINTK ("EXIT\n"); +out: + DPRINTK ("EXIT, returning 0\n"); return 0; } +/** + * via_dsp_ioctl_space - get information about channel buffering + * @card: Private info for specified board + * @chan: pointer to channel-specific info + * @arg: user buffer for returned information + * + * Handles SNDCTL_DSP_GETISPACE and SNDCTL_DSP_GETOSPACE. + * + * Locking: inside card->syscall_sem + */ + static int via_dsp_ioctl_space (struct via_info *card, struct via_channel *chan, void *arg) { audio_buf_info info; - int n; info.fragstotal = VIA_DMA_BUFFERS; info.fragsize = VIA_DMA_BUF_SIZE; - /* number of full fragments we can read without blocking */ - n = atomic_read (&chan->next_buf) - atomic_read (&chan->buf_in_use); - info.fragments = VIA_DMA_BUFFERS - n; + /* number of full fragments we can read/write without blocking */ + info.fragments = atomic_read (&chan->n_bufs); + + if ((chan->slop_len > 0) && (info.fragments > 0)) + info.fragments--; /* number of bytes that can be read or written immediately - * without blocking. FIXME: we are lazy and ignore partially-full - * buffers. + * without blocking. */ - info.bytes = info.fragments * VIA_DMA_BUF_SIZE; + info.bytes = (info.fragments * VIA_DMA_BUF_SIZE); + if (chan->slop_len > 0) + info.bytes += VIA_DMA_BUF_SIZE - chan->slop_len; DPRINTK ("EXIT, returning fragstotal=%d, fragsize=%d, fragments=%d, bytes=%d\n", info.fragstotal, @@ -1868,14 +2278,95 @@ static int via_dsp_ioctl_space (struct via_info *card, } +/** + * via_dsp_ioctl_ptr - get information about hardware buffer ptr + * @card: Private info for specified board + * @chan: pointer to channel-specific info + * @arg: user buffer for returned information + * + * Handles SNDCTL_DSP_GETIPTR and SNDCTL_DSP_GETOPTR. + * + * Locking: inside card->syscall_sem + */ + +static int via_dsp_ioctl_ptr (struct via_info *card, + struct via_channel *chan, + void *arg) +{ + count_info info; + + spin_lock_irq (&card->lock); + + info.bytes = chan->bytes; + info.blocks = chan->n_irqs; + chan->n_irqs = 0; + + spin_unlock_irq (&card->lock); + + if (chan->is_active) { + unsigned long extra; + info.ptr = atomic_read (&chan->hw_ptr) * VIA_DMA_BUF_SIZE; + extra = VIA_DMA_BUF_SIZE - inl (chan->iobase + VIA_BASE0_PCM_OUT_BLOCK_COUNT); + info.ptr += extra; + info.bytes += extra; + } else { + info.ptr = 0; + } + + DPRINTK ("EXIT, returning bytes=%d, blocks=%d, ptr=%d\n", + info.bytes, + info.blocks, + info.ptr); + + return copy_to_user (arg, &info, sizeof (info)); +} + + +static int via_dsp_ioctl_trigger (struct via_channel *chan, int val) +{ + int enable, do_something; + + if (chan->is_record) + enable = (val & PCM_ENABLE_INPUT); + else + enable = (val & PCM_ENABLE_OUTPUT); + + if (!chan->is_enabled && enable) { + do_something = 1; + } else if (chan->is_enabled && !enable) { + do_something = -1; + } else { + do_something = 0; + } + + DPRINTK ("enable=%d, do_something=%d\n", + enable, do_something); + + if (chan->is_active && do_something) + return -EINVAL; + + if (do_something == 1) { + chan->is_enabled = 1; + via_chan_maybe_start (chan); + DPRINTK ("Triggering input\n"); + } + + else if (do_something == -1) { + chan->is_enabled = 0; + DPRINTK ("Setup input trigger\n"); + } + + return 0; +} + static int via_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int rc = -EINVAL, rd=0, wr=0, val=0; + int rc, rd=0, wr=0, val=0; struct via_info *card; - - DPRINTK ("ENTER, cmd = 0x%08X\n", cmd); + struct via_channel *chan; + int nonblock = (file->f_flags & O_NONBLOCK); assert (file != NULL); card = file->private_data; @@ -1885,188 +2376,277 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file, wr = 1; if (file->f_mode & FMODE_READ) rd = 1; - + + rc = via_syscall_down (card, nonblock); + if (rc) + return rc; + rc = -EINVAL; + switch (cmd) { - /* OSS API version. XXX unverified */ + /* OSS API version. XXX unverified */ case OSS_GETVERSION: - DPRINTK("EXIT, returning SOUND_VERSION\n"); - return put_user (SOUND_VERSION, (int *)arg); + DPRINTK("ioctl OSS_GETVERSION, EXIT, returning SOUND_VERSION\n"); + rc = put_user (SOUND_VERSION, (int *)arg); + break; /* list of supported PCM data formats */ case SNDCTL_DSP_GETFMTS: - DPRINTK("EXIT, returning AFMT U8|S16_LE\n"); - return put_user (AFMT_U8 | AFMT_S16_LE, (int *)arg); + DPRINTK("DSP_GETFMTS, EXIT, returning AFMT U8|S16_LE\n"); + rc = put_user (AFMT_U8 | AFMT_S16_LE, (int *)arg); + break; /* query or set current channel's PCM data format */ case SNDCTL_DSP_SETFMT: - if (get_user(val, (int *)arg)) - return -EFAULT; + if (get_user(val, (int *)arg)) { + rc = -EFAULT; + break; + } + DPRINTK("DSP_SETFMT, val==%d\n", val); if (val != AFMT_QUERY) { rc = 0; - spin_lock_irq (&card->lock); if (rc == 0 && rd) rc = via_chan_set_fmt (card, &card->ch_in, val); if (rc == 0 && wr) rc = via_chan_set_fmt (card, &card->ch_out, val); - spin_unlock_irq (&card->lock); - if (rc <= 0) - return rc ? rc : -EINVAL; + if (rc <= 0) { + if (rc == 0) + rc = -EINVAL; + break; + } val = rc; } else { - spin_lock_irq (&card->lock); if ((rd && (card->ch_in.pcm_fmt & VIA_PCM_FMT_16BIT)) || (wr && (card->ch_out.pcm_fmt & VIA_PCM_FMT_16BIT))) val = AFMT_S16_LE; else val = AFMT_U8; - spin_unlock_irq (&card->lock); } DPRINTK("SETFMT EXIT, returning %d\n", val); - return put_user (val, (int *)arg); + rc = put_user (val, (int *)arg); + break; /* query or set number of channels (1=mono, 2=stereo) */ case SNDCTL_DSP_CHANNELS: - if (get_user(val, (int *)arg)) - return -EFAULT; + if (get_user(val, (int *)arg)) { + rc = -EFAULT; + break; + } + DPRINTK("DSP_CHANNELS, val==%d\n", val); if (val != 0) { rc = 0; - spin_lock_irq (&card->lock); if (rc == 0 && rd) rc = via_chan_set_stereo (card, &card->ch_in, val); if (rc == 0 && wr) rc = via_chan_set_stereo (card, &card->ch_out, val); - spin_unlock_irq (&card->lock); - if (rc <= 0) - return rc ? rc : -EINVAL; + if (rc <= 0) { + if (rc == 0) + rc = -EINVAL; + break; + } val = rc; } else { - spin_lock_irq (&card->lock); if ((rd && (card->ch_in.pcm_fmt & VIA_PCM_FMT_STEREO)) || (wr && (card->ch_out.pcm_fmt & VIA_PCM_FMT_STEREO))) val = 2; else val = 1; - spin_unlock_irq (&card->lock); } DPRINTK("CHANNELS EXIT, returning %d\n", val); - return put_user (val, (int *)arg); - + rc = put_user (val, (int *)arg); + break; + /* enable (val is not zero) or disable (val == 0) stereo */ case SNDCTL_DSP_STEREO: - if (get_user(val, (int *)arg)) - return -EFAULT; + if (get_user(val, (int *)arg)) { + rc = -EFAULT; + break; + } + DPRINTK("DSP_STEREO, val==%d\n", val); rc = 0; - spin_lock_irq (&card->lock); + if (rc == 0 && rd) rc = via_chan_set_stereo (card, &card->ch_in, val ? 2 : 1); if (rc == 0 && wr) rc = via_chan_set_stereo (card, &card->ch_out, val ? 2 : 1); - spin_unlock_irq (&card->lock); - if (rc <= 0) - return rc ? rc : -EINVAL; + + if (rc <= 0) { + if (rc == 0) + rc = -EINVAL; + break; + } DPRINTK("STEREO EXIT, returning %d\n", val); - return 0; - + rc = 0; + break; + /* query or set sampling rate */ case SNDCTL_DSP_SPEED: - if (get_user(val, (int *)arg)) - return -EFAULT; - if (val < 0) - return -EINVAL; + if (get_user(val, (int *)arg)) { + rc = -EFAULT; + break; + } + DPRINTK("DSP_SPEED, val==%d\n", val); + if (val < 0) { + rc = -EINVAL; + break; + } if (val > 0) { rc = 0; - spin_lock_irq (&card->lock); + if (rc == 0 && rd) rc = via_chan_set_speed (card, &card->ch_in, val); if (rc == 0 && wr) rc = via_chan_set_speed (card, &card->ch_out, val); - spin_unlock_irq (&card->lock); - if (rc <= 0) - return rc ? rc : -EINVAL; + + if (rc <= 0) { + if (rc == 0) + rc = -EINVAL; + break; + } val = rc; } else { - spin_lock_irq (&card->lock); if (rd) val = card->ch_in.rate; else if (wr) val = card->ch_out.rate; else val = 0; - spin_unlock_irq (&card->lock); } DPRINTK("SPEED EXIT, returning %d\n", val); - return put_user (val, (int *)arg); - + rc = put_user (val, (int *)arg); + break; + /* wait until all buffers have been played, and then stop device */ case SNDCTL_DSP_SYNC: + DPRINTK ("DSP_SYNC\n"); if (wr) { - DPRINTK("SYNC EXIT (after calling via_dsp_drain_dac)\n"); - return via_dsp_drain_dac (card, file->f_flags & O_NONBLOCK); + DPRINTK("SYNC EXIT (after calling via_dsp_drain_playback)\n"); + rc = via_dsp_drain_playback (card, &card->ch_out, nonblock); } break; /* stop recording/playback immediately */ case SNDCTL_DSP_RESET: - spin_lock_irq (&card->lock); + DPRINTK ("DSP_RESET\n"); if (rd) { via_chan_clear (&card->ch_in); - via_chan_pcm_fmt (card, &card->ch_in, 1); + via_chan_pcm_fmt (&card->ch_in, 1); } if (wr) { via_chan_clear (&card->ch_out); - via_chan_pcm_fmt (card, &card->ch_out, 1); + via_chan_pcm_fmt (&card->ch_out, 1); } - spin_unlock_irq (&card->lock); - DPRINTK("RESET EXIT, returning 0\n"); - return 0; + + rc = 0; + break; /* obtain bitmask of device capabilities, such as mmap, full duplex, etc. */ case SNDCTL_DSP_GETCAPS: - DPRINTK("GETCAPS EXIT\n"); - return put_user(DSP_CAP_REVISION, (int *)arg); - + DPRINTK("DSP_GETCAPS\n"); + rc = put_user(VIA_DSP_CAP, (int *)arg); + break; + /* obtain bitmask of device capabilities, such as mmap, full duplex, etc. */ case SNDCTL_DSP_GETBLKSIZE: - DPRINTK("GETBLKSIZE EXIT\n"); - return put_user(VIA_DMA_BUF_SIZE, (int *)arg); - + DPRINTK("DSP_GETBLKSIZE\n"); + rc = put_user(VIA_DMA_BUF_SIZE, (int *)arg); + break; + /* obtain information about input buffering */ case SNDCTL_DSP_GETISPACE: - DPRINTK("GETISPACE EXIT\n"); - return via_dsp_ioctl_space (card, &card->ch_in, (void*) arg); - + DPRINTK("DSP_GETISPACE\n"); + if (rd) + rc = via_dsp_ioctl_space (card, &card->ch_in, (void*) arg); + break; + /* obtain information about output buffering */ case SNDCTL_DSP_GETOSPACE: - DPRINTK("GETOSPACE EXIT\n"); - return via_dsp_ioctl_space (card, &card->ch_out, (void*) arg); + DPRINTK("DSP_GETOSPACE\n"); + if (wr) + rc = via_dsp_ioctl_space (card, &card->ch_out, (void*) arg); + break; + + /* obtain information about input hardware pointer */ + case SNDCTL_DSP_GETIPTR: + DPRINTK("DSP_GETIPTR\n"); + if (rd) + rc = via_dsp_ioctl_ptr (card, &card->ch_in, (void*) arg); + break; + + /* obtain information about output hardware pointer */ + case SNDCTL_DSP_GETOPTR: + DPRINTK("DSP_GETOPTR\n"); + if (wr) + rc = via_dsp_ioctl_ptr (card, &card->ch_out, (void*) arg); + break; /* return number of bytes remaining to be played by DMA engine */ case SNDCTL_DSP_GETODELAY: { - int n; - - n = atomic_read (&card->ch_out.next_buf) - - atomic_read (&card->ch_out.buf_in_use); - assert (n >= 0); - - if (n == 0) - val = 0; - else { - val = (n - 1) * VIA_DMA_BUF_SIZE; - val += inl (card->ch_out.iobase + VIA_BASE0_PCM_OUT_BLOCK_COUNT); + DPRINTK("DSP_GETODELAY\n"); + + chan = &card->ch_out; + + if (!wr) + break; + + val = VIA_DMA_BUFFERS - atomic_read (&chan->n_bufs); + + if (val > 0) { + val *= VIA_DMA_BUF_SIZE; + val -= VIA_DMA_BUF_SIZE - + inl (chan->iobase + VIA_BASE0_PCM_OUT_BLOCK_COUNT); } - + val += chan->slop_len; + + assert (val <= (VIA_DMA_BUF_SIZE * VIA_DMA_BUFFERS)); + DPRINTK("GETODELAY EXIT, val = %d bytes\n", val); - return put_user (val, (int *)arg); + rc = put_user (val, (int *)arg); + break; } + /* handle the quick-start of a channel, + * or the notification that a quick-start will + * occur in the future + */ + case SNDCTL_DSP_SETTRIGGER: + if (get_user(val, (int *)arg)) { + rc = -EFAULT; + break; + } + DPRINTK("DSP_SETTRIGGER, rd=%d, wr=%d, act=%d/%d, en=%d/%d\n", + rd, wr, card->ch_in.is_active, card->ch_out.is_active, + card->ch_in.is_enabled, card->ch_out.is_enabled); + + rc = 0; + + if (rd) + rc = via_dsp_ioctl_trigger (&card->ch_in, val); + if (!rc && wr) + rc = via_dsp_ioctl_trigger (&card->ch_out, val); + + break; + + /* Enable full duplex. Since we do this as soon as we are opened + * with O_RDWR, this is mainly a no-op that always returns success. + */ + case SNDCTL_DSP_SETDUPLEX: + DPRINTK("DSP_SETDUPLEX\n"); + if (!rd || !wr) + break; + rc = 0; + break; + /* set fragment size. implemented as a successful no-op for now */ case SNDCTL_DSP_SETFRAGMENT: - if (get_user(val, (int *)arg)) - return -EFAULT; + if (get_user(val, (int *)arg)) { + rc = -EFAULT; + break; + } + DPRINTK("DSP_SETFRAGMENT, val==%d\n", val); DPRINTK ("SNDCTL_DSP_SETFRAGMENT (fragshift==0x%04X (%d), maxfrags==0x%04X (%d))\n", val & 0xFFFF, @@ -2075,19 +2655,29 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file, (val >> 16) & 0xFFFF); /* just to shut up some programs */ - return 0; + rc = 0; + break; - /* inform device of an upcoming pause in input (or output). not implemented */ + /* inform device of an upcoming pause in input (or output). */ case SNDCTL_DSP_POST: - DPRINTK("POST EXIT (null ioctl, returning -EINVAL)\n"); - return -EINVAL; + DPRINTK("DSP_POST\n"); + if (wr) { + if (card->ch_out.slop_len > 0) + via_chan_flush_frag (&card->ch_out); + via_chan_maybe_start (&card->ch_out); + } + + rc = 0; + break; /* not implemented */ default: - DPRINTK ("unhandled ioctl\n"); + DPRINTK ("unhandled ioctl, cmd==%u, arg==%p\n", + cmd, (void*) arg); break; } - + + up (&card->syscall_sem); DPRINTK("EXIT, returning %d\n", rc); return rc; } @@ -2095,25 +2685,28 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file, static int via_dsp_open (struct inode *inode, struct file *file) { - int open_mode, rc = -EINVAL, minor = MINOR(inode->i_rdev); - int got_read_chan = 0, is_busy; + int rc, minor = MINOR(inode->i_rdev); + int got_read_chan = 0; struct via_info *card; struct pci_dev *pdev; + struct via_channel *chan; struct pci_driver *drvr; - unsigned long flags; + int nonblock = (file->f_flags & O_NONBLOCK); DPRINTK ("ENTER, minor=%d, file->f_mode=0x%x\n", minor, file->f_mode); - - if (file->f_mode & FMODE_READ) /* no input ATM */ - goto err_out; + + if (!(file->f_mode & (FMODE_READ | FMODE_WRITE))) { + DPRINTK ("EXIT, returning -EINVAL\n"); + return -EINVAL; + } card = NULL; pci_for_each_dev(pdev) { drvr = pci_dev_driver (pdev); if (drvr == &via_driver) { - assert (pdev->driver_data != NULL); - - card = pdev->driver_data; + assert (pci_get_drvdata (pdev) != NULL); + + card = pci_get_drvdata (pdev); DPRINTK ("dev_dsp = %d, minor = %d, assn = %d\n", card->dev_dsp, minor, (card->dev_dsp ^ minor) & ~0xf); @@ -2122,77 +2715,69 @@ static int via_dsp_open (struct inode *inode, struct file *file) goto match; } } - + DPRINTK ("no matching %s found\n", card ? "minor" : "driver"); - rc = -ENODEV; - goto err_out; + return -ENODEV; match: - file->private_data = card; - - /* wait for device to become free */ - spin_lock_irqsave (&card->lock, flags); - open_mode = card->open_mode; - if (open_mode & file->f_mode) - is_busy = 1; - else { - is_busy = 0; - card->open_mode |= file->f_mode; - open_mode = card->open_mode; - } - spin_unlock_irqrestore (&card->lock, flags); - if (is_busy) { - rc = -EBUSY; - goto err_out; + if (nonblock) { + if (down_trylock (&card->open_sem)) { + DPRINTK ("EXIT, returning -EAGAIN\n"); + return -EAGAIN; + } + } else { + if (down_interruptible (&card->open_sem)) { + DPRINTK ("EXIT, returning -ERESTARTSYS\n"); + return -ERESTARTSYS; + } } - DPRINTK("open_mode now 0x%x\n", open_mode); + file->private_data = card; + DPRINTK("file->f_mode == 0x%x\n", file->f_mode); /* handle input from analog source */ if (file->f_mode & FMODE_READ) { - rc = via_chan_init (card, &card->ch_in, 0x10); + chan = &card->ch_in; + + rc = via_chan_init (card, chan); if (rc) - goto err_out_clear_mode; - + goto err_out; + got_read_chan = 1; - - /* why is this forced to 16-bit stereo in all drivers? */ - card->ch_in.pcm_fmt = - VIA_PCM_FMT_16BIT | VIA_PCM_FMT_STEREO; - spin_lock_irqsave (&card->lock, flags); - via_chan_pcm_fmt (card, &card->ch_out, 0); - spin_unlock_irqrestore (&card->lock, flags); + /* why is this forced to 16-bit stereo in all drivers? */ + chan->pcm_fmt = VIA_PCM_FMT_16BIT | VIA_PCM_FMT_STEREO; - via_set_adc_rate (card, 8000); + via_chan_pcm_fmt (chan, 0); + via_set_rate (&card->ac97, chan, 44100); } /* handle output to analog source */ if (file->f_mode & FMODE_WRITE) { - rc = via_chan_init (card, &card->ch_out, 0x00); + chan = &card->ch_out; + + rc = via_chan_init (card, chan); if (rc) - goto err_out_clear_mode; - - if ((minor & 0xf) == SND_DEV_DSP16) - card->ch_out.pcm_fmt |= VIA_PCM_FMT_16BIT; + goto err_out_read_chan; - spin_lock_irqsave (&card->lock, flags); - via_chan_pcm_fmt (card, &card->ch_out, 0); - spin_unlock_irqrestore (&card->lock, flags); + if ((minor & 0xf) == SND_DEV_DSP16) { + chan->pcm_fmt |= VIA_PCM_FMT_16BIT; + via_set_rate (&card->ac97, chan, 44100); + } else { + via_set_rate (&card->ac97, chan, 8000); + } - via_set_dac_rate (card, 8000); + via_chan_pcm_fmt (chan, 0); } DPRINTK ("EXIT, returning 0\n"); return 0; -err_out_clear_mode: +err_out_read_chan: if (got_read_chan) via_chan_free (card, &card->ch_in); - spin_lock_irqsave (&card->lock, flags); - card->open_mode &= ~file->f_mode; - spin_unlock_irqrestore (&card->lock, flags); err_out: + up (&card->open_sem); DPRINTK("ERROR EXIT, returning %d\n", rc); return rc; } @@ -2201,222 +2786,40 @@ err_out: static int via_dsp_release(struct inode *inode, struct file *file) { struct via_info *card; - unsigned long flags; + int nonblock = (file->f_flags & O_NONBLOCK); + int rc; DPRINTK ("ENTER\n"); - + assert (file != NULL); card = file->private_data; assert (card != NULL); - - lock_kernel(); - if (file->f_mode & FMODE_READ) - via_chan_free (card, &card->ch_in); - if (file->f_mode & FMODE_WRITE) { - via_dsp_drain_dac (card, file->f_flags & O_NONBLOCK); - via_chan_free (card, &card->ch_out); + rc = via_syscall_down (card, nonblock); + if (rc) { + DPRINTK ("EXIT (syscall_down error), rc=%d\n", rc); + return rc; } - - spin_lock_irqsave (&card->lock, flags); - card->open_mode &= ~(file->f_mode); - spin_unlock_irqrestore (&card->lock, flags); - - wake_up (&card->open_wait); - unlock_kernel(); - - DPRINTK("EXIT, returning 0\n"); - return 0; -} - - -#ifdef VIA_PROC_FS - -/**************************************************************** - * - * /proc/driver/via/info - * - * - */ - -static int via_info_read_proc (char *page, char **start, off_t off, - int count, int *eof, void *data) -{ -#define YN(val,bit) (((val) & (bit)) ? "yes" : "no") -#define ED(val,bit) (((val) & (bit)) ? "enable" : "disable") - - int len = 0; - u8 r40, r41, r42, r44; - struct via_info *card = data; - - DPRINTK ("ENTER\n"); - - assert (card != NULL); - - len += sprintf (page+len, VIA_CARD_NAME "\n\n"); - - pci_read_config_byte (card->pdev, 0x40, &r40); - pci_read_config_byte (card->pdev, 0x41, &r41); - pci_read_config_byte (card->pdev, 0x42, &r42); - pci_read_config_byte (card->pdev, 0x44, &r44); - - len += sprintf (page+len, - "Via 82Cxxx PCI registers:\n" - "\n" - "40 Codec Ready: %s\n" - " Codec Low-power: %s\n" - " Secondary Codec Ready: %s\n" - "\n" - "41 Interface Enable: %s\n" - " De-Assert Reset: %s\n" - " Force SYNC high: %s\n" - " Force SDO high: %s\n" - " Variable Sample Rate On-Demand Mode: %s\n" - " SGD Read Channel PCM Data Out: %s\n" - " FM Channel PCM Data Out: %s\n" - " SB PCM Data Out: %s\n" - "\n" - "42 Game port enabled: %s\n" - " SoundBlaster enabled: %s\n" - " FM enabled: %s\n" - " MIDI enabled: %s\n" - "\n" - "44 AC-Link Interface Access: %s\n" - " Secondary Codec Support: %s\n" - - "\n", - - YN (r40, VIA_CR40_AC97_READY), - YN (r40, VIA_CR40_AC97_LOW_POWER), - YN (r40, VIA_CR40_SECONDARY_READY), - - ED (r41, VIA_CR41_AC97_ENABLE), - YN (r41, (1 << 6)), - YN (r41, (1 << 5)), - YN (r41, (1 << 4)), - ED (r41, (1 << 3)), - ED (r41, (1 << 2)), - ED (r41, (1 << 1)), - ED (r41, (1 << 0)), - - YN (r42, VIA_CR42_GAME_ENABLE), - YN (r42, VIA_CR42_SB_ENABLE), - YN (r42, VIA_CR42_FM_ENABLE), - YN (r42, VIA_CR42_MIDI_ENABLE), - YN (r44, VIA_CR44_AC_LINK_ACCESS), - YN (r44, VIA_CR44_SECOND_CODEC_SUPPORT) - - ); - - DPRINTK("EXIT, returning %d\n", len); - return len; - -#undef YN -#undef ED -} - - -/**************************************************************** - * - * /proc/driver/via/... setup and cleanup - * - * - */ - -static int __init via_init_proc (void) -{ - DPRINTK ("ENTER\n"); - - if (!proc_mkdir ("driver/via", 0)) - return -EIO; - - DPRINTK ("EXIT, returning 0\n"); - return 0; -} - - -static void via_cleanup_proc (void) -{ - DPRINTK ("ENTER\n"); - - remove_proc_entry ("driver/via", NULL); - - DPRINTK ("EXIT\n"); -} - - -static int __init via_card_init_proc (struct via_info *card) -{ - char s[32]; - int rc; - - DPRINTK ("ENTER\n"); - - sprintf (s, "driver/via/%d", card->card_num); - if (!proc_mkdir (s, 0)) { - rc = -EIO; - goto err_out_none; - } - - sprintf (s, "driver/via/%d/info", card->card_num); - if (!create_proc_read_entry (s, 0, 0, via_info_read_proc, card)) { - rc = -EIO; - goto err_out_dir; - } + if (file->f_mode & FMODE_WRITE) { + rc = via_dsp_drain_playback (card, &card->ch_out, nonblock); + if (rc) + printk (KERN_DEBUG "via_audio: ignoring drain playback error %d\n", rc); - sprintf (s, "driver/via/%d/ac97", card->card_num); - if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, &card->ac97)) { - rc = -EIO; - goto err_out_info; + via_chan_free (card, &card->ch_out); } - DPRINTK ("EXIT, returning 0\n"); - return 0; - -err_out_info: - sprintf (s, "driver/via/%d/info", card->card_num); - remove_proc_entry (s, NULL); - -err_out_dir: - sprintf (s, "driver/via/%d", card->card_num); - remove_proc_entry (s, NULL); - -err_out_none: - DPRINTK ("EXIT, returning %d\n", rc); - return rc; -} - - -static void via_card_cleanup_proc (struct via_info *card) -{ - char s[32]; - - DPRINTK ("ENTER\n"); - - sprintf (s, "driver/via/%d/ac97", card->card_num); - remove_proc_entry (s, NULL); - - sprintf (s, "driver/via/%d/info", card->card_num); - remove_proc_entry (s, NULL); + if (file->f_mode & FMODE_READ) + via_chan_free (card, &card->ch_in); - sprintf (s, "driver/via/%d", card->card_num); - remove_proc_entry (s, NULL); + up (&card->syscall_sem); + up (&card->open_sem); - DPRINTK ("EXIT\n"); + DPRINTK("EXIT, returning 0\n"); + return 0; } -#else - -static inline int via_init_proc (void) { return 0; } -static inline void via_cleanup_proc (void) {} -static inline int via_card_init_proc (struct via_info *card) { return 0; } -static inline void via_card_cleanup_proc (struct via_info *card) {} - -#endif /* VIA_PROC_FS */ - - /**************************************************************** * * Chip setup and kernel registration @@ -2430,9 +2833,9 @@ static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id struct via_info *card; u8 tmp; static int printed_version = 0; - + DPRINTK ("ENTER\n"); - + if (printed_version++ == 0) printk (KERN_INFO "Via 686a audio driver " VIA_VERSION "\n"); @@ -2448,7 +2851,7 @@ static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id rc = -EIO; goto err_out_none; } - + card = kmalloc (sizeof (*card), GFP_KERNEL); if (!card) { printk (KERN_ERR PFX "out of memory, aborting\n"); @@ -2456,15 +2859,21 @@ static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id goto err_out_none; } - pdev->driver_data = card; + pci_set_drvdata (pdev, card); memset (card, 0, sizeof (*card)); card->pdev = pdev; card->baseaddr = pci_resource_start (pdev, 0); card->card_num = via_num_cards++; spin_lock_init (&card->lock); - init_waitqueue_head(&card->open_wait); - + init_MUTEX (&card->syscall_sem); + init_MUTEX (&card->open_sem); + + /* we must init these now, in case the intr handler needs them */ + via_chan_init_defaults (card, &card->ch_out); + via_chan_init_defaults (card, &card->ch_in); + via_chan_init_defaults (card, &card->ch_fm); + /* if BAR 2 is present, chip is Rev H or later, * which means it has a few extra features */ if (pci_resource_start (pdev, 2) > 0) @@ -2481,8 +2890,8 @@ static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id rc = -ENODEV; goto err_out_kfree; } - - /* + + /* * init AC97 mixer and codec */ rc = via_ac97_init (card); @@ -2499,10 +2908,10 @@ static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id printk (KERN_ERR PFX "DSP device init failed, aborting\n"); goto err_out_have_mixer; } - + /* * per-card /proc info - */ + */ rc = via_card_init_proc (card); if (rc) { printk (KERN_ERR PFX "card-specific /proc init failed, aborting\n"); @@ -2517,10 +2926,11 @@ static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id printk (KERN_ERR PFX "interrupt init failed, aborting\n"); goto err_out_have_proc; } - + pci_read_config_byte (pdev, 0x3C, &tmp); if ((tmp & 0x0F) != pdev->irq) { printk (KERN_WARNING PFX "IRQ fixup, 0x3C==0x%02X\n", tmp); + udelay (15); tmp &= 0xF0; tmp |= pdev->irq; pci_write_config_byte (pdev, 0x3C, tmp); @@ -2532,7 +2942,7 @@ static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id printk (KERN_INFO PFX "board #%d at 0x%04lX, IRQ %d\n", card->card_num + 1, card->baseaddr, pdev->irq); - + DPRINTK ("EXIT, returning 0\n"); return 0; @@ -2554,7 +2964,7 @@ err_out_kfree: err_out_none: release_region (pci_resource_start (pdev, 0), pci_resource_len (pdev, 0)); err_out: - pdev->driver_data = NULL; + pci_set_drvdata (pdev, NULL); DPRINTK ("EXIT - returning %d\n", rc); return rc; } @@ -2563,13 +2973,13 @@ err_out: static void __exit via_remove_one (struct pci_dev *pdev) { struct via_info *card; - + DPRINTK ("ENTER\n"); - + assert (pdev != NULL); - card = pdev->driver_data; + card = pci_get_drvdata (pdev); assert (card != NULL); - + via_interrupt_cleanup (card); via_card_cleanup_proc (card); via_dsp_cleanup (card); @@ -2582,8 +2992,8 @@ static void __exit via_remove_one (struct pci_dev *pdev) #endif kfree (card); - pdev->driver_data = NULL; - + pci_set_drvdata (pdev, NULL); + pci_set_power_state (pdev, 3); /* ...zzzzzz */ DPRINTK ("EXIT\n"); @@ -2623,11 +3033,11 @@ static int __init init_via82cxxx_audio(void) return 0; } - + static void __exit cleanup_via82cxxx_audio(void) { DPRINTK("ENTER\n"); - + pci_unregister_driver (&via_driver); via_cleanup_proc (); @@ -2637,3 +3047,187 @@ static void __exit cleanup_via82cxxx_audio(void) module_init(init_via82cxxx_audio); module_exit(cleanup_via82cxxx_audio); + +MODULE_AUTHOR("Jeff Garzik <jgarzik@mandrakesoft.com>"); +MODULE_DESCRIPTION("DSP audio and mixer driver for Via 82Cxxx audio devices"); +EXPORT_NO_SYMBOLS; + + + +#ifdef VIA_PROC_FS + +/**************************************************************** + * + * /proc/driver/via/info + * + * + */ + +static int via_info_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ +#define YN(val,bit) (((val) & (bit)) ? "yes" : "no") +#define ED(val,bit) (((val) & (bit)) ? "enable" : "disable") + + int len = 0; + u8 r40, r41, r42, r44; + struct via_info *card = data; + + DPRINTK ("ENTER\n"); + + assert (card != NULL); + + len += sprintf (page+len, VIA_CARD_NAME "\n\n"); + + pci_read_config_byte (card->pdev, 0x40, &r40); + pci_read_config_byte (card->pdev, 0x41, &r41); + pci_read_config_byte (card->pdev, 0x42, &r42); + pci_read_config_byte (card->pdev, 0x44, &r44); + + len += sprintf (page+len, + "Via 82Cxxx PCI registers:\n" + "\n" + "40 Codec Ready: %s\n" + " Codec Low-power: %s\n" + " Secondary Codec Ready: %s\n" + "\n" + "41 Interface Enable: %s\n" + " De-Assert Reset: %s\n" + " Force SYNC high: %s\n" + " Force SDO high: %s\n" + " Variable Sample Rate On-Demand Mode: %s\n" + " SGD Read Channel PCM Data Out: %s\n" + " FM Channel PCM Data Out: %s\n" + " SB PCM Data Out: %s\n" + "\n" + "42 Game port enabled: %s\n" + " SoundBlaster enabled: %s\n" + " FM enabled: %s\n" + " MIDI enabled: %s\n" + "\n" + "44 AC-Link Interface Access: %s\n" + " Secondary Codec Support: %s\n" + + "\n", + + YN (r40, VIA_CR40_AC97_READY), + YN (r40, VIA_CR40_AC97_LOW_POWER), + YN (r40, VIA_CR40_SECONDARY_READY), + + ED (r41, VIA_CR41_AC97_ENABLE), + YN (r41, (1 << 6)), + YN (r41, (1 << 5)), + YN (r41, (1 << 4)), + ED (r41, (1 << 3)), + ED (r41, (1 << 2)), + ED (r41, (1 << 1)), + ED (r41, (1 << 0)), + + YN (r42, VIA_CR42_GAME_ENABLE), + YN (r42, VIA_CR42_SB_ENABLE), + YN (r42, VIA_CR42_FM_ENABLE), + YN (r42, VIA_CR42_MIDI_ENABLE), + + YN (r44, VIA_CR44_AC_LINK_ACCESS), + YN (r44, VIA_CR44_SECOND_CODEC_SUPPORT) + + ); + + DPRINTK("EXIT, returning %d\n", len); + return len; + +#undef YN +#undef ED +} + + +/**************************************************************** + * + * /proc/driver/via/... setup and cleanup + * + * + */ + +static int __init via_init_proc (void) +{ + DPRINTK ("ENTER\n"); + + if (!proc_mkdir ("driver/via", 0)) + return -EIO; + + DPRINTK ("EXIT, returning 0\n"); + return 0; +} + + +static void via_cleanup_proc (void) +{ + DPRINTK ("ENTER\n"); + + remove_proc_entry ("driver/via", NULL); + + DPRINTK ("EXIT\n"); +} + + +static int __init via_card_init_proc (struct via_info *card) +{ + char s[32]; + int rc; + + DPRINTK ("ENTER\n"); + + sprintf (s, "driver/via/%d", card->card_num); + if (!proc_mkdir (s, 0)) { + rc = -EIO; + goto err_out_none; + } + + sprintf (s, "driver/via/%d/info", card->card_num); + if (!create_proc_read_entry (s, 0, 0, via_info_read_proc, card)) { + rc = -EIO; + goto err_out_dir; + } + + sprintf (s, "driver/via/%d/ac97", card->card_num); + if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, &card->ac97)) { + rc = -EIO; + goto err_out_info; + } + + DPRINTK ("EXIT, returning 0\n"); + return 0; + +err_out_info: + sprintf (s, "driver/via/%d/info", card->card_num); + remove_proc_entry (s, NULL); + +err_out_dir: + sprintf (s, "driver/via/%d", card->card_num); + remove_proc_entry (s, NULL); + +err_out_none: + DPRINTK ("EXIT, returning %d\n", rc); + return rc; +} + + +static void via_card_cleanup_proc (struct via_info *card) +{ + char s[32]; + + DPRINTK ("ENTER\n"); + + sprintf (s, "driver/via/%d/ac97", card->card_num); + remove_proc_entry (s, NULL); + + sprintf (s, "driver/via/%d/info", card->card_num); + remove_proc_entry (s, NULL); + + sprintf (s, "driver/via/%d", card->card_num); + remove_proc_entry (s, NULL); + + DPRINTK ("EXIT\n"); +} + +#endif /* VIA_PROC_FS */ diff --git a/drivers/sound/waveartist.c b/drivers/sound/waveartist.c index 0788264c0..5e4f6c34d 100644 --- a/drivers/sound/waveartist.c +++ b/drivers/sound/waveartist.c @@ -1762,10 +1762,10 @@ static struct address_info cfg; static int attached; -static int __initdata io; -static int __initdata irq; -static int __initdata dma; -static int __initdata dma2; +static int __initdata io = 0; +static int __initdata irq = 0; +static int __initdata dma = 0; +static int __initdata dma2 = 0; MODULE_PARM(io, "i"); /* IO base */ diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index 21e4df264..37bb96b28 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c @@ -2046,17 +2046,13 @@ static int __init serial_console_setup(struct console *co, char *options) } static struct console sercons = { - "ttyS", - serial_console_write, - NULL, - serial_console_device, - serial_console_wait_key, - NULL, - serial_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + name: "ttyS", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: -1, }; /* diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 53452e878..584b3615c 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c @@ -67,6 +67,14 @@ static char ixj_c_revision[] = "$Revision: 3.31 $"; #include <asm/segment.h> #include <asm/uaccess.h> +#ifdef CONFIG_PCMCIA +#include <pcmcia/version.h> +#include <pcmcia/cs_types.h> +#include <pcmcia/cs.h> +#include <pcmcia/cistpl.h> +#include <pcmcia/ds.h> +#endif + #ifdef CONFIG_ISAPNP #include <linux/isapnp.h> #endif @@ -5876,8 +5884,8 @@ static void ixj_detach(dev_link_t * link) } /* Unlink device structure, free bits */ *linkp = link->next; - kfree_s(link->priv, sizeof(ixj_info_t)); - kfree_s(link, sizeof(struct dev_link_t)); + kfree(link->priv); + kfree(link); } #define CS_CHECK(fn, args...) \ @@ -6039,7 +6047,7 @@ int ixj_event(event_t event, int priority, event_callback_args_t * args) case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { - link->release.expires = RUN_AT(HZ / 20); + link->release.expires = jiffies + (HZ / 20); link->state |= DEV_RELEASE_PENDING; add_timer(&link->release); } diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in index 389890e10..9e510e087 100644 --- a/drivers/usb/Config.in +++ b/drivers/usb/Config.in @@ -79,10 +79,10 @@ comment 'USB Devices' if [ "$CONFIG_INPUT" = "n" ]; then comment ' Input core support is needed for USB HID' else - dep_tristate ' USB Human Interface Device (HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT + dep_tristate ' USB Human Interface Device (full HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT if [ "$CONFIG_USB_HID" != "y" ]; then - dep_tristate ' USB HIDBP Keyboard support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT - dep_tristate ' USB HIDBP Mouse support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT + dep_tristate ' USB HIDBP Keyboard (basic) support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT + dep_tristate ' USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT fi dep_tristate ' Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT fi diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index bf60b9167..217fa9f2c 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -21,7 +21,7 @@ export-objs := usb.o # Multipart objects. list-multi := usbcore.o -usbcore-objs := usb.o usb-debug.o usb-core.o hub.o +usbcore-objs := usb.o usb-debug.o hub.o # Optional parts of multipart objects. @@ -86,27 +86,14 @@ else endif endif -# Extract lists of the multi-part drivers. -# The 'int-*' lists are the intermediate files used to build the multi's. - -multi-y := $(filter $(list-multi), $(obj-y)) -multi-m := $(filter $(list-multi), $(obj-m)) -int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) -int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) - -# Files that are both resident and modular: remove from modular. - -obj-m := $(filter-out $(obj-y), $(obj-m)) -int-m := $(filter-out $(int-y), $(int-m)) - # Translate to Rules.make lists. +multi-used := $(filter $(list-multi), $(obj-y) $(obj-m)) +multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs)) +active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m)) -O_OBJS := $(filter-out $(export-objs), $(obj-y)) -OX_OBJS := $(filter $(export-objs), $(obj-y)) -M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) -MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) -MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) +O_OBJS := $(obj-y) +M_OBJS := $(obj-m) +MIX_OBJS := $(filter $(export-objs), $(active-objs)) # The global Rules.make. diff --git a/drivers/usb/acm.c b/drivers/usb/acm.c index c0fd417eb..24ca4858d 100644 --- a/drivers/usb/acm.c +++ b/drivers/usb/acm.c @@ -243,6 +243,7 @@ static void acm_read_bulk(struct urb *urb) } urb->actual_length = 0; + urb->dev = acm->dev; if (usb_submit_urb(urb)) dbg("failed resubmitting read urb"); @@ -291,9 +292,11 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) if (acm->used++) return 0; + acm->ctrlurb.dev = acm->dev; if (usb_submit_urb(&acm->ctrlurb)) dbg("usb_submit_urb(ctrl irq) failed"); + acm->readurb.dev = acm->dev; if (usb_submit_urb(&acm->readurb)) dbg("usb_submit_urb(read bulk) failed"); @@ -339,6 +342,7 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c memcpy(acm->writeurb.transfer_buffer, buf, count); acm->writeurb.transfer_buffer_length = count; + acm->writeurb.dev = acm->dev; if (usb_submit_urb(&acm->writeurb)) dbg("usb_submit_urb(write bulk) failed"); diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c index 3b2a91949..1db828b24 100644 --- a/drivers/usb/audio.c +++ b/drivers/usb/audio.c @@ -879,6 +879,7 @@ static void usbin_completed(struct urb *urb) mask = 0; printk(KERN_ERR "usbin_completed: panic: unknown URB\n"); } + urb->dev = as->state->usbdev; spin_lock_irqsave(&as->lock, flags); if (!usbin_retire_desc(u, urb) && u->flags & FLG_RUNNING && @@ -943,6 +944,7 @@ static void usbin_sync_completed(struct urb *urb) mask = 0; printk(KERN_ERR "usbin_sync_completed: panic: unknown URB\n"); } + urb->dev = as->state->usbdev; spin_lock_irqsave(&as->lock, flags); if (!usbin_sync_retire_desc(u, urb) && u->flags & FLG_RUNNING && @@ -1007,8 +1009,10 @@ static int usbin_start(struct usb_audiodev *as) } spin_lock_irqsave(&as->lock, flags); } - if (u->dma.count >= u->dma.dmasize && !u->dma.mapped) + if (u->dma.count >= u->dma.dmasize && !u->dma.mapped) { + spin_unlock_irqrestore(&as->lock, flags); return 0; + } u->flags |= FLG_RUNNING; if (!(u->flags & FLG_URB0RUNNING)) { urb = &u->durb[0].urb; @@ -1233,6 +1237,7 @@ static void usbout_completed(struct urb *urb) mask = 0; printk(KERN_ERR "usbout_completed: panic: unknown URB\n"); } + urb->dev = as->state->usbdev; spin_lock_irqsave(&as->lock, flags); if (!usbout_retire_desc(u, urb) && u->flags & FLG_RUNNING && @@ -1304,6 +1309,7 @@ static void usbout_sync_completed(struct urb *urb) mask = 0; printk(KERN_ERR "usbout_sync_completed: panic: unknown URB\n"); } + urb->dev = as->state->usbdev; spin_lock_irqsave(&as->lock, flags); if (!usbout_sync_retire_desc(u, urb) && u->flags & FLG_RUNNING && @@ -1368,8 +1374,10 @@ static int usbout_start(struct usb_audiodev *as) } spin_lock_irqsave(&as->lock, flags); } - if (u->dma.count <= 0 && !u->dma.mapped) + if (u->dma.count <= 0 && !u->dma.mapped) { + spin_unlock_irqrestore(&as->lock, flags); return 0; + } u->flags |= FLG_RUNNING; if (!(u->flags & FLG_URB0RUNNING)) { urb = &u->durb[0].urb; @@ -2768,6 +2776,14 @@ static void usb_audio_parsestreaming(struct usb_audio_state *s, unsigned char *b init_waitqueue_head(&as->usbin.dma.wait); init_waitqueue_head(&as->usbout.dma.wait); spin_lock_init(&as->lock); + spin_lock_init(&as->usbin.durb[0].urb.lock); + spin_lock_init(&as->usbin.durb[1].urb.lock); + spin_lock_init(&as->usbin.surb[0].urb.lock); + spin_lock_init(&as->usbin.surb[1].urb.lock); + spin_lock_init(&as->usbout.durb[0].urb.lock); + spin_lock_init(&as->usbout.durb[1].urb.lock); + spin_lock_init(&as->usbout.surb[0].urb.lock); + spin_lock_init(&as->usbout.surb[1].urb.lock); as->state = s; as->usbin.interface = asifin; as->usbout.interface = asifout; diff --git a/drivers/usb/bluetooth.c b/drivers/usb/bluetooth.c index 0100595cb..c543b249e 100644 --- a/drivers/usb/bluetooth.c +++ b/drivers/usb/bluetooth.c @@ -1,11 +1,16 @@ /* - * bluetooth.c Version 0.4 + * bluetooth.c Version 0.6 * * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com> * Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu> * * USB Bluetooth driver, based on the Bluetooth Spec version 1.0B * + * (10/05/2000) Version 0.6 gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * Got a real major id number and name. + * * (08/06/2000) Version 0.5 gkh * Fixed problem of not resubmitting the bulk read urb if there is * an error in the callback. Ericsson devices seem to need this. @@ -89,8 +94,8 @@ MODULE_DESCRIPTION("USB Bluetooth driver"); #define BLUETOOTH_PROGRAMMING_PROTOCOL_CODE 0x01 -#define BLUETOOTH_TTY_MAJOR 240 /* Prototype number for now */ -#define BLUETOOTH_TTY_MINORS 8 +#define BLUETOOTH_TTY_MAJOR 216 /* real device node major id */ +#define BLUETOOTH_TTY_MINORS 256 /* whole lotta bluetooth devices */ #define USB_BLUETOOTH_MAGIC 0x6d02 /* magic number for bluetooth struct */ @@ -138,11 +143,16 @@ struct usb_bluetooth { unsigned char * interrupt_in_buffer; struct urb * interrupt_in_urb; + __u8 interrupt_in_endpointAddress; + __u8 interrupt_in_interval; + int interrupt_in_buffer_size; unsigned char * bulk_in_buffer; struct urb * read_urb; + __u8 bulk_in_endpointAddress; + int bulk_in_buffer_size; - int bulk_out_size; + int bulk_out_buffer_size; struct urb * write_urb_pool[NUM_BULK_URBS]; __u8 bulk_out_endpointAddress; @@ -312,10 +322,18 @@ static int bluetooth_open (struct tty_struct *tty, struct file * filp) #ifndef BTBUGGYHARDWARE /* Start reading from the device */ + FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, + usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), + bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, + bluetooth_read_bulk_callback, bluetooth); result = usb_submit_urb(bluetooth->read_urb); if (result) dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result); #endif + FILL_INT_URB(bluetooth->interrupt_in_urb, bluetooth->dev, + usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress), + bluetooth->interrupt_in_buffer, bluetooth->interrupt_in_buffer_size, + bluetooth_int_callback, bluetooth, bluetooth->interrupt_in_interval); result = usb_submit_urb(bluetooth->interrupt_in_urb); if (result) dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result); @@ -445,7 +463,7 @@ static int bluetooth_write (struct tty_struct * tty, int from_user, const unsign urb->transfer_buffer = NULL; } - buffer_size = MIN (count, bluetooth->bulk_out_size); + buffer_size = MIN (count, bluetooth->bulk_out_buffer_size); new_buffer = kmalloc (buffer_size, GFP_KERNEL); if (new_buffer == NULL) { @@ -508,7 +526,7 @@ static int bluetooth_write_room (struct tty_struct *tty) for (i = 0; i < NUM_BULK_URBS; ++i) { if (bluetooth->write_urb_pool[i]->status != -EINPROGRESS) { - room += bluetooth->bulk_out_size; + room += bluetooth->bulk_out_buffer_size; } } @@ -627,6 +645,7 @@ static void bluetooth_set_termios (struct tty_struct *tty, struct termios * old) #ifdef BTBUGGYHARDWARE void btusb_enable_bulk_read(struct tty_struct *tty){ struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); + int result; if (!bluetooth) { return; @@ -639,9 +658,15 @@ void btusb_enable_bulk_read(struct tty_struct *tty){ return; } - if (bluetooth->read_urb) - if (usb_submit_urb(bluetooth->read_urb)) - dbg (__FUNCTION__ " - usb_submit_urb(read bulk) failed"); + if (bluetooth->read_urb) { + FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, + usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), + bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, + bluetooth_read_bulk_callback, bluetooth); + result = usb_submit_urb(bluetooth->read_urb); + if (result) + err (__FUNCTION__ " - failed submitting read urb, error %d", result); + } } void btusb_disable_bulk_read(struct tty_struct *tty){ @@ -782,14 +807,20 @@ static void bluetooth_read_bulk_callback (struct urb *urb) unsigned char *data = urb->transfer_buffer; unsigned int count = urb->actual_length; unsigned int i; - uint packet_size; + unsigned int packet_size; + int result; #ifdef BTBUGGYHARDWARE if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00) && (data[2] == 0x00) && (data[3] == 0x00)) { urb->actual_length = 0; - if (usb_submit_urb(urb)) - dbg(__FUNCTION__ " - failed resubmitting read urb"); + FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, + usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), + bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, + bluetooth_read_bulk_callback, bluetooth); + result = usb_submit_urb(bluetooth->read_urb); + if (result) + err (__FUNCTION__ " - failed resubmitting read urb, error %d", result); return; } @@ -863,8 +894,13 @@ static void bluetooth_read_bulk_callback (struct urb *urb) } exit: - if (usb_submit_urb(urb)) - dbg(__FUNCTION__ " - failed resubmitting read urb"); + FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, + usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), + bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, + bluetooth_read_bulk_callback, bluetooth); + result = usb_submit_urb(bluetooth->read_urb); + if (result) + err (__FUNCTION__ " - failed resubmitting read urb, error %d", result); return; } @@ -1027,7 +1063,8 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum) err("No free urbs available"); goto probe_error; } - buffer_size = endpoint->wMaxPacketSize; + bluetooth->bulk_in_buffer_size = buffer_size = endpoint->wMaxPacketSize; + bluetooth->bulk_in_endpointAddress = endpoint->bEndpointAddress; bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); if (!bluetooth->bulk_in_buffer) { err("Couldn't allocate bulk_in_buffer"); @@ -1050,7 +1087,7 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum) bluetooth->write_urb_pool[i] = urb; } - bluetooth->bulk_out_size = endpoint->wMaxPacketSize * 2; + bluetooth->bulk_out_buffer_size = endpoint->wMaxPacketSize * 2; endpoint = interrupt_in_endpoint[0]; bluetooth->interrupt_in_urb = usb_alloc_urb(0); @@ -1058,7 +1095,9 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum) err("No free urbs available"); goto probe_error; } - buffer_size = endpoint->wMaxPacketSize; + bluetooth->interrupt_in_buffer_size = buffer_size = endpoint->wMaxPacketSize; + bluetooth->interrupt_in_endpointAddress = endpoint->bEndpointAddress; + bluetooth->interrupt_in_interval = endpoint->bInterval; bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); if (!bluetooth->interrupt_in_buffer) { err("Couldn't allocate interrupt_in_buffer"); @@ -1070,7 +1109,7 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum) /* initialize the devfs nodes for this device and let the user know what bluetooths we are bound to */ tty_register_devfs (&bluetooth_tty_driver, 0, minor); - info("Bluetooth converter now attached to ttyBLUE%d (or usb/ttblue/%d for devfs)", minor, minor); + info("Bluetooth converter now attached to ttyUB%d (or usb/ttub/%d for devfs)", minor, minor); bluetooth_table[minor] = bluetooth; @@ -1145,7 +1184,7 @@ static void usb_bluetooth_disconnect(struct usb_device *dev, void *ptr) } } - info("Bluetooth converter now disconnected from ttyBLUE%d", bluetooth->minor); + info("Bluetooth converter now disconnected from ttyUB%d", bluetooth->minor); bluetooth_table[bluetooth->minor] = NULL; @@ -1163,7 +1202,7 @@ static void usb_bluetooth_disconnect(struct usb_device *dev, void *ptr) static struct tty_driver bluetooth_tty_driver = { magic: TTY_DRIVER_MAGIC, driver_name: "usb-bluetooth", - name: "usb/ttblue/%d", + name: "usb/ttub/%d", major: BLUETOOTH_TTY_MAJOR, minor_start: 0, num: BLUETOOTH_TTY_MINORS, diff --git a/drivers/usb/dc2xx.c b/drivers/usb/dc2xx.c index db236778d..6760e797b 100644 --- a/drivers/usb/dc2xx.c +++ b/drivers/usb/dc2xx.c @@ -65,7 +65,7 @@ /* current USB framework handles max of 16 USB devices per driver */ -#define MAX_CAMERAS 8 +#define MAX_CAMERAS 16 /* USB char devs use USB_MAJOR and from USB_CAMERA_MINOR_BASE up */ #define USB_CAMERA_MINOR_BASE 80 @@ -82,38 +82,40 @@ /* table of cameras that work through this driver */ -static const struct camera { - unsigned short idVendor; - unsigned short idProduct; - /* plus hooks for camera-specific info if needed */ -} cameras [] = { +static __devinitdata struct usb_device_id camera_table [] = { + /* These have the same application level protocol */ - { 0x040a, 0x0120 }, // Kodak DC-240 - { 0x040a, 0x0130 }, // Kodak DC-280 - { 0x040a, 0x0132 }, // Kodak DC-3400 + { idVendor: 0x040a, idProduct: 0x0120 }, // Kodak DC-240 + { idVendor: 0x040a, idProduct: 0x0130 }, // Kodak DC-280 + { idVendor: 0x040a, idProduct: 0x0131 }, // Kodak DC-5000 + { idVendor: 0x040a, idProduct: 0x0132 }, // Kodak DC-3400 /* These have a different application level protocol which * is part of the Flashpoint "DigitaOS". That supports some * non-camera devices, and some non-Kodak cameras. */ - { 0x040a, 0x0100 }, // Kodak DC-220 - { 0x040a, 0x0110 }, // Kodak DC-260 - { 0x040a, 0x0111 }, // Kodak DC-265 - { 0x040a, 0x0112 }, // Kodak DC-290 - { 0xf003, 0x6002 }, // HP PhotoSmart C500 + { idVendor: 0x040a, idProduct: 0x0100 }, // Kodak DC-220 + { idVendor: 0x040a, idProduct: 0x0110 }, // Kodak DC-260 + { idVendor: 0x040a, idProduct: 0x0111 }, // Kodak DC-265 + { idVendor: 0x040a, idProduct: 0x0112 }, // Kodak DC-290 + { idVendor: 0xf003, idProduct: 0x6002 }, // HP PhotoSmart C500 /* Other USB devices may well work here too, so long as they * just stick to half duplex bulk packet exchanges. That * means, among other things, no iso or interrupt endpoints. */ + + { } // TERMINATING ENTRY }; +MODULE_DEVICE_TABLE (usb, camera_table); + struct camera_state { struct usb_device *dev; /* USB device handle */ int inEP; /* read endpoint */ int outEP; /* write endpoint */ - const struct camera *info; /* DC-240, etc */ + const struct usb_device_id *info; /* DC-240, etc */ int subminor; /* which minor dev #? */ struct semaphore sem; /* locks this struct */ @@ -343,27 +345,15 @@ static /* const */ struct file_operations usb_camera_fops = { -static void * camera_probe(struct usb_device *dev, unsigned int ifnum) +static void * __devinit +camera_bind (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *camera_info) { int i; - const struct camera *camera_info = NULL; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; int direction, ep; struct camera_state *camera = NULL; - /* Is it a supported camera? */ - for (i = 0; i < sizeof (cameras) / sizeof (struct camera); i++) { - if (cameras [i].idVendor != dev->descriptor.idVendor) - continue; - if (cameras [i].idProduct != dev->descriptor.idProduct) - continue; - camera_info = &cameras [i]; - break; - } - if (camera_info == NULL) - return NULL; - /* these have one config, one interface */ if (dev->descriptor.bNumConfigurations != 1 || dev->config[0].bNumInterfaces != 1) { @@ -437,7 +427,8 @@ static void * camera_probe(struct usb_device *dev, unsigned int ifnum) goto error; } - info ("USB Camera #%d connected", camera->subminor); + info ("USB Camera #%d connected, major/minor %d/%d", camera->subminor, + USB_MAJOR, USB_CAMERA_MINOR_BASE + camera->subminor); camera->dev = dev; usb_inc_dev_use (dev); @@ -452,7 +443,7 @@ bye: return camera; } -static void camera_disconnect(struct usb_device *dev, void *ptr) +static void __devexit camera_disconnect(struct usb_device *dev, void *ptr) { struct camera_state *camera = (struct camera_state *) ptr; int subminor = camera->subminor; @@ -477,12 +468,14 @@ static void camera_disconnect(struct usb_device *dev, void *ptr) } static /* const */ struct usb_driver camera_driver = { - "dc2xx", - camera_probe, - camera_disconnect, - { NULL, NULL }, - &usb_camera_fops, - USB_CAMERA_MINOR_BASE + name: "dc2xx", + + id_table: camera_table, + bind: camera_bind, + disconnect: camera_disconnect, + + fops: &usb_camera_fops, + minor: USB_CAMERA_MINOR_BASE }; diff --git a/drivers/usb/devio.c b/drivers/usb/devio.c index d099394d5..2a1e12aad 100644 --- a/drivers/usb/devio.c +++ b/drivers/usb/devio.c @@ -1035,12 +1035,14 @@ static int proc_ioctl (struct dev_state *ps, void *arg) if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) { if ((buf = kmalloc (size, GFP_KERNEL)) == 0) return -ENOMEM; - if ((_IOC_DIR (ctrl.ioctl_code) & _IOC_WRITE) != 0 - && copy_from_user (buf, ctrl.data, size) != 0) { - kfree (buf); - return -EFAULT; - } else + if ((_IOC_DIR(ctrl.ioctl_code) & _IOC_WRITE)) { + if (copy_from_user (buf, ctrl.data, size)) { + kfree (buf); + return -EFAULT; + } + } else { memset (buf, 0, size); + } } /* ioctl to device */ diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c index 5ccae5103..8b9b0bfbc 100644 --- a/drivers/usb/hub.c +++ b/drivers/usb/hub.c @@ -142,6 +142,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor * the hub can/will return fewer bytes here. */ if (ret < 0) { err("Unable to get hub descriptor (err = %d)", ret); + kfree(hub->descriptor); return -1; } @@ -191,6 +192,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor ret = usb_get_hub_status(dev, &hubstatus); if (ret < 0) { err("Unable to get hub status (err = %d)", ret); + kfree(hub->descriptor); return -1; } @@ -212,6 +214,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor hub->urb = usb_alloc_urb(0); if (!hub->urb) { err("couldn't allocate interrupt urb"); + kfree(hub->descriptor); return -1; } @@ -220,6 +223,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor ret = usb_submit_urb(hub->urb); if (ret) { err("usb_submit_urb failed (%d)", ret); + kfree(hub->descriptor); return -1; } @@ -247,24 +251,32 @@ static void *hub_probe(struct usb_device *dev, unsigned int i) /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ if ((interface->bInterfaceSubClass != 0) && - (interface->bInterfaceSubClass != 1)) + (interface->bInterfaceSubClass != 1)) { + err("invalid subclass (%d) for USB hub device #%d", + interface->bInterfaceSubClass, dev->devnum); return NULL; + } /* Multiple endpoints? What kind of mutant ninja-hub is this? */ - if (interface->bNumEndpoints != 1) + if (interface->bNumEndpoints != 1) { + err("invalid bNumEndpoints (%d) for USB hub device #%d", + interface->bNumEndpoints, dev->devnum); return NULL; + } endpoint = &interface->endpoint[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { - err("Device is hub class, but has output endpoint?"); + err("Device #%d is hub class, but has output endpoint?", + dev->devnum); return NULL; } /* If it's not an interrupt endpoint, we'd better punt! */ - if ((endpoint->bmAttributes & 3) != 3) { - err("Device is hub class, but has endpoint other than interrupt?"); + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) { + err("Device #%d is hub class, but has endpoint other than interrupt?", + dev->devnum); return NULL; } @@ -291,7 +303,7 @@ static void *hub_probe(struct usb_device *dev, unsigned int i) if (usb_hub_configure(hub, endpoint) >= 0) return hub; - err("hub configuration failed"); + err("hub configuration failed for device #%d", dev->devnum); /* free hub, but first clean up its list. */ spin_lock_irqsave(&hub_event_lock, flags); @@ -539,8 +551,6 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port, tempstr = kmalloc(1024, GFP_KERNEL); portstr = kmalloc(1024, GFP_KERNEL); - if (portstr) - portstr[0] = 0; for (i = 0; i < HUB_PROBE_TRIES; i++) { struct usb_device *pdev, *cdev; @@ -567,6 +577,7 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port, cdev = dev; pdev = dev->parent; if (portstr && tempstr) { + portstr[0] = 0; while (pdev) { int port; @@ -583,25 +594,15 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port, cdev = pdev; pdev = pdev->parent; } - } - - if (portstr) info("USB new device connect on bus%d/%s, assigned device number %d", dev->bus->busnum, portstr, dev->devnum); - else + } else info("USB new device connect on bus%d, assigned device number %d", dev->bus->busnum, dev->devnum); - if (portstr) - kfree(portstr); - if (tempstr) - kfree(tempstr); - /* Run it through the hoops (find a driver, etc) */ - if (!usb_new_device(dev)) { - up(&usb_address0_sem); - return; - } + if (!usb_new_device(dev)) + goto done; /* Free the configuration if there was an error */ usb_free_dev(dev); @@ -612,7 +613,12 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port, hub->children[port] = NULL; usb_hub_port_disable(hub, port); +done: up(&usb_address0_sem); + if (portstr) + kfree(portstr); + if (tempstr) + kfree(tempstr); } static void usb_hub_events(void) @@ -794,6 +800,7 @@ int usb_hub_init(void) /* Fall through if kernel_thread failed */ usb_deregister(&hub_driver); + err("failed to start usb_hub_thread"); return -1; } diff --git a/drivers/usb/mdc800.c b/drivers/usb/mdc800.c index 80a1ebbf4..e4fc25d39 100644 --- a/drivers/usb/mdc800.c +++ b/drivers/usb/mdc800.c @@ -22,7 +22,7 @@ * (c) 1999/2000 Henning Zabel <henning@uni-paderborn.de> * * - * The driver brings the USB functions of the MDC800 to Linux. + * The driver brings the USB functions of the MDC800 to Linux. * To use the Camera you must support the USB Protocoll of the camera * to the Kernel Node. * The Driver uses a misc device Node. Create it with : @@ -30,6 +30,16 @@ * * The driver supports only one camera. * + * version 0.7.5 + * Fixed potential SMP races with Spinlocks. + * Thanks to Oliver Neukum <oliver.neukum@lrz.uni-muenchen.de> who + * noticed the race conditions. + * (30/10/2000) + * + * Fixed: Setting urb->dev before submitting urb. + * by Greg KH <greg@kroah.com> + * (13/10/2000) + * * version 0.7.3 * bugfix : The mdc800->state field gets set to READY after the * the diconnect function sets it to NOT_CONNECTED. This makes the @@ -61,7 +71,7 @@ * (09/11/1999) * * version 0.5.0: - * first Version that gets a version number. Most of the needed + * first Version that gets a version number. Most of the needed * functions work. * (20/10/1999) */ @@ -80,8 +90,8 @@ #include <linux/usb.h> -#define VERSION "0.7.3" -#define RELEASE_DATE "(24/04/2000)" +#define VERSION "0.7.5" +#define RELEASE_DATE "(30/10/2000)" /* Vendor and Product Information */ #define MDC800_VENDOR_ID 0x055f @@ -123,7 +133,7 @@ struct mdc800_data int camera_busy; // is camera busy ? int camera_request_ready; // Status to synchronize with irq - char camera_response [8]; // last Bytes send after busy + char camera_response [8]; // last Bytes send after busy purb_t write_urb; char* write_urb_buffer; @@ -138,16 +148,16 @@ struct mdc800_data /* Device Data */ char out [64]; // Answer Buffer - int out_ptr; // Index to the first not readen byte + int out_ptr; // Index to the first not readen byte int out_count; // Bytes in the buffer - int open; // Camera device open ? - int rw_lock; // Block read <-> write + int open; // Camera device open ? + spinlock_t io_lock; // IO -lock - char in [8]; // Command Input Buffer + char in [8]; // Command Input Buffer int in_count; - int pic_index; // Cache for the Imagesize (-1 for nothing cached ) + int pic_index; // Cache for the Imagesize (-1 for nothing cached ) int pic_len; }; @@ -253,16 +263,16 @@ static void mdc800_usb_irq (struct urb *urb) } } wake_up= ( mdc800->camera_request_ready > 0 ) - && - ( - ((mdc800->camera_request_ready == 1) && (!mdc800->camera_busy)) - || - ((mdc800->camera_request_ready == 2) && data_received) - || - ((mdc800->camera_request_ready == 3) && (mdc800->camera_busy)) - || - (urb->status < 0) - ); + && + ( + ((mdc800->camera_request_ready == 1) && (!mdc800->camera_busy)) + || + ((mdc800->camera_request_ready == 2) && data_received) + || + ((mdc800->camera_request_ready == 3) && (mdc800->camera_busy)) + || + (urb->status < 0) + ); if (wake_up) { @@ -362,7 +372,7 @@ static struct usb_driver mdc800_usb_driver; */ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum ) { - int i,j; + int i,j; struct usb_interface_descriptor *intf_desc; int irq_interval=0; @@ -432,10 +442,10 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum ) info ("Found Mustek MDC800 on USB."); + spin_lock (&mdc800->io_lock); + mdc800->dev=dev; - mdc800->state=READY; mdc800->open=0; - mdc800->rw_lock=0; /* Setup URB Structs */ FILL_INT_URB ( @@ -469,6 +479,10 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum ) mdc800 ); + mdc800->state=READY; + + spin_unlock (&mdc800->io_lock); + return mdc800; } @@ -539,18 +553,21 @@ static int mdc800_getAnswerSize (char command) static int mdc800_device_open (struct inode* inode, struct file *file) { int retval=0; + int errn=0; + + spin_lock (&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) { - return -EBUSY; + errn=-EBUSY; + goto error_out; } - if (mdc800->open) { - return -EBUSY; + errn=-EBUSY; + goto error_out; } - mdc800->rw_lock=0; mdc800->in_count=0; mdc800->out_count=0; mdc800->out_ptr=0; @@ -562,16 +579,20 @@ static int mdc800_device_open (struct inode* inode, struct file *file) mdc800->camera_request_ready=0; retval=0; + mdc800->irq_urb->dev = mdc800->dev; if (usb_submit_urb (mdc800->irq_urb)) { err ("request USB irq fails (submit_retval=%i urb_status=%i).",retval, mdc800->irq_urb->status); - return -EIO; + errn = -EIO; + goto error_out; } mdc800->open=1; - dbg ("Mustek MDC800 device opened."); - return 0; + +error_out: + spin_unlock (&mdc800->io_lock); + return errn; } @@ -583,7 +604,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file) int retval=0; dbg ("Mustek MDC800 device closed."); - lock_kernel(); + spin_lock (&mdc800->io_lock); if (mdc800->open && (mdc800->state != NOT_CONNECTED)) { mdc800->open=0; @@ -595,7 +616,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file) { retval=-EIO; } - unlock_kernel(); + spin_unlock (&mdc800->io_lock); return retval; } @@ -609,23 +630,29 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof int left=len, sts=len; /* single transfer size */ char* ptr=buf; + spin_lock (&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) + { + spin_unlock (&mdc800->io_lock); return -EBUSY; - + } if (mdc800->state == WORKING) { warn ("Illegal State \"working\" reached during read ?!"); + spin_unlock (&mdc800->io_lock); return -EBUSY; } - - if (!mdc800->open || mdc800->rw_lock) + if (!mdc800->open) + { + spin_unlock (&mdc800->io_lock); return -EBUSY; - mdc800->rw_lock=1; + } while (left) { - if (signal_pending (current)) { - mdc800->rw_lock=0; + if (signal_pending (current)) + { + spin_unlock (&mdc800->io_lock); return -EINTR; } @@ -640,24 +667,25 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof mdc800->out_ptr=0; /* Download -> Request new bytes */ + mdc800->download_urb->dev = mdc800->dev; if (usb_submit_urb (mdc800->download_urb)) { err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return len-left; } interruptible_sleep_on_timeout (&mdc800->download_wait, TO_DOWNLOAD_GET_READY*HZ/1000); if (mdc800->download_urb->status != 0) { err ("request download-bytes fails (status=%i)",mdc800->download_urb->status); - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return len-left; } } else { /* No more bytes -> that's an error*/ - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return -EIO; } } @@ -671,7 +699,7 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof } } - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return len-left; } @@ -686,17 +714,23 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l { int i=0; + spin_lock (&mdc800->io_lock); if (mdc800->state != READY) + { + spin_unlock (&mdc800->io_lock); return -EBUSY; - - if (!mdc800->open || mdc800->rw_lock) + } + if (!mdc800->open ) + { + spin_unlock (&mdc800->io_lock); return -EBUSY; - mdc800->rw_lock=1; + } while (i<len) { - if (signal_pending (current)) { - mdc800->rw_lock=0; + if (signal_pending (current)) + { + spin_unlock (&mdc800->io_lock); return -EINTR; } @@ -718,7 +752,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l else { err ("Command is to long !\n"); - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return -EIO; } @@ -730,7 +764,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l if (mdc800_usb_waitForIRQ (0,TO_GET_READY)) { err ("Camera didn't get ready.\n"); - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return -EIO; } @@ -738,17 +772,18 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l mdc800->state=WORKING; memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8); + mdc800->write_urb->dev = mdc800->dev; if (usb_submit_urb (mdc800->write_urb)) { err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return -EIO; } interruptible_sleep_on_timeout (&mdc800->write_wait, TO_WRITE_GET_READY*HZ/1000); if (mdc800->state == WORKING) { usb_unlink_urb (mdc800->write_urb); - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return -EIO; } @@ -760,7 +795,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l { err ("call 0x07 before 0x05,0x3e"); mdc800->state=READY; - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return -EIO; } mdc800->pic_len=-1; @@ -779,7 +814,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ)) { err ("requesting answer from irq fails"); - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return -EIO; } @@ -807,7 +842,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND)) { err ("Command Timeout."); - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return -EIO; } } @@ -817,7 +852,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l } i++; } - mdc800->rw_lock=0; + spin_unlock (&mdc800->io_lock); return i; } @@ -866,10 +901,11 @@ int __init usb_mdc800_init (void) /* Allocate Memory */ try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL)); + memset(mdc800, 0, sizeof(struct mdc800_data)); mdc800->dev=0; mdc800->open=0; mdc800->state=NOT_CONNECTED; - memset(mdc800, 0, sizeof(struct mdc800_data)); + spin_lock_init (&mdc800->io_lock); init_waitqueue_head (&mdc800->irq_wait); init_waitqueue_head (&mdc800->write_wait); diff --git a/drivers/usb/net1080.c b/drivers/usb/net1080.c index 044e72b4a..bdfe71eb4 100644 --- a/drivers/usb/net1080.c +++ b/drivers/usb/net1080.c @@ -45,16 +45,18 @@ #include <linux/usb.h> -static const struct product { - char *name; - u16 idVendor; - u16 idProduct; -} products [] = { - { "NetChip TurboCONNECT", 0x0525, 0x1080 }, // reference +static const struct usb_device_id products [] = { + { // reference design + idProduct: 0x1080, + idVendor: 0x0525, + driver_info: (unsigned long) "NetChip TurboCONNECT", + }, // Belkin, ... - { 0, 0, 0 }, // END + { }, // END }; +MODULE_DEVICE_TABLE (usb, products); + static u8 node_id [ETH_ALEN]; @@ -91,6 +93,7 @@ struct nc_trailer { + (mtu) \ + 1 \ + sizeof (struct nc_trailer)) +#define MAX_PACKET 8191 // zero means no timeout; else, how long a 64 byte bulk // read may be queued before HW flushes it. @@ -132,7 +135,7 @@ struct skb_data { // skb->cb is one of these struct net1080 { // housekeeping struct usb_device *udev; - const struct product *prod_info; + const struct usb_device_id *prod_info; struct semaphore mutex; struct list_head dev_list; wait_queue_head_t *wait; @@ -422,7 +425,7 @@ static int net1080_reset (struct net1080 *dev) #endif info ("%s: %s, port %c on USB %d dev %d, peer %sconnected", - dev->net.name, dev->prod_info->name, + dev->net.name, (char *) dev->prod_info->driver_info, (status & STATUS_PORT_A) ? 'A' : 'B', dev->udev->bus->busnum, dev->udev->devnum, @@ -443,7 +446,7 @@ done: static int net1080_change_mtu (struct net_device *net, int new_mtu) { - if ((new_mtu < 0) || NC_MAX_PACKET (new_mtu) > 8191) + if ((new_mtu < 0) || NC_MAX_PACKET (new_mtu) > MAX_PACKET) return -EINVAL; net->mtu = new_mtu; return 0; @@ -518,8 +521,7 @@ static void rx_complete (struct urb *urb) entry->state = rx_done; entry->urb = 0; - if ((urb->transfer_flags & USB_ASYNC_UNLINK) != 0 - || netif_queue_stopped (&dev->net)) { + if ((urb->transfer_flags & USB_ASYNC_UNLINK) != 0) { dbg ("rx ... shutting down"); usb_free_urb (urb); urb = 0; @@ -528,12 +530,17 @@ static void rx_complete (struct urb *urb) switch (urb_status) { // success case 0: - if (skb->len & 0x01) - break; - entry->state = rx_cleanup; - dev->stats.rx_errors++; - dev->stats.rx_length_errors++; - dbg ("even rx len %d", skb->len); + if (!(skb->len & 0x01)) { + entry->state = rx_cleanup; + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; + dbg ("even rx len %d", skb->len); + } else if (skb->len > MAX_PACKET) { + entry->state = rx_cleanup; + dev->stats.rx_errors++; + dev->stats.rx_frame_errors++; + dbg ("rx too big, %d", skb->len); + } break; // hardware-reported interface shutdown ... which we @@ -816,10 +823,18 @@ static void rx_process (struct net1080 *dev, struct sk_buff *skb) header = (struct nc_header *) skb->data; le16_to_cpus (&header->hdr_len); le16_to_cpus (&header->packet_len); - if (header->hdr_len < NC_MIN_HEADER) { + if (header->packet_len > MAX_PACKET) { + dev->stats.rx_frame_errors++; + dbg ("packet too big, %d", header->packet_len); + goto error; + } else if (header->hdr_len < NC_MIN_HEADER) { dev->stats.rx_frame_errors++; dbg ("header too short, %d", header->hdr_len); goto error; + } else if (header->hdr_len > header->packet_len) { + dev->stats.rx_frame_errors++; + dbg ("header too big, %d packet %d", header->hdr_len, header->packet_len); + goto error; } else if (header->hdr_len != sizeof *header) { // out of band data for us? dbg ("header OOB, %d bytes", header->hdr_len - NC_MIN_HEADER); @@ -952,7 +967,7 @@ static void net1080_disconnect (struct usb_device *udev, void *ptr) info ("%s: USB %d dev %d, %s, disconnected", dev->net.name, udev->bus->busnum, udev->devnum, - dev->prod_info->name); + (char *) dev->prod_info->driver_info); unregister_netdev (&dev->net); @@ -973,24 +988,14 @@ static void net1080_disconnect (struct usb_device *udev, void *ptr) // precondition: never called in_interrupt -static void *net1080_probe (struct usb_device *udev, unsigned ifnum) +static void * +net1080_bind (struct usb_device *udev, unsigned ifnum, const struct usb_device_id *prod) { - int i; struct net1080 *dev; struct net_device *net; struct usb_interface_descriptor *interface; int retval; - for (i = 0; products [i].idVendor != 0; i++) { - if (products [i].idVendor != udev->descriptor.idVendor) - continue; - if (products [i].idProduct != udev->descriptor.idProduct) - continue; - break; - } - if (products [i].idVendor == 0) - return 0; - // sanity check; expect dedicated interface/devices for now. interface = &udev->actconfig->interface [ifnum].altsetting[0]; if (udev->descriptor.bNumConfigurations != 1 @@ -1013,7 +1018,7 @@ static void *net1080_probe (struct usb_device *udev, unsigned ifnum) init_MUTEX_LOCKED (&dev->mutex); usb_inc_dev_use (udev); dev->udev = udev; - dev->prod_info = &products [i]; + dev->prod_info = prod; INIT_LIST_HEAD (&dev->dev_list); skb_queue_head_init (&dev->rxq); skb_queue_head_init (&dev->txq); @@ -1067,7 +1072,8 @@ static void *net1080_probe (struct usb_device *udev, unsigned ifnum) static struct usb_driver net1080_driver = { name: "net1080", - probe: net1080_probe, + id_table: products, + bind: net1080_bind, disconnect: net1080_disconnect, }; diff --git a/drivers/usb/pegasus.c b/drivers/usb/pegasus.c index a58c29c8e..02c1eff80 100644 --- a/drivers/usb/pegasus.c +++ b/drivers/usb/pegasus.c @@ -14,11 +14,13 @@ ** v0.4.0 Control messages remained unurbified are now URBs. ** Now we can touch the HW at any time. ** v0.4.9 Control urbs again use process context to wait. Argh... -** Some long standing bugs (start_net) fixed. Also nasty -** trick with resubmiting control urb from interrupt -** context used. Please let me know how it behaves. -** Pegasus II support added since this version. +** Some long standing bugs (enable_net_traffic) fixed. +** Also nasty trick about resubmiting control urb from +** interrupt context used. Please let me know how it +** behaves. Pegasus II support added since this version. ** TODO: suppressing HCD warnings spewage on disconnect. +** v0.4.13 Ethernet address is now set at probe(), not at open() +** time as this seems to break dhcpd. */ /* @@ -48,7 +50,7 @@ #include <linux/usb.h> -static const char *version = __FILE__ ": v0.4.9 2000/09/14 (C) 1999-2000 Petko Manolov (petkan@dce.bg)"; +static const char *version = __FILE__ ": v0.4.13 2000/10/13 (C) 1999-2000 Petko Manolov (petkan@dce.bg)"; #define PEGASUS_USE_INTR @@ -81,10 +83,13 @@ static const char *version = __FILE__ ": v0.4.9 2000/09/14 (C) 1999-2000 Petko M #define LINKSYS_GPIO_RESET 0x24 #define DEFAULT_GPIO_SET 0x26 -#define PEGASUS_PRESENT 1 -#define PEGASUS_RUNNING 2 -#define CTRL_URB_RUNNING 4 -#define CTRL_URB_SLEEP 8 +#define PEGASUS_PRESENT 0x00000001 +#define PEGASUS_RUNNING 0x00000002 +#define PEGASUS_TX_BUSY 0x00000004 +#define PEGASUS_RX_BUSY 0x00000008 +#define CTRL_URB_RUNNING 0x00000010 +#define CTRL_URB_SLEEP 0x00000020 +#define PEGASUS_UNPLUG 0x00000040 #define ETH_REGS_CHANGE 0x40000000 #define ETH_REGS_CHANGED 0x80000000 @@ -94,12 +99,6 @@ static const char *version = __FILE__ ": v0.4.9 2000/09/14 (C) 1999-2000 Petko M #define REG_TIMEOUT (HZ) #define PEGASUS_TX_TIMEOUT (HZ*10) -#ifdef PEGASUS_USE_INTR - #define INTR_IVAL 0x80 -#else - #define INTR_IVAL 0 -#endif - #define TX_UNDERRUN 0x80 #define EXCESSIVE_COL 0x40 #define LATE_COL 0x20 @@ -144,6 +143,7 @@ typedef struct pegasus { struct net_device_stats stats; unsigned flags; unsigned features; + int intr_interval; struct urb ctrl_urb, rx_urb, tx_urb, intr_urb; devrequest dr; wait_queue_head_t ctrl_wait; @@ -165,7 +165,7 @@ struct usb_eth_dev { static int loopback = 0; -static int mode = 0; +static int mii_mode = 0; static int multicast_filter_limit = 32; @@ -183,13 +183,14 @@ static struct usb_eth_dev usb_dev_id[] = { {"MELCO/BUFFALO LUA-TX", 0x0411, 0x0001, DEFAULT_GPIO_RESET}, {"D-Link DSB-650TX", 0x2001, 0x4001, LINKSYS_GPIO_RESET}, {"D-Link DSB-650TX", 0x2001, 0x4002, LINKSYS_GPIO_RESET}, - {"D-Link DSB-650TX(PNA)", 0x2001, 0x4003, DEFAULT_GPIO_RESET}, + {"D-Link DSB-650TX(PNA)", 0x2001, 0x4003, + HAS_HOME_PNA | DEFAULT_GPIO_RESET}, {"D-Link DSB-650", 0x2001, 0xabc1, DEFAULT_GPIO_RESET}, {"D-Link DU-E10", 0x07b8, 0xabc1, DEFAULT_GPIO_RESET}, {"D-Link DU-E100", 0x07b8, 0x4002, DEFAULT_GPIO_RESET}, {"Linksys USB10TX", 0x066b, 0x2202, LINKSYS_GPIO_RESET}, {"Linksys USB100TX", 0x066b, 0x2203, LINKSYS_GPIO_RESET}, - {"Linksys USB100TX", 0x066b, 0x2204, LINKSYS_GPIO_RESET}, + {"Linksys USB100TX", 0x066b, 0x2204, HAS_HOME_PNA | LINKSYS_GPIO_RESET}, {"Linksys USB Ethernet Adapter", 0x066b, 0x2206, LINKSYS_GPIO_RESET}, {"SMC 202 USB Ethernet", 0x0707, 0x0200, DEFAULT_GPIO_RESET}, {"ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)", 0x07a6, 0x0986, @@ -209,7 +210,7 @@ static int update_eth_regs_async( pegasus_t * ); /* Aargh!!! I _really_ hate such tweaks */ static void ctrl_callback( urb_t *urb ) { - pegasus_t *pegasus = urb->context; + pegasus_t *pegasus = urb->context; if ( !pegasus ) return; @@ -260,11 +261,11 @@ static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) { err( __FUNCTION__ " BAD CTRLs %d", ret); - return ret; + goto out; } pegasus->flags |= CTRL_URB_SLEEP; interruptible_sleep_on( &pegasus->ctrl_wait ); - +out: return ret; } @@ -419,7 +420,7 @@ static int read_eprom_word( pegasus_t *pegasus, __u8 index, __u16 *retdata ) return -1; } - +#ifdef PEGASUS_WRITE_EEPROM static inline void enable_eprom_write( pegasus_t *pegasus ) { __u8 tmp; @@ -461,40 +462,24 @@ static int write_eprom_word( pegasus_t *pegasus, __u8 index, __u16 data ) warn( __FUNCTION__ " failed" ); return -1; } +#endif /* PEGASUS_WRITE_EEPROM */ - -static void set_intr_interval( pegasus_t *pegasus ) +static inline void get_node_id( pegasus_t *pegasus, __u8 *id ) { - __u16 d; - __u8 tmp; + int i; - read_eprom_word( pegasus, 4, &d ); - ((__u8 *)&d)[1] = INTR_IVAL; - write_eprom_word( pegasus, 4, d ); - get_registers( pegasus, EthCtrl2, 1, &tmp ); - set_register( pegasus, EthCtrl2, tmp | EPROM_LOAD ); - udelay( 10000 ); - set_register( pegasus, EthCtrl2, tmp ); -#ifdef PEGASUS_DUMP_EEPROM - { int i; - for ( i=0; i < 0x40; i++ ) { - read_eprom_word( pegasus, i, &d ); - printk( "eepromword %02x-%04x, ", i, d ); - } - printk( "\n" ); - } -#endif + for (i = 0; i < 3; i++) + read_eprom_word( pegasus, i, (__u16 *)&id[i*2]); } -static inline int get_node_id( pegasus_t *pegasus, __u8 *id ) +static void set_ethernet_addr( pegasus_t *pegasus ) { - int i; + __u8 node_id[6]; - for (i = 0; i < 3; i++) - if ( read_eprom_word( pegasus, i, (__u16 *)&id[i*2]) ) - return 1; - return 0; + get_node_id(pegasus, node_id); + set_registers( pegasus, EthID, sizeof(node_id), node_id ); + memcpy( pegasus->net->dev_addr, node_id, sizeof(node_id) ); } @@ -509,7 +494,7 @@ static inline int reset_mac( pegasus_t *pegasus ) if (~data & 0x08) { if (loopback & 1) break; - if ( mode && (pegasus->features & HAS_HOME_PNA) ) + if ( mii_mode && (pegasus->features & HAS_HOME_PNA) ) set_register( pegasus, Gpio1, 0x34 ); else set_register( pegasus, Gpio1, 0x26 ); @@ -524,18 +509,13 @@ static inline int reset_mac( pegasus_t *pegasus ) } -static int start_net( struct net_device *dev, struct usb_device *usb ) +static int enable_net_traffic( struct net_device *dev, struct usb_device *usb ) { __u16 linkpart, bmsr; - __u8 node_id[6]; __u8 data[4]; pegasus_t *pegasus = dev->priv; - if ( get_node_id(pegasus, node_id) ) - return 1; - set_registers( pegasus, EthID, sizeof(node_id), node_id ); - memcpy( dev->dev_addr, node_id, sizeof(node_id) ); if ( read_phy_word(pegasus, pegasus->phy, MII_BMSR, &bmsr) ) return 2; if ( !(bmsr & 0x20) && !loopback ) @@ -552,7 +532,7 @@ static int start_net( struct net_device *dev, struct usb_device *usb ) data[1] |= 0x20; /* set full duplex */ if ( linkpart & (ANLPA_100TX_FD | ANLPA_100TX_HD) ) data[1] |= 0x10; /* set 100 Mbps */ - if ( mode ) + if ( mii_mode ) data[1] = 0; data[2] = (loopback & 1) ? 0x09 : 0x01; @@ -577,6 +557,15 @@ static void read_bulk_callback( struct urb *urb ) return; net = pegasus->net; + if ( !netif_device_present(net) ) + return; + + if ( pegasus->flags & PEGASUS_RX_BUSY ) { + pegasus->stats.rx_errors++; + return; + } + pegasus->flags |= PEGASUS_RX_BUSY; + rx_status = *(int *)(pegasus->rx_buff + count - 4); if (urb->status) { @@ -617,9 +606,13 @@ static void read_bulk_callback( struct urb *urb ) pegasus->stats.rx_bytes += pkt_len; goon: - pegasus->rx_urb.dev = pegasus->usb; + FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb, + usb_rcvbulkpipe(pegasus->usb, 1), + pegasus->rx_buff, PEGASUS_MAX_MTU, + read_bulk_callback, pegasus ); if ( (res = usb_submit_urb(&pegasus->rx_urb)) ) warn( __FUNCTION__ " failed submint rx_urb %d", res); + pegasus->flags &= ~PEGASUS_RX_BUSY; } @@ -629,13 +622,17 @@ static void write_bulk_callback( struct urb *urb ) if ( !pegasus || !(pegasus->flags & PEGASUS_RUNNING) ) return; + + if ( !netif_device_present(pegasus->net) ) + return; + if ( urb->status ) info("%s: TX status %d", pegasus->net->name, urb->status); - netif_wake_queue(pegasus->net); + netif_wake_queue( pegasus->net ); } - +#ifdef PEGASUS_USE_INTR static void intr_callback( struct urb *urb ) { pegasus_t *pegasus = urb->context; @@ -666,7 +663,7 @@ static void intr_callback( struct urb *urb ) info("intr status %d", urb->status); } } - +#endif static void pegasus_tx_timeout( struct net_device *net ) { @@ -675,12 +672,12 @@ static void pegasus_tx_timeout( struct net_device *net ) if ( !pegasus ) return; - usb_unlink_urb(&pegasus->tx_urb); + usb_unlink_urb( &pegasus->tx_urb ); warn("%s: Tx timed out.", net->name); pegasus->stats.tx_errors++; net->trans_start = jiffies; - netif_wake_queue(net); + netif_wake_queue( net ); } @@ -690,20 +687,20 @@ static int pegasus_start_xmit( struct sk_buff *skb, struct net_device *net ) int count = ((skb->len+2) & 0x3f) ? skb->len+2 : skb->len+3; int res; - netif_stop_queue(net); - if ( !(pegasus->flags & PEGASUS_RUNNING) ) - return 0; - + netif_stop_queue( net ); + ((__u16 *)pegasus->tx_buff)[0] = skb->len; memcpy(pegasus->tx_buff+2, skb->data, skb->len); + FILL_BULK_URB( &pegasus->tx_urb, pegasus->usb, + usb_sndbulkpipe(pegasus->usb, 2), + pegasus->tx_buff, PEGASUS_MAX_MTU, + write_bulk_callback, pegasus ); pegasus->tx_urb.transfer_buffer_length = count; pegasus->tx_urb.transfer_flags |= USB_ASYNC_UNLINK; - - pegasus->tx_urb.dev = pegasus->usb; if ((res = usb_submit_urb(&pegasus->tx_urb))) { warn("failed tx_urb %d", res); pegasus->stats.tx_errors++; - netif_start_queue(net); + netif_start_queue( net ); } else { pegasus->stats.tx_packets++; pegasus->stats.tx_bytes += skb->len; @@ -722,7 +719,7 @@ static struct net_device_stats *pegasus_netdev_stats( struct net_device *dev ) } -static inline void stop_net( pegasus_t *pegasus ) +static inline void disable_net_traffic( pegasus_t *pegasus ) { int tmp=0; @@ -730,23 +727,41 @@ static inline void stop_net( pegasus_t *pegasus ) } +static inline void get_interrupt_interval( pegasus_t *pegasus ) +{ + __u8 data[2]; + + read_eprom_word( pegasus, 4, (__u16 *)data ); + pegasus->intr_interval = data[1]; +} + + static int pegasus_open(struct net_device *net) { pegasus_t *pegasus = (pegasus_t *)net->priv; int res; - if ((res = start_net(net, pegasus->usb))) { - err("can't start_net() - %d", res); + MOD_INC_USE_COUNT; + if ( (res = enable_net_traffic(net, pegasus->usb)) ) { + err("can't enable_net_traffic() - %d", res); + MOD_DEC_USE_COUNT; return -EIO; } - pegasus->rx_urb.dev = pegasus->usb; + FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb, + usb_rcvbulkpipe(pegasus->usb, 1), + pegasus->rx_buff, PEGASUS_MAX_MTU, + read_bulk_callback, pegasus ); if ( (res = usb_submit_urb(&pegasus->rx_urb)) ) warn( __FUNCTION__ " failed rx_urb %d", res ); #ifdef PEGASUS_USE_INTR - pegasus->intr_urb.dev = pegasus->usb; + get_interrupt_interval( pegasus ); + FILL_INT_URB( &pegasus->intr_urb, pegasus->usb, + usb_rcvintpipe(pegasus->usb, 3), + pegasus->intr_buff, sizeof(pegasus->intr_buff), + intr_callback, pegasus, pegasus->intr_interval ); if ( (res = usb_submit_urb(&pegasus->intr_urb)) ) warn( __FUNCTION__ " failed intr_urb %d", res); -#endif +#endif netif_start_queue( net ); pegasus->flags |= PEGASUS_RUNNING; @@ -758,15 +773,18 @@ static int pegasus_close( struct net_device *net ) { pegasus_t *pegasus = net->priv; - stop_net( pegasus ); pegasus->flags &= ~PEGASUS_RUNNING; - netif_stop_queue(net); + netif_stop_queue( net ); + if ( !(pegasus->flags & PEGASUS_UNPLUG) ) + disable_net_traffic( pegasus ); usb_unlink_urb( &pegasus->rx_urb ); usb_unlink_urb( &pegasus->tx_urb ); usb_unlink_urb( &pegasus->ctrl_urb ); usb_unlink_urb( &pegasus->intr_urb ); + MOD_DEC_USE_COUNT; + return 0; } @@ -855,7 +873,7 @@ static inline void setup_pegasus_II( pegasus_t *pegasus ) { set_register( pegasus, Reg1d, 0 ); set_register( pegasus, Reg7b, 2 ); - if ( pegasus->features & HAS_HOME_PNA ) + if ( pegasus->features & HAS_HOME_PNA && mii_mode ) set_register( pegasus, Reg81, 6 ); else set_register( pegasus, Reg81, 2 ); @@ -881,37 +899,33 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum ) err("out of memory allocating device structure"); return NULL; } + + usb_inc_dev_use( dev ); memset(pegasus, 0, sizeof(struct pegasus)); + init_MUTEX( &pegasus-> ctrl_sem ); + init_waitqueue_head( &pegasus->ctrl_wait ); - net = init_etherdev(0, 0); + net = init_etherdev( NULL, 0 ); + if ( !net ) { + kfree( pegasus ); + return NULL; + } + + pegasus->usb = dev; + pegasus->net = net; net->priv = pegasus; net->open = pegasus_open; net->stop = pegasus_close; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,48) net->watchdog_timeo = PEGASUS_TX_TIMEOUT; net->tx_timeout = pegasus_tx_timeout; +#endif net->do_ioctl = pegasus_ioctl; net->hard_start_xmit = pegasus_start_xmit; net->set_multicast_list = pegasus_set_multicast; net->get_stats = pegasus_netdev_stats; net->mtu = PEGASUS_MTU; - init_MUTEX( &pegasus-> ctrl_sem ); - init_waitqueue_head( &pegasus->ctrl_wait ); - - usb_inc_dev_use (dev); - pegasus->usb = dev; - pegasus->net = net; - - FILL_BULK_URB( &pegasus->rx_urb, dev, usb_rcvbulkpipe(dev, 1), - pegasus->rx_buff, PEGASUS_MAX_MTU, - read_bulk_callback, pegasus ); - FILL_BULK_URB( &pegasus->tx_urb, dev, usb_sndbulkpipe(dev, 2), - pegasus->tx_buff, PEGASUS_MAX_MTU, - write_bulk_callback, pegasus ); - FILL_INT_URB( &pegasus->intr_urb, dev, usb_rcvintpipe(dev, 3), - pegasus->intr_buff, 8, intr_callback, - pegasus, INTR_IVAL ); - pegasus->features = usb_dev_id[dev_indx].private; if ( reset_mac(pegasus) ) { err("can't reset MAC"); @@ -921,23 +935,21 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum ) return NULL; } + set_ethernet_addr( pegasus ); + if ( pegasus->features & PEGASUS_II ) { info( "setup Pegasus II specific registers" ); setup_pegasus_II( pegasus ); } - + pegasus->phy = mii_phy_probe( pegasus ); if ( !pegasus->phy ) { warn( "can't locate MII phy, using default" ); pegasus->phy = 1; } - set_intr_interval( pegasus ); - info( "%s: %s", net->name, usb_dev_id[dev_indx].name ); - MOD_INC_USE_COUNT; - return pegasus; } @@ -951,16 +963,11 @@ static void pegasus_disconnect( struct usb_device *dev, void *ptr ) return; } - stop_net( pegasus ); - pegasus->flags &= ~PEGASUS_RUNNING; - netif_stop_queue( pegasus->net ); + pegasus->flags |= PEGASUS_UNPLUG; unregister_netdev( pegasus->net ); - - usb_dec_dev_use (pegasus->usb); + usb_dec_dev_use( dev ); kfree( pegasus ); pegasus = NULL; - - MOD_DEC_USE_COUNT; } diff --git a/drivers/usb/plusb.c b/drivers/usb/plusb.c index a8ffa3aba..d3d1b4e6a 100644 --- a/drivers/usb/plusb.c +++ b/drivers/usb/plusb.c @@ -245,6 +245,7 @@ static void plusb_int_complete(urb_t *purb) return; } + s->bulkurb->dev = s->usbdev; ret=usb_submit_urb(s->bulkurb); if(ret && ret!=-EBUSY) { err("plusb_int_complete: usb_submit_urb failed"); diff --git a/drivers/usb/printer.c b/drivers/usb/printer.c index bbbc05f33..7614373cf 100644 --- a/drivers/usb/printer.c +++ b/drivers/usb/printer.c @@ -52,6 +52,7 @@ #define IOCNR_GET_DEVICE_ID 1 #define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len) /* get device_id string */ +#define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */ /* * A DEVICE_ID string may include the printer's serial number. @@ -179,10 +180,19 @@ static int usblp_open(struct inode *inode, struct file *file) if (usblp->used) goto out; + /* + * TODO: need to implement LP_ABORTOPEN + O_NONBLOCK as in drivers/char/lp.c ??? + * This is #if 0-ed because we *don't* want to fail an open + * just because the printer is off-line. + */ +#if 0 if ((retval = usblp_check_status(usblp, 0))) { retval = retval > 1 ? -EIO : -ENOSPC; goto out; } +#else + retval = 0; +#endif usblp->used = 1; file->private_data = usblp; @@ -192,6 +202,7 @@ static int usblp_open(struct inode *inode, struct file *file) if (usblp->bidir) { usblp->readcount = 0; + usblp->readurb.dev = usblp->dev; usb_submit_urb(&usblp->readurb); } out: @@ -231,30 +242,59 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct usblp *usblp = file->private_data; - int length; + int length, err; + unsigned char status; - if ((_IOC_TYPE(cmd) != 'P') || (_IOC_DIR(cmd) != _IOC_READ)) - return -EINVAL; + if (_IOC_TYPE(cmd) == 'P') /* new-style ioctl number */ + + switch (_IOC_NR(cmd)) { - switch (_IOC_NR(cmd)) { + case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */ + if (_IOC_DIR(cmd) != _IOC_READ) + return -EINVAL; - case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */ + err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1); + if (err < 0) { + dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string", + usblp->minor, err); + usblp->device_id_string[0] = usblp->device_id_string[1] = '\0'; + return -EIO; + } - length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */ + length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */ + if (length < DEVICE_ID_SIZE) + usblp->device_id_string[length] = '\0'; + else + usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0'; - dbg ("usblp_ioctl GET_DEVICE_ID actlen: %d, size: %d, string: '%s'", - length, _IOC_SIZE(cmd), &usblp->device_id_string[2]); + dbg ("usblp%d Device ID string [%d/max %d]='%s'", + usblp->minor, length, _IOC_SIZE(cmd), &usblp->device_id_string[2]); - if (length > _IOC_SIZE(cmd)) length = _IOC_SIZE(cmd); /* truncate */ + if (length > _IOC_SIZE(cmd)) length = _IOC_SIZE(cmd); /* truncate */ - if (copy_to_user((unsigned char *) arg, usblp->device_id_string, (unsigned long) length)) - return -EFAULT; + if (copy_to_user((unsigned char *) arg, usblp->device_id_string, (unsigned long) length)) + return -EFAULT; - break; + break; - default: - return -EINVAL; - } + default: + return -EINVAL; + } + else /* old-style ioctl value */ + switch (cmd) { + + case LPGETSTATUS: + if (usblp_read_status(usblp, &status)) { + err("usblp%d: failed reading printer status", usblp->minor); + return -EIO; + } + if (copy_to_user ((unsigned char *)arg, &status, 1)) + return -EFAULT; + break; + + default: + return -EINVAL; + } return 0; } @@ -301,6 +341,7 @@ static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, if (copy_from_user(usblp->writeurb.transfer_buffer, buffer + writecount, usblp->writeurb.transfer_buffer_length)) return -EFAULT; + usblp->writeurb.dev = usblp->dev; usb_submit_urb(&usblp->writeurb); } @@ -332,6 +373,7 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t if (usblp->readurb.status) { err("usblp%d: error %d reading from printer", usblp->minor, usblp->readurb.status); + usblp->readurb.dev = usblp->dev; usb_submit_urb(&usblp->readurb); return -EIO; } @@ -342,8 +384,11 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t if (copy_to_user(buffer, usblp->readurb.transfer_buffer + usblp->readcount, count)) return -EFAULT; - if ((usblp->readcount += count) == usblp->readurb.actual_length) + if ((usblp->readcount += count) == usblp->readurb.actual_length) { + usblp->readcount = 0; + usblp->readurb.dev = usblp->dev; usb_submit_urb(&usblp->readurb); + } return count; } diff --git a/drivers/usb/rio500.c b/drivers/usb/rio500.c index 59c97376e..e40e6c30f 100644 --- a/drivers/usb/rio500.c +++ b/drivers/usb/rio500.c @@ -36,6 +36,7 @@ #include <linux/malloc.h> #include <linux/spinlock.h> #include <linux/usb.h> +#include <linux/smp_lock.h> #include "rio500_usb.h" @@ -57,6 +58,7 @@ struct rio_usb_data { char *obuf, *ibuf; /* transfer buffers */ char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ wait_queue_head_t wait_q; /* for timeouts */ + struct semaphore lock; /* general race avoidance */ }; static struct rio_usb_data rio_instance; @@ -65,7 +67,10 @@ static int open_rio(struct inode *inode, struct file *file) { struct rio_usb_data *rio = &rio_instance; + lock_kernel(); + if (rio->isopen || !rio->present) { + unlock_kernel(); return -EBUSY; } rio->isopen = 1; @@ -74,6 +79,8 @@ static int open_rio(struct inode *inode, struct file *file) MOD_INC_USE_COUNT; + unlock_kernel(); + info("Rio opened."); return 0; @@ -101,6 +108,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, unsigned char *buffer; int result, requesttype; int retries; + int retval; /* Sanity check to make sure rio is connected, powered, etc */ if ( rio == NULL || @@ -113,15 +121,22 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, data = (void *) arg; if (data == NULL) break; - if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) - return -EFAULT; - if (rio_cmd.length > PAGE_SIZE) - return -EINVAL; + if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { + retval = -EFAULT; + goto err_out; + } + if (rio_cmd.length > PAGE_SIZE) { + retval = -EINVAL; + goto err_out; + } buffer = (unsigned char *) __get_free_page(GFP_KERNEL); if (buffer == NULL) return -ENOMEM; - if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) - return -EFAULT; + if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { + retval = -EFAULT; + free_page((unsigned long) buffer); + goto err_out; + } requesttype = rio_cmd.requesttype | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE; @@ -131,6 +146,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, rio_cmd.index, rio_cmd.length); /* Send rio control message */ retries = 3; + down(&(rio->lock)); while (retries) { result = usb_control_msg(rio->rio_dev, usb_rcvctrlpipe(rio-> rio_dev, 0), @@ -151,8 +167,12 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, le32_to_cpu(result), le32_to_cpu(*((long *) buffer))); if (copy_to_user(rio_cmd.buffer, buffer, - rio_cmd.length)) - return -EFAULT; + rio_cmd.length)) { + up(&(rio->lock)); + free_page((unsigned long) buffer); + retval = -EFAULT; + goto err_out; + } retries = 0; } @@ -164,6 +184,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, be swapped at the app level */ } + up(&(rio->lock)); free_page((unsigned long) buffer); break; @@ -178,8 +199,10 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, buffer = (unsigned char *) __get_free_page(GFP_KERNEL); if (buffer == NULL) return -ENOMEM; - if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) + if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { + free_page((unsigned long)buffer); return -EFAULT; + } requesttype = rio_cmd.requesttype | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; @@ -188,6 +211,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, rio_cmd.index, rio_cmd.length); /* Send rio control message */ retries = 3; + down(&(rio->lock)); while (retries) { result = usb_control_msg(rio->rio_dev, usb_sndctrlpipe(rio-> rio_dev, 0), @@ -211,6 +235,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, } } + up(&(rio->lock)); free_page((unsigned long) buffer); break; @@ -220,6 +245,9 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, } return 0; + +err_out: + return retval; } static ssize_t @@ -234,6 +262,7 @@ write_rio(struct file *file, const char *buffer, int result = 0; int maxretry; + int errn = 0; /* Sanity check to make sure rio is connected, powered, etc */ if ( rio == NULL || @@ -241,19 +270,26 @@ write_rio(struct file *file, const char *buffer, rio->rio_dev == NULL ) return -1; + down(&(rio->lock)); + do { unsigned long thistime; char *obuf = rio->obuf; thistime = copy_size = (count >= OBUF_SIZE) ? OBUF_SIZE : count; - if (copy_from_user(rio->obuf, buffer, copy_size)) - return -EFAULT; + if (copy_from_user(rio->obuf, buffer, copy_size)) { + errn = -EFAULT; + goto error; + } maxretry = 5; while (thistime) { - if (!rio->rio_dev) - return -ENODEV; + if (!rio->rio_dev) { + errn = -ENODEV; + goto error; + } if (signal_pending(current)) { + up(&(rio->lock)); return bytes_written ? bytes_written : -EINTR; } @@ -266,7 +302,8 @@ write_rio(struct file *file, const char *buffer, if (result == USB_ST_TIMEOUT) { /* NAK - so hold for a while */ if (!maxretry--) { - return -ETIME; + errn = -ETIME; + goto error; } interruptible_sleep_on_timeout(&rio-> wait_q, NAK_TIMEOUT); continue; @@ -278,14 +315,21 @@ write_rio(struct file *file, const char *buffer, }; if (result) { err("Write Whoops - %x", result); - return -EIO; + errn = -EIO; + goto error; } bytes_written += copy_size; count -= copy_size; buffer += copy_size; } while (count > 0); + up(&(rio->lock)); + return bytes_written ? bytes_written : -EIO; + +error: + up(&(rio->lock)); + return errn; } static ssize_t @@ -307,12 +351,17 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos) read_count = 0; + down(&(rio->lock)); + while (count > 0) { if (signal_pending(current)) { + up(&(rio->lock)); return read_count ? read_count : -EINTR; } - if (!rio->rio_dev) + if (!rio->rio_dev) { + up(&(rio->lock)); return -ENODEV; + } this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; result = usb_bulk_msg(rio->rio_dev, @@ -327,6 +376,7 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos) count = this_read = partial; } else if (result == USB_ST_TIMEOUT || result == 15) { /* FIXME: 15 ??? */ if (!maxretry--) { + up(&(rio->lock)); err("read_rio: maxretry timeout"); return -ETIME; } @@ -334,21 +384,26 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos) NAK_TIMEOUT); continue; } else if (result != USB_ST_DATAUNDERRUN) { + up(&(rio->lock)); err("Read Whoops - result:%u partial:%u this_read:%u", result, partial, this_read); return -EIO; } else { + unlock_kernel(); return (0); } if (this_read) { - if (copy_to_user(buffer, ibuf, this_read)) + if (copy_to_user(buffer, ibuf, this_read)) { + up(&(rio->lock)); return -EFAULT; + } count -= this_read; read_count += this_read; buffer += this_read; } } + up(&(rio->lock)); return read_count; } @@ -383,6 +438,8 @@ static void *probe_rio(struct usb_device *dev, unsigned int ifnum) } dbg("probe_rio: ibuf address:%p", rio->ibuf); + init_MUTEX(&(rio->lock)); + return rio; } diff --git a/drivers/usb/scanner.c b/drivers/usb/scanner.c index baa69f4fe..67ea8c8d8 100644 --- a/drivers/usb/scanner.c +++ b/drivers/usb/scanner.c @@ -274,13 +274,18 @@ open_scanner(struct inode * inode, struct file * file) kdev_t scn_minor; + int err=0; + + lock_kernel(); + scn_minor = USB_SCN_MINOR(inode); dbg("open_scanner: scn_minor:%d", scn_minor); if (!p_scn_table[scn_minor]) { err("open_scanner(%d): Unable to access minor data", scn_minor); - return -ENODEV; + err = -ENODEV; + goto out_error; } scn = p_scn_table[scn_minor]; @@ -289,17 +294,20 @@ open_scanner(struct inode * inode, struct file * file) if (!dev) { err("open_scanner(%d): Scanner device not present", scn_minor); - return -ENODEV; + err = -ENODEV; + goto out_error; } if (!scn->present) { err("open_scanner(%d): Scanner is not present", scn_minor); - return -ENODEV; + err = -ENODEV; + goto out_error; } if (scn->isopen) { err("open_scanner(%d): Scanner device is already open", scn_minor); - return -EBUSY; + err = -EBUSY; + goto out_error; } init_waitqueue_head(&scn->rd_wait_q); @@ -310,7 +318,11 @@ open_scanner(struct inode * inode, struct file * file) MOD_INC_USE_COUNT; - return 0; +out_error: + + unlock_kernel(); + + return err; } static int @@ -346,7 +358,7 @@ write_scanner(struct file * file, const char * buffer, { struct scn_usb_data *scn; struct usb_device *dev; - + ssize_t bytes_written = 0; /* Overall count of bytes written */ ssize_t ret = 0; @@ -355,7 +367,7 @@ write_scanner(struct file * file, const char * buffer, int this_write; /* Number of bytes to write */ int partial; /* Number of bytes successfully written */ int result = 0; - + char *obuf; scn = file->private_data; @@ -368,6 +380,8 @@ write_scanner(struct file * file, const char * buffer, file->f_dentry->d_inode->i_atime = CURRENT_TIME; + down(&(scn->gen_lock)); + while (count > 0) { if (signal_pending(current)) { @@ -376,7 +390,7 @@ write_scanner(struct file * file, const char * buffer, } this_write = (count >= OBUF_SIZE) ? OBUF_SIZE : count; - + if (copy_from_user(scn->obuf, buffer, this_write)) { ret = -EFAULT; break; @@ -393,7 +407,7 @@ write_scanner(struct file * file, const char * buffer, warn("write_scanner(%d): funky result: %d. Please notify the maintainer.", scn_minor, result); ret = -EIO; break; - } + } #ifdef WR_DATA_DUMP if (partial) { @@ -420,6 +434,7 @@ write_scanner(struct file * file, const char * buffer, break; } } + up(&(scn->gen_lock)); mdelay(5); /* This seems to help with SANE queries */ return ret ? ret : bytes_written; } @@ -458,6 +473,7 @@ read_scanner(struct file * file, char * buffer, atime of the device node */ + down(&(scn->gen_lock)); while (count > 0) { if (signal_pending(current)) { @@ -466,11 +482,11 @@ read_scanner(struct file * file, char * buffer, } this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; - + result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, scn->bulk_in_ep), ibuf, this_read, &partial, RD_NAK_TIMEOUT); dbg("read stats(%d): result:%d this_read:%d partial:%d count:%d", scn_minor, result, this_read, partial, count); -/* +/* * Scanners are sometimes inheriently slow since they are mechanical * in nature. USB bulk reads tend to timeout while the scanner is * positioning, resetting, warming up the lamp, etc if the timeout is @@ -481,7 +497,7 @@ read_scanner(struct file * file, char * buffer, * that something had hung or crashed when in fact the USB read was * just waiting on data. So, the below code retains the same long * timeout period, but splits it up into smaller parts so that - * Ctrl-C's are acted upon in a reasonable amount of time. + * Ctrl-C's are acted upon in a reasonable amount of time. */ if (result == USB_ST_TIMEOUT && !partial) { /* Timeout @@ -526,7 +542,8 @@ read_scanner(struct file * file, char * buffer, break; } } - + up(&(scn->gen_lock)); + return ret ? ret : bytes_read; } @@ -536,7 +553,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) struct scn_usb_data *scn; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; - + int ep_cnt; int ix; @@ -558,7 +575,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) * 3. Determine/Assign Intr Endpoint */ -/* +/* * There doesn't seem to be an imaging class defined in the USB * Spec. (yet). If there is, HP isn't following it and it doesn't * look like anybody else is either. Therefore, we have to test the @@ -585,7 +602,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) dev->descriptor.idProduct == product) { /* User specified */ valid_device = 1; } - + if (!valid_device) return NULL; /* We didn't find anything pleasing */ @@ -607,7 +624,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) interface = dev->config[0].interface[ifnum].altsetting; endpoint = interface[ifnum].endpoint; -/* +/* * Start checking for two bulk endpoints OR two bulk endpoints *and* one * interrupt endpoint. If we have an interrupt endpoint go ahead and * setup the handler. FIXME: This is a future enhancement... @@ -630,7 +647,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) dbg("probe_scanner: bulk_in_ep:%d", have_bulk_in); continue; } - + if (!have_bulk_out && IS_EP_BULK_OUT(endpoint[ep_cnt])) { ep_cnt++; have_bulk_out = ep_cnt; @@ -673,7 +690,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) } -/* +/* * Determine a minor number and initialize the structure associated * with it. The problem with this is that we are counting on the fact * that the user will sequentially add device nodes for the scanner @@ -703,7 +720,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) /* Ok, if we detected an interrupt EP, setup a handler for it */ if (have_intr) { dbg("probe_scanner(%d): Configuring IRQ handler for intr EP:%d", scn_minor, have_intr); - FILL_INT_URB(&scn->scn_irq, dev, + FILL_INT_URB(&scn->scn_irq, dev, usb_rcvintpipe(dev, have_intr), &scn->button, 1, irq_scanner, scn, // endpoint[(int)have_intr].bInterval); @@ -741,6 +758,8 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) scn->scn_minor = scn_minor; scn->isopen = 0; + init_MUTEX(&(scn->gen_lock)); + return p_scn_table[scn_minor] = scn; } @@ -748,7 +767,7 @@ static void disconnect_scanner(struct usb_device *dev, void *ptr) { struct scn_usb_data *scn = (struct scn_usb_data *) ptr; - + if(scn->intr_ep) { dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor); usb_unlink_urb(&scn->scn_irq); @@ -770,11 +789,11 @@ ioctl_scanner(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct usb_device *dev; - + int result; kdev_t scn_minor; - + scn_minor = USB_SCN_MINOR(inode); if (!p_scn_table[scn_minor]) { @@ -783,7 +802,7 @@ ioctl_scanner(struct inode *inode, struct file *file, } dev = p_scn_table[scn_minor]->scn_dev; - + switch (cmd) { case PV8630_IOCTL_INREQUEST : @@ -794,10 +813,10 @@ ioctl_scanner(struct inode *inode, struct file *file, __u16 value; __u16 index; } args; - + if (copy_from_user(&args, (void *)arg, sizeof(args))) return -EFAULT; - + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), args.request, USB_TYPE_VENDOR| USB_RECIP_DEVICE|USB_DIR_IN, @@ -810,7 +829,7 @@ ioctl_scanner(struct inode *inode, struct file *file, return -EFAULT; dbg("ioctl_scanner(%d): inreq: result:%d\n", scn_minor, result); - + return result; } case PV8630_IOCTL_OUTREQUEST : @@ -820,10 +839,10 @@ ioctl_scanner(struct inode *inode, struct file *file, __u16 value; __u16 index; } args; - + if (copy_from_user(&args, (void *)arg, sizeof(args))) return -EFAULT; - + dbg("ioctl_scanner(%d): outreq: args.value:%x args.index:%x args.request:%x\n", scn_minor, args.value, args.index, args.request); result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -833,7 +852,7 @@ ioctl_scanner(struct inode *inode, struct file *file, 0, HZ*5); dbg("ioctl_scanner(%d): outreq: result:%d\n", scn_minor, result); - + return result; } default: diff --git a/drivers/usb/scanner.h b/drivers/usb/scanner.h index bf01c8082..c1ec964dc 100644 --- a/drivers/usb/scanner.h +++ b/drivers/usb/scanner.h @@ -30,6 +30,7 @@ #include <linux/delay.h> #include <linux/ioctl.h> #include <linux/sched.h> +#include <linux/smp_lock.h> // #define DEBUG @@ -94,6 +95,7 @@ struct scn_usb_data { char *obuf, *ibuf; /* transfer buffers */ char bulk_in_ep, bulk_out_ep, intr_ep; /* Endpoint assignments */ wait_queue_head_t rd_wait_q; /* read timeouts */ + struct semaphore gen_lock; /* lock to prevent concurrent reads or writes */ }; static struct scn_usb_data *p_scn_table[SCN_MAX_MNR] = { NULL, /* ... */}; diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 8fabc8364..f5635bb01 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -14,6 +14,10 @@ * Peter Berger (pberger@brimson.com) * Al Borchers (borchers@steinerpoint.com) * +* (10/05/2000) gkh +* -- Fixed bug with urb->dev not being set properly, now that the usb +* core needs it. +* * (8/8/2000) pberger and borchers * -- Fixed close so that * - it can timeout while waiting for transmit idle, if needed; @@ -642,7 +646,8 @@ dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, co memcpy( oob_port->write_urb->transfer_buffer, buf, len ); oob_port->write_urb->transfer_buffer_length = len; - + oob_port->write_urb->dev = port->serial->dev; + if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) { count -= len; buf += len; @@ -728,6 +733,7 @@ count ); memcpy( data, buf, len ); port->write_urb->transfer_buffer_length = len; } + port->write_urb->dev = port->serial->dev; if( (ret=usb_submit_urb(port->write_urb)) == 0 ) { priv->dp_out_buf_len = 0; @@ -802,6 +808,7 @@ port_priv->dp_port_num, modem_signals ); data[7] = 0; oob_port->write_urb->transfer_buffer_length = 8; + oob_port->write_urb->dev = port->serial->dev; if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) { port_priv->dp_modem_signals = @@ -921,8 +928,10 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); } /* restart read chain */ - if( priv->dp_throttle_restart ) + if( priv->dp_throttle_restart ) { + port->read_urb->dev = port->serial->dev; ret = usb_submit_urb( port->read_urb ); + } /* turn throttle off */ priv->dp_throttled = 0; @@ -1270,6 +1279,7 @@ priv->dp_port_num, count, from_user, in_interrupt() ); } port->write_urb->transfer_buffer_length = data_len+2; + port->write_urb->dev = port->serial->dev; *data++ = DIGI_CMD_SEND_DATA; *data++ = data_len; @@ -1349,6 +1359,7 @@ dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status ); port->write_urb->transfer_buffer_length = priv->dp_out_buf_len+2; + port->write_urb->dev = serial->dev; memcpy( port->write_urb->transfer_buffer+2, priv->dp_out_buf, priv->dp_out_buf_len ); @@ -1631,6 +1642,7 @@ static int digi_startup_device( struct usb_serial *serial ) port = &serial->port[i]; port->write_urb->transfer_flags |= USB_DISABLE_SPD; + port->write_urb->dev = port->serial->dev; if( (ret=usb_submit_urb(port->read_urb)) != 0 ) { err( @@ -1794,6 +1806,7 @@ dbg( "digi_read_bulk_callback: TOP" ); } /* continue read */ + urb->dev = port->serial->dev; if( (ret=usb_submit_urb(urb)) != 0 ) { err( __FUNCTION__ ": failed resubmitting urb, ret=%d, port=%d", ret, priv->dp_port_num ); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 06c4a0506..70f4cd1b0 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -12,6 +12,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (10/05/2000) gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * * (09/11/2000) gkh * Removed DEBUG #ifdefs with call to usb_serial_debug_data * @@ -166,6 +170,7 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp) { /* ftdi_sio_open */ struct termios tmp_termios; struct usb_serial *serial = port->serial; + int result; char buf[1]; /* Needed for the usb_control_msg I think */ dbg("ftdi_sio_open port %d", port->number); @@ -216,9 +221,14 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp) err("Error from RTS HIGH urb"); } - /*Start reading from the device*/ - if (usb_submit_urb(port->read_urb)) - err("usb_submit_urb(read bulk) failed"); + /* Start reading from the device */ + FILL_BULK_URB(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, + ftdi_sio_read_bulk_callback, port); + result = usb_submit_urb(port->read_urb); + if (result) + err(__FUNCTION__ " - failed submitting read urb, error %d", result); return (0); } /* ftdi_sio_open */ @@ -279,6 +289,7 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user, struct usb_serial *serial = port->serial; const int data_offset = 1; int rc; + int result; DECLARE_WAITQUEUE(wait, current); dbg("ftdi_sio_serial_write port %d, %d bytes", port->number, count); @@ -338,10 +349,16 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user, usb_serial_debug_data (__FILE__, __FUNCTION__, count, first_byte); /* send the data out the bulk port */ - port->write_urb->transfer_buffer_length = count; - - if (usb_submit_urb(port->write_urb)) - err("usb_submit_urb(write bulk) failed"); + FILL_BULK_URB(port->write_urb, serial->dev, + usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), + port->write_urb->transfer_buffer, count, + ftdi_sio_write_bulk_callback, port); + + result = usb_submit_urb(port->write_urb); + if (result) { + err(__FUNCTION__ " - failed submitting write urb, error %d", result); + return 0; + } dbg("write returning: %d", count - data_offset); return (count - data_offset); @@ -393,6 +410,7 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb) const int data_offset = 2; int i; + int result; dbg("ftdi_sio read callback"); @@ -429,8 +447,14 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb) } /* Continue trying to always read */ - if (usb_submit_urb(urb)) - err("failed resubmitting read urb"); + FILL_BULK_URB(urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + urb->transfer_buffer, urb->transfer_buffer_length, + ftdi_sio_read_bulk_callback, port); + + result = usb_submit_urb(urb); + if (result) + err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); return; } /* ftdi_sio_serial_read_bulk_callback */ diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7a1d02609..9c509ff15 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -22,6 +22,10 @@ Tip 'o the hat to Linuxcare for supporting staff in their work on open source projects. + (10/05/2000) gkh + Fixed bug with urb->dev not being set properly, now that the usb + core needs it. + Wed Jul 19 14:00:42 EST 2000 gkh Added module_init and module_exit functions to handle the fact that this driver is a loadable module now. @@ -202,6 +206,7 @@ static int keyspan_write(struct usb_serial_port *port, int from_user, /* send the data out the bulk port */ s_priv->out_urbs[current_urb]->transfer_buffer_length = count + 1; + s_priv->out_urbs[current_urb]->dev = serial->dev; if (usb_submit_urb(s_priv->out_urbs[current_urb])) { dbg("usb_submit_urb(write bulk) failed"); @@ -234,13 +239,26 @@ static void keyspan_write_bulk_callback (struct urb *urb) static void keyspan_read_bulk_callback (struct urb *urb) { + struct usb_serial *serial = (struct usb_serial *)urb->context; + struct usb_serial_port *port; int i; int endpoint; - struct usb_serial *serial; - struct usb_serial_port *port; struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; + if (serial_paranoia_check (serial, __FUNCTION__)) + return; + port = &serial->port[0]; + if (port_paranoia_check (port, __FUNCTION__)) + return; + + if (urb->status) { + dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status); + return; + } + + usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data); + endpoint = usb_pipeendpoint(urb->pipe); @@ -255,8 +273,7 @@ static void keyspan_read_bulk_callback (struct urb *urb) /* If this is one of the data endpoints, stuff it's contents into the tty flip_buffer. */ case 1: - case 2: serial = (struct usb_serial *) urb->context; - port = &serial->port[0]; + case 2: tty = port->tty; if (urb->actual_length) { for (i = 0; i < urb->actual_length ; ++i) { @@ -279,7 +296,8 @@ static void keyspan_read_bulk_callback (struct urb *urb) break; } - /* Resubmit urb so we continue receiving */ + /* Resubmit urb so we continue receiving */ + urb->dev = serial->dev; if (usb_submit_urb(urb)) { dbg(__FUNCTION__ "resubmit read urb failed.\n"); } @@ -326,6 +344,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) /* Start reading from port */ for (i = 0; i < 4; i++) { if (s_priv->in_urbs[i]) { + s_priv->in_urbs[i]->dev = serial->dev; if (usb_submit_urb(s_priv->in_urbs[i])) { dbg(__FUNCTION__ " submit in urb %d failed", i); } @@ -578,8 +597,9 @@ static int keyspan_usa19_send_setup(struct usb_serial *serial, struct usb_serial } memcpy (s_priv->out_urbs[2]->transfer_buffer, &msg, sizeof(msg)); - /* send the data out the device on control endpoint */ + /* send the data out the device on control endpoint */ s_priv->out_urbs[2]->transfer_buffer_length = sizeof(msg); + s_priv->out_urbs[2]->dev = serial->dev; if (usb_submit_urb(s_priv->out_urbs[2])) { dbg(__FUNCTION__ " usb_submit_urb(setup) failed\n"); diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 537ad80c9..51a1f10df 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -12,6 +12,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (10/05/2000) gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * * (08/28/2000) gkh * Added locks for SMP safeness. * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more @@ -212,6 +216,7 @@ static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port) { /* just restart the receive interrupt URB */ dbg("keyspan_pda_rx_unthrottle port %d", port->number); + port->interrupt_in_urb->dev = port->serial->dev; if (usb_submit_urb(port->interrupt_in_urb)) dbg(" usb_submit_urb(read urb) failed"); return; @@ -506,6 +511,7 @@ static int keyspan_pda_write(struct usb_serial_port *port, int from_user, priv->tx_room -= count; + port->write_urb->dev = port->serial->dev; if (usb_submit_urb(port->write_urb)) { dbg(" usb_submit_urb(write bulk) failed"); spin_unlock_irqrestore (&port->port_lock, flags); @@ -627,6 +633,7 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp) keyspan_pda_set_modem_info(serial, 0); /*Start reading from the device*/ + port->interrupt_in_urb->dev = serial->dev; if (usb_submit_urb(port->interrupt_in_urb)) dbg(__FUNCTION__" - usb_submit_urb(read int) failed"); } else { diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 1d1bd088c..dc832fa53 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -10,6 +10,10 @@ * * Please report both successes and troubles to the author at omninet@kroah.com * + * (10/05/2000) gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * * (08/28/2000) gkh * Added locks for SMP safeness. * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more @@ -129,6 +133,7 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) struct usb_serial_port *wport; struct omninet_data *od; unsigned long flags; + int result; if (port_paranoia_check (port, __FUNCTION__)) return -ENODEV; @@ -162,8 +167,13 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) wport->tty = port->tty; /* Start reading from the device */ - if (usb_submit_urb(port->read_urb)) - dbg(__FUNCTION__" - read bulk (%p) failed", port->read_urb); + FILL_BULK_URB(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, + omninet_read_bulk_callback, port); + result = usb_submit_urb(port->read_urb); + if (result) + err(__FUNCTION__ " - failed submitting read urb, error %d", result); } spin_unlock_irqrestore (&port->port_lock, flags); @@ -222,6 +232,7 @@ static void omninet_read_bulk_callback (struct urb *urb) struct omninet_header *header = (struct omninet_header *) &data[0]; int i; + int result; // dbg("omninet_read_bulk_callback"); @@ -255,8 +266,13 @@ static void omninet_read_bulk_callback (struct urb *urb) } /* Continue trying to always read */ - if (usb_submit_urb(urb)) - dbg(__FUNCTION__" - failed resubmitting read urb"); + FILL_BULK_URB(urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + urb->transfer_buffer, urb->transfer_buffer_length, + omninet_read_bulk_callback, port); + result = usb_submit_urb(urb); + if (result) + err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); return; } @@ -270,11 +286,7 @@ static int omninet_write (struct usb_serial_port *port, int from_user, const uns struct omninet_header *header = (struct omninet_header *) wport->write_urb->transfer_buffer; unsigned long flags; -/* -#ifdef DEBUG - int i; -#endif -*/ + int result; // dbg("omninet_write port %d", port->number); @@ -282,23 +294,13 @@ static int omninet_write (struct usb_serial_port *port, int from_user, const uns dbg(__FUNCTION__" - write request of 0 bytes"); return (0); } -/* -#ifdef DEBUG - printk (KERN_DEBUG __FILE__ ": omninet_write %d: ", count); - for (i = 0; i < count; i++) { - if( isalpha(buf[i]) ) - printk ("%c ", buf[i]); - else - printk ("%.2x ", buf[i]); - } - printk ("\n"); -#endif -*/ if (wport->write_urb->status == -EINPROGRESS) { dbg (__FUNCTION__" - already writing"); return (0); } + usb_serial_debug_data (__FILE__, __FUNCTION__, count, buf); + spin_lock_irqsave (&port->port_lock, flags); count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; @@ -319,8 +321,10 @@ static int omninet_write (struct usb_serial_port *port, int from_user, const uns /* send the data out the bulk port, always 64 bytes */ wport->write_urb->transfer_buffer_length = 64; - if (usb_submit_urb(wport->write_urb)) { - dbg(__FUNCTION__" - usb_submit_urb(write bulk) failed"); + wport->write_urb->dev = serial->dev; + result = usb_submit_urb(wport->write_urb); + if (result) { + err(__FUNCTION__ " - failed submitting write urb, error %d", result); spin_unlock_irqrestore (&port->port_lock, flags); return 0; } diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index b589decff..5dde77426 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -11,6 +11,11 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (10/05/2000) gkh + * Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help + * fix bug with urb->dev not being set properly, now that the usb core + * needs it. + * * (09/11/2000) gkh * Added usb_serial_debug_data function to help get rid of #DEBUG in the * drivers. @@ -57,9 +62,11 @@ struct usb_serial_port { unsigned char * interrupt_in_buffer; struct urb * interrupt_in_urb; + __u8 interrupt_in_endpointAddress; unsigned char * bulk_in_buffer; struct urb * read_urb; + __u8 bulk_in_endpointAddress; unsigned char * bulk_out_buffer; int bulk_out_size; diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c index 86c8755b8..902a4e1d0 100644 --- a/drivers/usb/serial/usbserial.c +++ b/drivers/usb/serial/usbserial.c @@ -15,6 +15,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (10/05/2000) gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * * (09/11/2000) gkh * Removed DEBUG #ifdefs with call to usb_serial_debug_data * @@ -693,6 +697,7 @@ static int generic_open (struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; unsigned long flags; + int result; if (port_paranoia_check (port, __FUNCTION__)) return -ENODEV; @@ -709,9 +714,17 @@ static int generic_open (struct usb_serial_port *port, struct file *filp) /* if we have a bulk interrupt, start reading from it */ if (serial->num_bulk_in) { - /*Start reading from the device*/ - if (usb_submit_urb(port->read_urb)) - dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed"); + /* Start reading from the device */ + FILL_BULK_URB(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, + ((serial->type->read_bulk_callback) ? + serial->type->read_bulk_callback : + generic_read_bulk_callback), + port); + result = usb_submit_urb(port->read_urb); + if (result) + err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); } } @@ -751,6 +764,7 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns { struct usb_serial *serial = port->serial; unsigned long flags; + int result; dbg(__FUNCTION__ " - port %d", port->number); @@ -778,11 +792,19 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns memcpy (port->write_urb->transfer_buffer, buf, count); } - /* send the data out the bulk port */ - port->write_urb->transfer_buffer_length = count; + /* set up our urb */ + FILL_BULK_URB(port->write_urb, serial->dev, + usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), + port->write_urb->transfer_buffer, count, + ((serial->type->write_bulk_callback) ? + serial->type->write_bulk_callback : + generic_write_bulk_callback), + port); - if (usb_submit_urb(port->write_urb)) { - dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed"); + /* send the data out the bulk port */ + result = usb_submit_urb(port->write_urb); + if (result) { + err(__FUNCTION__ " - failed submitting write urb, error %d", result); spin_unlock_irqrestore (&port->port_lock, flags); return 0; } @@ -835,6 +857,7 @@ static void generic_read_bulk_callback (struct urb *urb) struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int i; + int result; dbg(__FUNCTION__ " - port %d", port->number); @@ -859,10 +882,16 @@ static void generic_read_bulk_callback (struct urb *urb) } /* Continue trying to always read */ - if (usb_submit_urb(urb)) - dbg(__FUNCTION__ " - failed resubmitting read urb"); - - return; + FILL_BULK_URB(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, + ((serial->type->read_bulk_callback) ? + serial->type->read_bulk_callback : + generic_read_bulk_callback), + port); + result = usb_submit_urb(port->read_urb); + if (result) + err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); } @@ -1071,6 +1100,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) goto probe_error; } buffer_size = endpoint->wMaxPacketSize; + port->bulk_in_endpointAddress = endpoint->bEndpointAddress; port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); if (!port->bulk_in_buffer) { err("Couldn't allocate bulk_in_buffer"); @@ -1119,6 +1149,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) goto probe_error; } buffer_size = endpoint->wMaxPacketSize; + port->interrupt_in_endpointAddress = endpoint->bEndpointAddress; port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); if (!port->interrupt_in_buffer) { err("Couldn't allocate interrupt_in_buffer"); @@ -1136,6 +1167,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ max_endpoints = MAX(num_bulk_in, num_bulk_out); max_endpoints = MAX(max_endpoints, num_interrupt_in); + dbg (__FUNCTION__ " - setting up %d port structures for this device", max_endpoints); for (i = 0; i < max_endpoints; ++i) { port = &serial->port[i]; port->number = i + serial->minor; diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 4245c1386..868333c87 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -11,6 +11,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (10/05/2000) gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * * (09/11/2000) gkh * Got rid of always calling kmalloc for every urb we wrote out to the * device. @@ -138,7 +142,9 @@ static int bytes_out; ******************************************************************************/ static int visor_open (struct usb_serial_port *port, struct file *filp) { + struct usb_serial *serial = port->serial; unsigned long flags; + int result; if (port_paranoia_check (port, __FUNCTION__)) return -ENODEV; @@ -155,9 +161,14 @@ static int visor_open (struct usb_serial_port *port, struct file *filp) bytes_in = 0; bytes_out = 0; - /*Start reading from the device*/ - if (usb_submit_urb(port->read_urb)) - dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed"); + /* Start reading from the device */ + FILL_BULK_URB(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, + visor_read_bulk_callback, port); + result = usb_submit_urb(port->read_urb); + if (result) + err(__FUNCTION__ " - failed submitting read urb, error %d", result); } spin_unlock_irqrestore (&port->port_lock, flags); @@ -301,15 +312,22 @@ static void visor_write_bulk_callback (struct urb *urb) static void visor_read_bulk_callback (struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int i; + int result; if (port_paranoia_check (port, __FUNCTION__)) return; dbg(__FUNCTION__ " - port %d", port->number); + if (!serial) { + dbg(__FUNCTION__ " - bad serial pointer, exiting"); + return; + } + if (urb->status) { dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status); return; @@ -327,8 +345,13 @@ static void visor_read_bulk_callback (struct urb *urb) } /* Continue trying to always read */ - if (usb_submit_urb(urb)) - dbg(__FUNCTION__ " - failed resubmitting read urb"); + FILL_BULK_URB(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, + visor_read_bulk_callback, port); + result = usb_submit_urb(port->read_urb); + if (result) + err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); return; } @@ -352,13 +375,16 @@ static void visor_throttle (struct usb_serial_port *port) static void visor_unthrottle (struct usb_serial_port *port) { unsigned long flags; + int result; dbg(__FUNCTION__ " - port %d", port->number); spin_lock_irqsave (&port->port_lock, flags); - if (usb_submit_urb (port->read_urb)) - dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed"); + port->read_urb->dev = port->serial->dev; + result = usb_submit_urb(port->read_urb); + if (result) + err(__FUNCTION__ " - failed submitting read urb, error %d", result); spin_unlock_irqrestore (&port->port_lock, flags); diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 7302b729a..55abab383 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -11,6 +11,18 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (10/05/2000) gkh + * Fixed bug with urb->dev not being set properly, now that the usb + * core needs it. + * + * (10/03/2000) smd + * firmware is improved to guard against crap sent to device + * firmware now replies CMD_FAILURE on bad things + * read_callback fix you provided for private info struct + * command_finished now indicates success or fail + * setup_port struct now packed to avoid gcc padding + * firmware uses 1 based port numbering, driver now handles that + * * (09/11/2000) gkh * Removed DEBUG #ifdefs with call to usb_serial_debug_data * @@ -148,8 +160,11 @@ static void command_port_write_callback (struct urb *urb) static void command_port_read_callback (struct urb *urb) { - struct whiteheat_private *info = (struct whiteheat_private *)urb->context; + struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); + struct whiteheat_private *info; unsigned char *data = urb->transfer_buffer; + int result; dbg (__FUNCTION__); @@ -158,15 +173,39 @@ static void command_port_read_callback (struct urb *urb) return; } + if (!serial) { + dbg(__FUNCTION__ " - bad serial pointer, exiting"); + return; + } + usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data); + info = (struct whiteheat_private *)port->private; + if (!info) { + dbg (__FUNCTION__ " - info is NULL, exiting."); + return; + } + /* right now, if the command is COMMAND_COMPLETE, just flip the bit saying the command finished */ /* in the future we're going to have to pay attention to the actual command that completed */ if (data[0] == WHITEHEAT_CMD_COMPLETE) { - info->command_finished = TRUE; + info->command_finished = WHITEHEAT_CMD_COMPLETE; + wake_up_interruptible(&info->wait_command); } - return; + if (data[0] == WHITEHEAT_CMD_FAILURE) { + info->command_finished = WHITEHEAT_CMD_FAILURE; + wake_up_interruptible(&info->wait_command); + } + + /* Continue trying to always read */ + FILL_BULK_URB(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, + command_port_read_callback, port); + result = usb_submit_urb(port->read_urb); + if (result) + dbg(__FUNCTION__ " - failed resubmitting read urb, error %d", result); } @@ -187,6 +226,7 @@ static int whiteheat_send_cmd (struct usb_serial *serial, __u8 command, __u8 *da transfer_buffer[0] = command; memcpy (&transfer_buffer[1], data, datasize); port->write_urb->transfer_buffer_length = datasize + 1; + port->write_urb->dev = serial->dev; if (usb_submit_urb (port->write_urb)) { dbg (__FUNCTION__" - submit urb failed"); return -1; @@ -203,6 +243,16 @@ static int whiteheat_send_cmd (struct usb_serial *serial, __u8 command, __u8 *da return -1; } + if (info->command_finished == WHITEHEAT_CMD_FAILURE) { + dbg (__FUNCTION__ " - command failed."); + return -1; + } + + if (info->command_finished == WHITEHEAT_CMD_COMPLETE) { + dbg (__FUNCTION__ " - command completed."); + return 0; + } + return 0; } @@ -212,6 +262,7 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) struct whiteheat_min_set open_command; struct usb_serial_port *command_port; struct whiteheat_private *info; + int result; dbg(__FUNCTION__" - port %d", port->number); @@ -234,15 +285,20 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) command_port->private = info; command_port->write_urb->complete = command_port_write_callback; command_port->read_urb->complete = command_port_read_callback; - usb_submit_urb (command_port->read_urb); + command_port->read_urb->dev = port->serial->dev; + command_port->tty = port->tty; /* need this to "fake" our our sanity check macros */ + usb_submit_urb (command_port->read_urb); } /* Start reading from the device */ - if (usb_submit_urb(port->read_urb)) - dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed"); + port->read_urb->dev = port->serial->dev; + result = usb_submit_urb(port->read_urb); + if (result) + err(__FUNCTION__ " - failed submitting read urb, error %d", result); /* send an open port command */ - open_command.port = port->number - port->serial->minor; + /* firmware uses 1 based port numbering */ + open_command.port = port->number - port->serial->minor + 1; whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command)); /* Need to do device specific setup here (control lines, baud rate, etc.) */ @@ -261,7 +317,8 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp) dbg(__FUNCTION__ " - port %d", port->number); /* send a close command to the port */ - close_command.port = port->number - port->serial->minor; + /* firmware uses 1 based port numbering */ + close_command.port = port->number - port->serial->minor + 1; whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command)); /* Need to change the control lines here */ @@ -303,6 +360,10 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct termios return; } + /* set the port number */ + /* firmware uses 1 based port numbering */ + port_settings.port = port->number + 1; + /* get the byte size */ switch (cflag & CSIZE) { case CS5: port_settings.bits = 5; break; @@ -337,10 +398,10 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct termios else port_settings.hflow = 0; dbg(__FUNCTION__ " - hardware flow control = %s %s %s %s", - (port_settings.hflow | WHITEHEAT_CTS_FLOW) ? "CTS" : "", - (port_settings.hflow | WHITEHEAT_RTS_FLOW) ? "RTS" : "", - (port_settings.hflow | WHITEHEAT_DSR_FLOW) ? "DSR" : "", - (port_settings.hflow | WHITEHEAT_DTR_FLOW) ? "DTR" : ""); + (port_settings.hflow & WHITEHEAT_CTS_FLOW) ? "CTS" : "", + (port_settings.hflow & WHITEHEAT_RTS_FLOW) ? "RTS" : "", + (port_settings.hflow & WHITEHEAT_DSR_FLOW) ? "DSR" : "", + (port_settings.hflow & WHITEHEAT_DTR_FLOW) ? "DTR" : ""); /* determine software flow control */ if (I_IXOFF(port->tty)) @@ -485,7 +546,8 @@ static void set_command (struct usb_serial_port *port, unsigned char state, unsi struct whiteheat_rdb_set rdb_command; /* send a set rts command to the port */ - rdb_command.port = port->number - port->serial->minor; + /* firmware uses 1 based port numbering */ + rdb_command.port = port->number - port->serial->minor + 1; rdb_command.state = state; whiteheat_send_cmd (port->serial, command, (__u8 *)&rdb_command, sizeof(rdb_command)); diff --git a/drivers/usb/serial/whiteheat.h b/drivers/usb/serial/whiteheat.h index 970a555c0..99cdbb6cb 100644 --- a/drivers/usb/serial/whiteheat.h +++ b/drivers/usb/serial/whiteheat.h @@ -37,6 +37,7 @@ #define WHITEHEAT_ECHO 14 /* send data to the indicated IN endpoint */ #define WHITEHEAT_DO_TEST 15 /* perform the specified test */ #define WHITEHEAT_CMD_COMPLETE 16 /* reply for certain commands */ +#define WHITEHEAT_CMD_FAILURE 17 /* reply for failed commands */ /* Data for the WHITEHEAT_SETUP_PORT command */ #define WHITEHEAT_CTS_FLOW 0x08 @@ -64,7 +65,7 @@ struct whiteheat_port_settings { * RTS (0x80) (RTS off/on when receiver fills/empties) * DTR (0x02) (DTR off/on when receiver fills/empties) */ __u8 lloop; /* local loopback 0 or 1, default 0 */ -}; +} __attribute__ ((packed)); /* data for WHITEHEAT_SET_RTS, WHITEHEAT_SET_DTR, and WHITEHEAT_SET_BREAK commands */ struct whiteheat_rdb_set { diff --git a/drivers/usb/serial/whiteheat_fw.h b/drivers/usb/serial/whiteheat_fw.h index 7d942ba00..e50a9e82f 100644 --- a/drivers/usb/serial/whiteheat_fw.h +++ b/drivers/usb/serial/whiteheat_fw.h @@ -47,159 +47,154 @@ struct whiteheat_hex_record { }; static const struct whiteheat_hex_record whiteheat_firmware[] = { -{ 0x0000, 3, {0x02, 0x93, 0xa9} }, +{ 0x0000, 3, {0x02, 0x95, 0x09} }, { 0x0003, 3, {0x02, 0x13, 0x12} }, -{ 0x000b, 3, {0x02, 0x0a, 0x80} }, -{ 0x0033, 3, {0x02, 0x08, 0x15} }, +{ 0x000b, 3, {0x02, 0x0a, 0x91} }, +{ 0x0033, 3, {0x02, 0x08, 0x1b} }, { 0x0043, 3, {0x02, 0x0a, 0x00} }, -{ 0x005b, 3, {0x02, 0x82, 0x31} }, +{ 0x005b, 3, {0x02, 0x1a, 0xd2} }, { 0x0370, 16, {0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x73, 0x14, 0x70, 0x03, 0x02, 0x04, 0xe7, 0x24} }, -{ 0x0380, 16, {0xfe, 0x70, 0x03, 0x02, 0x05, 0x45, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x64, 0x14, 0x70, 0x03} }, +{ 0x0380, 16, {0xfe, 0x70, 0x03, 0x02, 0x05, 0x4f, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x64, 0x14, 0x70, 0x03} }, { 0x0390, 16, {0x02, 0x04, 0x52, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x49, 0x24} }, -{ 0x03a0, 16, {0x05, 0x60, 0x03, 0x02, 0x05, 0x94, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60} }, +{ 0x03a0, 16, {0x05, 0x60, 0x03, 0x02, 0x05, 0x9e, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60} }, { 0x03b0, 16, {0x36, 0x24, 0x02, 0x70, 0x7b, 0x74, 0x12, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} }, -{ 0x03c0, 16, {0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x7b, 0xea, 0x49, 0x60, 0x0d} }, -{ 0x03d0, 16, {0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xb4} }, -{ 0x03e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x3a, 0xea} }, -{ 0x03f0, 16, {0x49, 0x60, 0x33, 0x12, 0x9b, 0x72, 0xf5, 0x4b, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4b, 0xd3} }, +{ 0x03c0, 16, {0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x81, 0xea, 0x49, 0x60, 0x0d} }, +{ 0x03d0, 16, {0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} }, +{ 0x03e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x40, 0xea} }, +{ 0x03f0, 16, {0x49, 0x60, 0x33, 0x12, 0x9f, 0x48, 0xf5, 0x4b, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4b, 0xd3} }, { 0x0400, 16, {0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4b, 0x40} }, -{ 0x0410, 16, {0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4b, 0x12, 0x8d, 0xd9, 0x90, 0x7f, 0xb5} }, -{ 0x0420, 16, {0xe5, 0x4b, 0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0x9b} }, -{ 0x0430, 16, {0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0x00, 0xe5, 0x21, 0xf0} }, -{ 0x0440, 16, {0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x21, 0x02} }, -{ 0x0450, 16, {0x05, 0x9b, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x31, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} }, -{ 0x0460, 16, {0xa8, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0x00, 0xe5, 0x31, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} }, -{ 0x0470, 16, {0x02, 0x05, 0x9b, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02} }, +{ 0x0410, 16, {0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4b, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xb5} }, +{ 0x0420, 16, {0xe5, 0x4b, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} }, +{ 0x0430, 16, {0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x21, 0xf0} }, +{ 0x0440, 16, {0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x21, 0x02} }, +{ 0x0450, 16, {0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x31, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} }, +{ 0x0460, 16, {0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x31, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} }, +{ 0x0470, 16, {0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02} }, { 0x0480, 16, {0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x05, 0xe4, 0x33, 0x4f, 0x90} }, -{ 0x0490, 16, {0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0x9b, 0xe4} }, -{ 0x04a0, 16, {0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0x9b, 0x90} }, +{ 0x0490, 16, {0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0xe4} }, +{ 0x04a0, 16, {0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0x90} }, { 0x04b0, 16, {0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25} }, { 0x04c0, 16, {0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0x01, 0x90, 0x7f, 0x00} }, -{ 0x04d0, 16, {0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xb4} }, -{ 0x04e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24} }, -{ 0x04f0, 16, {0x02, 0x60, 0x03, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02} }, -{ 0x0500, 16, {0x05, 0x9b, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0x9b, 0x90, 0x7f, 0xea, 0xe0} }, -{ 0x0510, 16, {0x70, 0x2a, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0xf4, 0x54, 0x80, 0xfe, 0xc4, 0x54, 0x0f, 0xfe, 0xef} }, -{ 0x0520, 16, {0x54, 0x07, 0xfd, 0x2e, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4} }, -{ 0x0530, 16, {0xf0, 0x90, 0x7f, 0xd7, 0xed, 0xf0, 0xef, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0} }, -{ 0x0540, 16, {0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70} }, -{ 0x0550, 16, {0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0} }, -{ 0x0560, 16, {0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4} }, -{ 0x0570, 16, {0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5} }, -{ 0x0580, 16, {0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44} }, -{ 0x0590, 16, {0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44} }, -{ 0x05a0, 2, {0x02, 0xf0} }, -{ 0x05a2, 1, {0x22} }, -{ 0x05a3, 16, {0x75, 0x47, 0xff, 0x75, 0x46, 0xff, 0x75, 0x45, 0x0f, 0x75, 0x44, 0x00, 0xd2, 0x03, 0xc2, 0x06} }, -{ 0x05b3, 16, {0xc2, 0x02, 0xc2, 0x00, 0xc2, 0x05, 0xc2, 0x01, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xe4, 0x90} }, -{ 0x05c3, 16, {0x01, 0xbc, 0xf0, 0xc2, 0x04, 0x90, 0x01, 0xc0, 0xf0, 0xa3, 0xf0, 0xc2, 0xaf, 0xc2, 0xa8, 0x12} }, -{ 0x05d3, 16, {0x0b, 0x8d, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} }, -{ 0x05e3, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0x7e} }, -{ 0x05f3, 16, {0x01, 0x7f, 0x00, 0x12, 0x19, 0xc1, 0x75, 0x49, 0x12, 0x75, 0x4a, 0x0a, 0x90, 0x01, 0x0b, 0xe0} }, -{ 0x0603, 16, {0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83} }, -{ 0x0613, 16, {0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} }, -{ 0x0623, 16, {0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} }, -{ 0x0633, 16, {0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, -{ 0x0643, 16, {0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} }, -{ 0x0653, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff, 0x74, 0x01, 0x93, 0x90} }, -{ 0x0663, 16, {0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff, 0xa3, 0xe0, 0xfe, 0xef} }, -{ 0x0673, 16, {0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0x6f} }, -{ 0x0683, 16, {0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x4f, 0x10, 0x75, 0x50, 0x02, 0x75} }, -{ 0x0693, 16, {0x51, 0x12, 0x75, 0x52, 0xac, 0x12, 0x90, 0x15, 0x75, 0x49, 0x12, 0x75, 0x4a, 0xb2, 0x90, 0x01} }, -{ 0x06a3, 16, {0x0d, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82} }, -{ 0x06b3, 16, {0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} }, -{ 0x06c3, 16, {0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} }, -{ 0x06d3, 16, {0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} }, -{ 0x06e3, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4a, 0xe5, 0x4a, 0xae, 0x49, 0x70, 0x02, 0x05, 0x49} }, -{ 0x06f3, 16, {0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83, 0x01, 0xe0, 0xfc, 0xa3} }, -{ 0x0703, 16, {0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0x9d, 0x25, 0x7e, 0x01} }, -{ 0x0713, 16, {0x7f, 0x18, 0x12, 0x85, 0x08, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, -{ 0x0723, 16, {0xa3, 0xe0, 0xff, 0x75, 0x4f, 0x0a, 0x75, 0x50, 0x06, 0x75, 0x51, 0x12, 0x75, 0x52, 0xb8, 0x12} }, -{ 0x0733, 16, {0x90, 0x15, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} }, -{ 0x0743, 16, {0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x1f, 0xf0, 0xd2, 0xaf} }, -{ 0x0753, 16, {0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xca, 0x75, 0x43, 0x50} }, -{ 0x0763, 16, {0x75, 0x42, 0x6d, 0x75, 0x41, 0x33, 0x75, 0x40, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} }, -{ 0x0773, 16, {0x7d, 0xff, 0x7c, 0xff, 0x78, 0x40, 0x12, 0x9d, 0x0e, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} }, -{ 0x0783, 16, {0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0d, 0x12, 0x0a, 0xed, 0x50} }, -{ 0x0793, 16, {0x06, 0x12, 0x0b, 0x00, 0x12, 0x0a, 0xf2, 0xc2, 0x06, 0x12, 0x92, 0x38, 0x90, 0x01, 0xbd, 0xe0} }, -{ 0x07a3, 16, {0x60, 0x10, 0x7e, 0x7b, 0x7f, 0x40, 0x12, 0x8e, 0xc1, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f} }, -{ 0x07b3, 16, {0xd3, 0xf0, 0x90, 0x02, 0xaf, 0xe0, 0xb4, 0x0f, 0x03, 0x12, 0x95, 0x30, 0x12, 0x99, 0xcc, 0xe4} }, -{ 0x07c3, 16, {0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc} }, -{ 0x07d3, 16, {0xe0, 0x5e, 0x60, 0x14, 0x74, 0x27, 0x2f, 0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01} }, -{ 0x07e3, 16, {0x80, 0x02, 0x7e, 0x00, 0x8e, 0x48, 0x80, 0x03, 0x75, 0x48, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82} }, -{ 0x07f3, 16, {0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe5, 0x48, 0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94} }, -{ 0x0803, 16, {0x0a, 0x40, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07} }, -{ 0x0813, 1, {0x84} }, -{ 0x0814, 1, {0x22} }, -{ 0x0815, 4, {0x53, 0xd8, 0xef, 0x32} }, -{ 0x0819, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x7f, 0x0a, 0xfe, 0x12, 0x09, 0x23, 0x90, 0x7f, 0x96, 0x74, 0x89} }, -{ 0x0829, 16, {0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0x23, 0x90, 0x7f} }, -{ 0x0839, 16, {0x96, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x7f, 0x02, 0x7d, 0xff} }, -{ 0x0849, 16, {0x12, 0x81, 0xe0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x02} }, -{ 0x0859, 16, {0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x90, 0x7f, 0x96, 0xe0} }, -{ 0x0869, 16, {0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf} }, -{ 0x0879, 16, {0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f} }, -{ 0x0889, 7, {0x32, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x22} }, -{ 0x0890, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} }, -{ 0x08a0, 16, {0x09, 0x23, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x81, 0xe0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23} }, -{ 0x08b0, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x90, 0x7f} }, -{ 0x08c0, 16, {0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x90, 0x7f, 0x96, 0xe0} }, -{ 0x08d0, 16, {0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01} }, -{ 0x08e0, 12, {0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x12, 0x0b, 0x00, 0x22} }, -{ 0x08ec, 16, {0x90, 0x11, 0xfc, 0xe4, 0x93, 0x70, 0x2f, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} }, -{ 0x08fc, 16, {0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x7f} }, -{ 0x090c, 16, {0x9d, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12, 0xf0, 0x12, 0x08, 0x19, 0x75, 0x82, 0xfc} }, -{ 0x091c, 7, {0x75, 0x83, 0x11, 0x74, 0xff, 0xf0, 0x22} }, -{ 0x0923, 16, {0x8e, 0x58, 0x8f, 0x59, 0xe5, 0x59, 0x15, 0x59, 0xae, 0x58, 0x70, 0x02, 0x15, 0x58, 0x4e, 0x60} }, -{ 0x0933, 7, {0x05, 0x12, 0x09, 0xef, 0x80, 0xee, 0x22} }, -{ 0x093a, 2, {0x8f, 0x4c} }, -{ 0x093c, 16, {0xe4, 0xf5, 0x4d, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x6a, 0xab, 0x4e, 0xaa, 0x4f} }, -{ 0x094c, 16, {0xa9, 0x50, 0x90, 0x00, 0x01, 0x12, 0x9b, 0x8b, 0xb4, 0x03, 0x1d, 0xaf, 0x4d, 0x05, 0x4d, 0xef} }, -{ 0x095c, 16, {0xb5, 0x4c, 0x01, 0x22, 0x12, 0x9b, 0x72, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} }, -{ 0x096c, 14, {0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x097a, 1, {0x22} }, -{ 0x097b, 16, {0xe4, 0xfe, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x12, 0xab, 0x4e, 0xaa, 0x4f, 0xa9} }, -{ 0x098b, 16, {0x50, 0x90, 0x00, 0x01, 0x12, 0x9b, 0x8b, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} }, -{ 0x099b, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x9b, 0xe4, 0x85, 0xf0, 0x4c, 0xf5, 0x4d, 0x62, 0x4c} }, -{ 0x09ab, 16, {0xe5, 0x4c, 0x62, 0x4d, 0xe5, 0x4d, 0x62, 0x4c, 0x29, 0xfd, 0xe5, 0x4c, 0x3a, 0xa9, 0x05, 0x75} }, -{ 0x09bb, 14, {0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x09c9, 1, {0x22} }, -{ 0x09ca, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} }, -{ 0x09da, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0x23, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} }, -{ 0x09ea, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} }, -{ 0x09ef, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} }, -{ 0x09ff, 1, {0x22} }, +{ 0x04d0, 16, {0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} }, +{ 0x04e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24} }, +{ 0x04f0, 16, {0x02, 0x60, 0x03, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02} }, +{ 0x0500, 16, {0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0} }, +{ 0x0510, 16, {0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4b, 0xef, 0x30, 0xe7, 0x03} }, +{ 0x0520, 16, {0x43, 0x4b, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4b, 0xf0, 0xe5, 0x4b, 0x44, 0x20, 0xf0, 0xef, 0xf4} }, +{ 0x0530, 16, {0x54, 0x80, 0xfd, 0xc4, 0x54, 0x0f, 0x2e, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} }, +{ 0x0540, 16, {0xf5, 0x83, 0xe4, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90} }, +{ 0x0550, 16, {0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4} }, +{ 0x0560, 16, {0x01, 0x04, 0xd2, 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90} }, +{ 0x0570, 16, {0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f} }, +{ 0x0580, 16, {0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} }, +{ 0x0590, 16, {0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f} }, +{ 0x05a0, 12, {0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} }, +{ 0x05ac, 1, {0x22} }, +{ 0x05ad, 16, {0x75, 0x47, 0xff, 0x75, 0x46, 0xff, 0x75, 0x45, 0x0f, 0x75, 0x44, 0x00, 0xd2, 0x03, 0xc2, 0x06} }, +{ 0x05bd, 16, {0xc2, 0x02, 0xc2, 0x00, 0xc2, 0x05, 0xc2, 0x01, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xe4, 0x90} }, +{ 0x05cd, 16, {0x01, 0xbc, 0xf0, 0xc2, 0x04, 0x90, 0x01, 0xc0, 0xf0, 0xa3, 0xf0, 0xc2, 0xaf, 0xc2, 0xa8, 0x12} }, +{ 0x05dd, 16, {0x0b, 0x8d, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} }, +{ 0x05ed, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0x7e} }, +{ 0x05fd, 16, {0x01, 0x7f, 0x00, 0x12, 0x10, 0x2c, 0x75, 0x49, 0x12, 0x75, 0x4a, 0x0a, 0x90, 0x01, 0x0b, 0xe0} }, +{ 0x060d, 16, {0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83} }, +{ 0x061d, 16, {0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} }, +{ 0x062d, 16, {0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} }, +{ 0x063d, 16, {0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, +{ 0x064d, 16, {0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} }, +{ 0x065d, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff, 0x74, 0x01, 0x93, 0x90} }, +{ 0x066d, 16, {0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff, 0xa3, 0xe0, 0xfe, 0xef} }, +{ 0x067d, 16, {0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0x6f} }, +{ 0x068d, 16, {0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x4f, 0x10, 0x75, 0x50, 0x02, 0x75} }, +{ 0x069d, 16, {0x51, 0x12, 0x75, 0x52, 0xac, 0x12, 0x91, 0x7a, 0x75, 0x49, 0x12, 0x75, 0x4a, 0xb2, 0x90, 0x01} }, +{ 0x06ad, 16, {0x0d, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82} }, +{ 0x06bd, 16, {0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} }, +{ 0x06cd, 16, {0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} }, +{ 0x06dd, 16, {0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} }, +{ 0x06ed, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4a, 0xe5, 0x4a, 0xae, 0x49, 0x70, 0x02, 0x05, 0x49} }, +{ 0x06fd, 16, {0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83, 0x01, 0xe0, 0xfc, 0xa3} }, +{ 0x070d, 16, {0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa0, 0xfb, 0x7e, 0x01} }, +{ 0x071d, 16, {0x7f, 0x18, 0x12, 0x85, 0x2f, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, +{ 0x072d, 16, {0xa3, 0xe0, 0xff, 0x75, 0x4f, 0x0a, 0x75, 0x50, 0x06, 0x75, 0x51, 0x12, 0x75, 0x52, 0xb8, 0x12} }, +{ 0x073d, 16, {0x91, 0x7a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} }, +{ 0x074d, 16, {0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x1f, 0xf0, 0xd2, 0xaf} }, +{ 0x075d, 16, {0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xd0, 0x75, 0x43, 0x50} }, +{ 0x076d, 16, {0x75, 0x42, 0x6d, 0x75, 0x41, 0x33, 0x75, 0x40, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} }, +{ 0x077d, 16, {0x7d, 0xff, 0x7c, 0xff, 0x78, 0x40, 0x12, 0xa0, 0xe4, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} }, +{ 0x078d, 16, {0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0d, 0x12, 0x09, 0xf5, 0x50} }, +{ 0x079d, 16, {0x06, 0x12, 0x0b, 0x00, 0x12, 0x09, 0xfa, 0xc2, 0x06, 0x12, 0x93, 0x98, 0x90, 0x01, 0xbd, 0xe0} }, +{ 0x07ad, 16, {0x60, 0x0c, 0x12, 0x8f, 0x55, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02} }, +{ 0x07bd, 16, {0xaf, 0xe0, 0xb4, 0x0f, 0x03, 0x12, 0x96, 0xe2, 0x12, 0x9d, 0xa2, 0xe4, 0xff, 0x74, 0x01, 0xa8} }, +{ 0x07cd, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14} }, +{ 0x07dd, 16, {0x74, 0x27, 0x2f, 0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00} }, +{ 0x07ed, 16, {0x8e, 0x48, 0x80, 0x03, 0x75, 0x48, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5} }, +{ 0x07fd, 16, {0x83, 0xe5, 0x48, 0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f} }, +{ 0x080d, 13, {0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} }, +{ 0x081a, 1, {0x22} }, +{ 0x081b, 4, {0x53, 0xd8, 0xef, 0x32} }, +{ 0x081f, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x7f, 0x0a, 0xfe, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0x74, 0x89} }, +{ 0x082f, 16, {0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0x29, 0x90, 0x7f} }, +{ 0x083f, 16, {0x96, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff} }, +{ 0x084f, 16, {0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x02} }, +{ 0x085f, 16, {0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} }, +{ 0x086f, 16, {0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf} }, +{ 0x087f, 16, {0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f} }, +{ 0x088f, 7, {0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x22} }, +{ 0x0896, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} }, +{ 0x08a6, 16, {0x09, 0x29, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29} }, +{ 0x08b6, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f} }, +{ 0x08c6, 16, {0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} }, +{ 0x08d6, 16, {0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01} }, +{ 0x08e6, 12, {0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x12, 0x0b, 0x00, 0x22} }, +{ 0x08f2, 16, {0x90, 0x95, 0xbe, 0xe4, 0x93, 0x70, 0x2f, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} }, +{ 0x0902, 16, {0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x7f} }, +{ 0x0912, 16, {0x9d, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12, 0xf0, 0x12, 0x08, 0x1f, 0x75, 0x82, 0xbe} }, +{ 0x0922, 7, {0x75, 0x83, 0x95, 0x74, 0xff, 0xf0, 0x22} }, +{ 0x0929, 16, {0x8e, 0x58, 0x8f, 0x59, 0xe5, 0x59, 0x15, 0x59, 0xae, 0x58, 0x70, 0x02, 0x15, 0x58, 0x4e, 0x60} }, +{ 0x0939, 7, {0x05, 0x12, 0x0a, 0x58, 0x80, 0xee, 0x22} }, +{ 0x0940, 2, {0x8f, 0x4c} }, +{ 0x0942, 16, {0xe4, 0xf5, 0x4d, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x6a, 0xab, 0x4e, 0xaa, 0x4f} }, +{ 0x0952, 16, {0xa9, 0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x03, 0x1d, 0xaf, 0x4d, 0x05, 0x4d, 0xef} }, +{ 0x0962, 16, {0xb5, 0x4c, 0x01, 0x22, 0x12, 0x9f, 0x48, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} }, +{ 0x0972, 14, {0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, +{ 0x0980, 1, {0x22} }, +{ 0x0981, 16, {0xe4, 0xfe, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x12, 0xab, 0x4e, 0xaa, 0x4f, 0xa9} }, +{ 0x0991, 16, {0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} }, +{ 0x09a1, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x9f, 0xba, 0x85, 0xf0, 0x4c, 0xf5, 0x4d, 0x62, 0x4c} }, +{ 0x09b1, 16, {0xe5, 0x4c, 0x62, 0x4d, 0xe5, 0x4d, 0x62, 0x4c, 0x29, 0xfd, 0xe5, 0x4c, 0x3a, 0xa9, 0x05, 0x75} }, +{ 0x09c1, 14, {0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, +{ 0x09cf, 1, {0x22} }, +{ 0x09d0, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} }, +{ 0x09e0, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} }, +{ 0x09f0, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} }, +{ 0x09f5, 5, {0x12, 0x08, 0x96, 0xd3, 0x22} }, +{ 0x09fa, 5, {0x12, 0x08, 0x1f, 0xd3, 0x22} }, +{ 0x09ff, 1, {0x32} }, { 0x0a00, 16, {0x02, 0x0b, 0xaa, 0x00, 0x02, 0x0b, 0xdd, 0x00, 0x02, 0x0b, 0xc2, 0x00, 0x02, 0x0c, 0x1c, 0x00} }, -{ 0x0a10, 16, {0x02, 0x0c, 0x06, 0x00, 0x02, 0x0a, 0xf7, 0x00, 0x02, 0x0a, 0xf8, 0x00, 0x02, 0x0a, 0xf9, 0x00} }, -{ 0x0a20, 16, {0x02, 0x0c, 0x37, 0x00, 0x02, 0x0d, 0x27, 0x00, 0x02, 0x0c, 0x73, 0x00, 0x02, 0x0d, 0x7b, 0x00} }, -{ 0x0a30, 16, {0x02, 0x0c, 0xaf, 0x00, 0x02, 0x0d, 0xcf, 0x00, 0x02, 0x0c, 0xeb, 0x00, 0x02, 0x0e, 0x23, 0x00} }, -{ 0x0a40, 16, {0x02, 0x0a, 0xfa, 0x00, 0x02, 0x0a, 0xfc, 0x00, 0x02, 0x0a, 0xfb, 0x00, 0x02, 0x0a, 0xfd, 0x00} }, -{ 0x0a50, 8, {0x02, 0x0e, 0x77, 0x00, 0x02, 0x0e, 0x8d, 0x00} }, -{ 0x0a58, 16, {0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} }, -{ 0x0a68, 16, {0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} }, -{ 0x0a78, 7, {0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} }, -{ 0x0a7f, 1, {0x22} }, -{ 0x0a80, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} }, -{ 0x0a90, 1, {0x07} }, -{ 0x0a91, 16, {0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} }, -{ 0x0aa1, 16, {0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} }, -{ 0x0ab1, 16, {0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} }, -{ 0x0ac1, 16, {0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} }, -{ 0x0ad1, 13, {0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} }, -{ 0x0ade, 15, {0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0aed, 5, {0x12, 0x08, 0x90, 0xd3, 0x22} }, -{ 0x0af2, 5, {0x12, 0x08, 0x19, 0xd3, 0x22} }, -{ 0x0af7, 1, {0x32} }, -{ 0x0af8, 1, {0x32} }, -{ 0x0af9, 1, {0x32} }, -{ 0x0afa, 1, {0x32} }, -{ 0x0afb, 1, {0x32} }, -{ 0x0afc, 1, {0x32} }, -{ 0x0afd, 1, {0x32} }, +{ 0x0a10, 16, {0x02, 0x0c, 0x06, 0x00, 0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xfe, 0x00, 0x02, 0x0a, 0xff, 0x00} }, +{ 0x0a20, 16, {0x02, 0x0c, 0x37, 0x00, 0x02, 0x0d, 0x29, 0x00, 0x02, 0x0c, 0x73, 0x00, 0x02, 0x0d, 0x7d, 0x00} }, +{ 0x0a30, 16, {0x02, 0x0c, 0xaf, 0x00, 0x02, 0x0d, 0xd1, 0x00, 0x02, 0x0c, 0xeb, 0x00, 0x02, 0x0e, 0x25, 0x00} }, +{ 0x0a40, 16, {0x02, 0x0d, 0x27, 0x00, 0x02, 0x0e, 0x79, 0x00, 0x02, 0x0d, 0x28, 0x00, 0x02, 0x0e, 0x7a, 0x00} }, +{ 0x0a50, 8, {0x02, 0x0e, 0x7b, 0x00, 0x02, 0x0e, 0x91, 0x00} }, +{ 0x0a58, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} }, +{ 0x0a68, 1, {0x22} }, +{ 0x0a69, 16, {0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} }, +{ 0x0a79, 16, {0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} }, +{ 0x0a89, 7, {0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} }, +{ 0x0a90, 1, {0x22} }, +{ 0x0a91, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} }, +{ 0x0aa1, 1, {0x07} }, +{ 0x0aa2, 16, {0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} }, +{ 0x0ab2, 16, {0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} }, +{ 0x0ac2, 16, {0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} }, +{ 0x0ad2, 16, {0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} }, +{ 0x0ae2, 13, {0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} }, +{ 0x0aef, 15, {0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0afe, 1, {0x32} }, +{ 0x0aff, 1, {0x32} }, { 0x0b00, 9, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} }, { 0x0b7d, 16, {0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} }, -{ 0x0b8d, 16, {0xd2, 0x00, 0x75, 0x8e, 0x10, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x10, 0x0c, 0x12, 0x08, 0xec} }, -{ 0x0b9d, 13, {0x12, 0x0e, 0xa9, 0x12, 0x90, 0xe6, 0x12, 0x1b, 0x0c, 0x12, 0x0a, 0x58, 0x22} }, +{ 0x0b8d, 16, {0xd2, 0x00, 0x75, 0x8e, 0x10, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12, 0x08, 0xf2} }, +{ 0x0b9d, 13, {0x12, 0x0e, 0xad, 0x12, 0x11, 0xe5, 0x12, 0x11, 0xc8, 0x12, 0x0a, 0x69, 0x22} }, { 0x0baa, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} }, { 0x0bba, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, { 0x0bc2, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} }, @@ -227,91 +222,97 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = { { 0x0cfb, 16, {0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x30, 0xe3, 0x13, 0xe5, 0x3b, 0x30, 0xe3, 0x07, 0x90, 0x20} }, { 0x0d0b, 16, {0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} }, { 0x0d1b, 12, {0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d27, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0d37, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x20} }, -{ 0x0d47, 16, {0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} }, -{ 0x0d57, 16, {0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, -{ 0x0d67, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, -{ 0x0d77, 4, {0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d7b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0d8b, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x20} }, -{ 0x0d9b, 16, {0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} }, -{ 0x0dab, 16, {0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, -{ 0x0dbb, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, -{ 0x0dcb, 4, {0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0dcf, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0ddf, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x20} }, -{ 0x0def, 16, {0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} }, -{ 0x0dff, 16, {0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, -{ 0x0e0f, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, -{ 0x0e1f, 4, {0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e23, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0e33, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x20} }, -{ 0x0e43, 16, {0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} }, -{ 0x0e53, 16, {0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, -{ 0x0e63, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, -{ 0x0e73, 4, {0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e77, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} }, -{ 0x0e87, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e8d, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} }, -{ 0x0e9d, 12, {0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0ea9, 16, {0x90, 0x01, 0x20, 0x12, 0x9d, 0x31, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} }, -{ 0x0eb9, 16, {0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} }, -{ 0x0ec9, 16, {0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, -{ 0x0ed9, 16, {0xc3, 0x94, 0x04, 0x50, 0x13, 0xef, 0x04, 0xa3, 0xf0, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x85, 0xe1} }, -{ 0x0ee9, 16, {0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xe3, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90} }, -{ 0x0ef9, 16, {0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x0f09, 16, {0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04} }, -{ 0x0f19, 16, {0xf0, 0x80, 0xdc, 0xe4, 0xf5, 0x30, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0} }, -{ 0x0f29, 16, {0x90, 0x01, 0x1e, 0xe0, 0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8} }, -{ 0x0f39, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x83} }, -{ 0x0f49, 16, {0x5f, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3a, 0x90, 0x01, 0x1e, 0xf0} }, -{ 0x0f59, 16, {0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20} }, -{ 0x0f69, 16, {0xf5, 0x83, 0xe0, 0x54, 0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83} }, -{ 0x0f79, 16, {0xee, 0xf0, 0x74, 0x36, 0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x32, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c} }, -{ 0x0f89, 16, {0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0} }, -{ 0x0f99, 16, {0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f} }, -{ 0x0fa9, 16, {0xf5, 0x4b, 0x60, 0x5e, 0xe4, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94} }, -{ 0x0fb9, 16, {0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4b} }, -{ 0x0fc9, 16, {0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4} }, -{ 0x0fd9, 16, {0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4} }, -{ 0x0fe9, 16, {0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x0ff9, 16, {0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12, 0x82, 0xd5, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0} }, -{ 0x1009, 3, {0x80, 0xa7, 0x22} }, -{ 0x100c, 16, {0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0x9b, 0x8b, 0xfd, 0x8b, 0x4d, 0x75} }, -{ 0x101c, 16, {0x4e, 0x12, 0x75, 0x4f, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4b} }, -{ 0x102c, 16, {0xf5, 0x4c, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} }, -{ 0x103c, 16, {0xa9, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0xe4, 0xfc, 0xec, 0x25, 0xe0, 0x24, 0xb4, 0xf5} }, -{ 0x104c, 16, {0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x0c, 0xbc, 0x10, 0xee, 0xe4, 0x90, 0x7f, 0xdd} }, -{ 0x105c, 16, {0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x11, 0xd2, 0xab, 0x4d, 0xaa, 0x4e, 0xa9, 0x4f} }, -{ 0x106c, 16, {0x90, 0x00, 0x01, 0x12, 0x9b, 0x8b, 0x64, 0x05, 0x60, 0x03, 0x02, 0x11, 0xc1, 0x90, 0x00, 0x03} }, -{ 0x107c, 16, {0x12, 0x9b, 0x8b, 0x64, 0x01, 0x60, 0x03, 0x02, 0x11, 0x48, 0x90, 0x00, 0x02, 0x12, 0x9b, 0x8b} }, -{ 0x108c, 16, {0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x11, 0x22, 0xec, 0xc3, 0x94, 0x10} }, -{ 0x109c, 16, {0x40, 0x03, 0x02, 0x11, 0x22, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4c, 0xae, 0x4b, 0x78, 0x02, 0xce} }, -{ 0x10ac, 16, {0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xf0, 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} }, -{ 0x10bc, 16, {0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe0, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01, 0xa8, 0x06} }, -{ 0x10cc, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe0, 0xf0, 0x90, 0x02, 0xae, 0xe0} }, -{ 0x10dc, 16, {0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4c, 0xae, 0x4b, 0x78} }, -{ 0x10ec, 16, {0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xe8, 0x2c, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x10fc, 16, {0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe1, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01} }, -{ 0x110c, 16, {0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x02} }, -{ 0x111c, 16, {0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0x9b, 0x8b, 0x25} }, -{ 0x112c, 16, {0x4c, 0xf5, 0x4c, 0xe4, 0x35, 0x4b, 0xf5, 0x4b, 0x90, 0x00, 0x05, 0x12, 0x9b, 0x8b, 0xfe, 0xe4} }, -{ 0x113c, 16, {0x25, 0x4c, 0xf5, 0x4c, 0xee, 0x35, 0x4b, 0xf5, 0x4b, 0x02, 0x11, 0xc4, 0xab, 0x4d, 0xaa, 0x4e} }, -{ 0x114c, 16, {0xa9, 0x4f, 0x90, 0x00, 0x03, 0x12, 0x9b, 0x8b, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} }, -{ 0x115c, 16, {0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0x9b, 0x8b, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} }, -{ 0x116c, 16, {0x4e, 0xef, 0x30, 0xe7, 0x1e, 0x90, 0x7f, 0xde, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80} }, -{ 0x117c, 16, {0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x4e} }, -{ 0x118c, 16, {0xf0, 0x80, 0x35, 0x90, 0x7f, 0xdf, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80, 0x02, 0xc3} }, -{ 0x119c, 16, {0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xad, 0xe0, 0x4e, 0xf0, 0xec} }, -{ 0x11ac, 16, {0x25, 0xe0, 0x24, 0xc5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x09, 0x7f} }, -{ 0x11bc, 16, {0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35} }, -{ 0x11cc, 16, {0x4e, 0xf5, 0x4e, 0x02, 0x10, 0x5d, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} }, -{ 0x11dc, 8, {0x7f, 0xae, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x00} }, -{ 0x11e4, 1, {0x22} }, -{ 0x11e5, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33} }, -{ 0x11f5, 7, {0xd8, 0xfc, 0x42, 0x3a, 0x7f, 0x00, 0x22} }, -{ 0x11fc, 3, {0x00, 0x03, 0x15} }, +{ 0x0d27, 1, {0x32} }, +{ 0x0d28, 1, {0x32} }, +{ 0x0d29, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, +{ 0x0d39, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x20} }, +{ 0x0d49, 16, {0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} }, +{ 0x0d59, 16, {0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, +{ 0x0d69, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, +{ 0x0d79, 4, {0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0d7d, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, +{ 0x0d8d, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x20} }, +{ 0x0d9d, 16, {0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} }, +{ 0x0dad, 16, {0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, +{ 0x0dbd, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, +{ 0x0dcd, 4, {0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0dd1, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, +{ 0x0de1, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x20} }, +{ 0x0df1, 16, {0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} }, +{ 0x0e01, 16, {0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, +{ 0x0e11, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, +{ 0x0e21, 4, {0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0e25, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, +{ 0x0e35, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x20} }, +{ 0x0e45, 16, {0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} }, +{ 0x0e55, 16, {0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} }, +{ 0x0e65, 16, {0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} }, +{ 0x0e75, 4, {0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0e79, 1, {0x32} }, +{ 0x0e7a, 1, {0x32} }, +{ 0x0e7b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} }, +{ 0x0e8b, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0e91, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} }, +{ 0x0ea1, 12, {0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x0ead, 16, {0x90, 0x01, 0x20, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} }, +{ 0x0ebd, 16, {0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} }, +{ 0x0ecd, 16, {0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, +{ 0x0edd, 16, {0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} }, +{ 0x0eed, 16, {0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f} }, +{ 0x0efd, 16, {0x1f, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0x17, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} }, +{ 0x0f0d, 16, {0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, +{ 0x0f1d, 16, {0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} }, +{ 0x0f2d, 16, {0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} }, +{ 0x0f3d, 16, {0xf5, 0x30, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, +{ 0x0f4d, 16, {0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} }, +{ 0x0f5d, 16, {0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x83, 0xb7, 0x90, 0x01, 0x1e} }, +{ 0x0f6d, 16, {0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3a, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, +{ 0x0f7d, 16, {0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x0f8d, 16, {0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x36} }, +{ 0x0f9d, 16, {0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x32, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} }, +{ 0x0fad, 16, {0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, +{ 0x0fbd, 16, {0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4b, 0x60, 0x5e} }, +{ 0x0fcd, 4, {0xe4, 0x90, 0x01, 0x1e} }, +{ 0x0fd1, 16, {0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} }, +{ 0x0fe1, 16, {0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4b, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} }, +{ 0x0ff1, 16, {0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} }, +{ 0x1001, 16, {0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} }, +{ 0x1011, 16, {0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} }, +{ 0x1021, 11, {0x83, 0x2d, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} }, +{ 0x102c, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x1030, 16, {0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} }, +{ 0x1040, 16, {0x4a, 0x70, 0x03, 0x02, 0x11, 0x74, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x11, 0x46, 0x90} }, +{ 0x1050, 16, {0x10, 0x56, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x11, 0x24, 0x02, 0x10, 0xdc, 0x02, 0x10, 0xc5, 0x02} }, +{ 0x1060, 16, {0x10, 0xab, 0x02, 0x10, 0x9a, 0x02, 0x10, 0x85, 0x02, 0x10, 0x6b, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x1070, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} }, +{ 0x1080, 16, {0xf0, 0x19, 0x02, 0x11, 0x46, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} }, +{ 0x1090, 16, {0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x11, 0x46, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, +{ 0x10a0, 16, {0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x11, 0x46, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x10b0, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} }, +{ 0x10c0, 16, {0xf0, 0x19, 0x02, 0x11, 0x46, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x10d0, 16, {0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x54, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} }, +{ 0x10e0, 16, {0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} }, +{ 0x10f0, 16, {0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} }, +{ 0x1100, 16, {0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, +{ 0x1110, 16, {0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} }, +{ 0x1120, 16, {0x9f, 0x8e, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} }, +{ 0x1130, 16, {0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} }, +{ 0x1140, 16, {0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x54, 0x30, 0xe0, 0xf7, 0x30} }, +{ 0x1150, 16, {0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} }, +{ 0x1160, 16, {0x10, 0x32, 0xe5, 0x54, 0x30, 0xe1, 0x03, 0x02, 0x10, 0x32, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} }, +{ 0x1170, 6, {0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} }, +{ 0x1176, 1, {0x22} }, +{ 0x1177, 2, {0xae, 0x07} }, +{ 0x1179, 16, {0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} }, +{ 0x1189, 16, {0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} }, +{ 0x1199, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} }, +{ 0x11a9, 16, {0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} }, +{ 0x11b9, 14, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} }, +{ 0x11c7, 1, {0x22} }, +{ 0x11c8, 16, {0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x7f, 0x05} }, +{ 0x11d8, 13, {0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x03, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x22} }, +{ 0x11e5, 16, {0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} }, +{ 0x11f5, 10, {0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, { 0x1200, 16, {0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0x10, 0x07, 0x01, 0x80, 0x42, 0x00, 0x01, 0x02} }, { 0x1210, 16, {0x03, 0x01, 0x09, 0x02, 0x58, 0x00, 0x01, 0x01, 0x04, 0x80, 0x3c, 0x09, 0x04, 0x00, 0x00, 0x0a} }, { 0x1220, 16, {0xff, 0xff, 0xff, 0x05, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40} }, @@ -438,557 +439,623 @@ static const struct whiteheat_hex_record whiteheat_firmware[] = { { 0x19a0, 16, {0x80, 0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74} }, { 0x19b0, 16, {0x00, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x02, 0x13, 0x43} }, { 0x19c0, 1, {0x32} }, -{ 0x19c1, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x19c5, 16, {0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} }, -{ 0x19d5, 16, {0x4a, 0x70, 0x03, 0x02, 0x1b, 0x09, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x1a, 0xdb, 0x90} }, -{ 0x19e5, 16, {0x19, 0xeb, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x1a, 0xb9, 0x02, 0x1a, 0x71, 0x02, 0x1a, 0x5a, 0x02} }, -{ 0x19f5, 16, {0x1a, 0x40, 0x02, 0x1a, 0x2f, 0x02, 0x1a, 0x1a, 0x02, 0x1a, 0x00, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x1a05, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} }, -{ 0x1a15, 16, {0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} }, -{ 0x1a25, 16, {0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x1a, 0xdb, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, -{ 0x1a35, 16, {0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x1a45, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} }, -{ 0x1a55, 16, {0xf0, 0x19, 0x02, 0x1a, 0xdb, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x1a65, 16, {0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x54, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} }, -{ 0x1a75, 16, {0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} }, -{ 0x1a85, 16, {0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} }, -{ 0x1a95, 16, {0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9b, 0xce, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, -{ 0x1aa5, 16, {0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} }, -{ 0x1ab5, 16, {0x9b, 0xb8, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} }, -{ 0x1ac5, 16, {0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} }, -{ 0x1ad5, 16, {0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x54, 0x30, 0xe0, 0xf7, 0x30} }, -{ 0x1ae5, 16, {0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} }, -{ 0x1af5, 16, {0x19, 0xc7, 0xe5, 0x54, 0x30, 0xe1, 0x03, 0x02, 0x19, 0xc7, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} }, -{ 0x1b05, 6, {0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} }, -{ 0x1b0b, 1, {0x22} }, -{ 0x1b0c, 16, {0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x7f, 0x02, 0x7d, 0xff, 0x12, 0x81, 0xe0, 0x7f, 0x05} }, -{ 0x1b1c, 13, {0x7e, 0x00, 0x12, 0x09, 0x23, 0x7f, 0x03, 0x7d, 0xff, 0x12, 0x81, 0xe0, 0x22} }, -{ 0x1b29, 16, {0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0} }, -{ 0x8000, 4, {0x8e, 0x54, 0x8f, 0x55} }, -{ 0x8004, 16, {0x75, 0x56, 0x03, 0xe5, 0x55, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe} }, -{ 0x8014, 16, {0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x81, 0x0e, 0xe5, 0x56, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} }, -{ 0x8024, 16, {0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x80, 0xb2, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} }, -{ 0x8034, 16, {0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} }, -{ 0x8044, 16, {0x80, 0x6c, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} }, -{ 0x8054, 16, {0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x56, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} }, -{ 0x8064, 16, {0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x55, 0x24, 0x06, 0xf5, 0x82} }, -{ 0x8074, 16, {0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9b, 0xce, 0x85, 0xf0, 0x82, 0xf5} }, -{ 0x8084, 16, {0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x55, 0x24} }, -{ 0x8094, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0x9b, 0xb8, 0x85} }, -{ 0x80a4, 16, {0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9b, 0xb8, 0x90, 0x7f} }, -{ 0x80b4, 16, {0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} }, -{ 0x80c4, 16, {0x22, 0xe5, 0x57, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} }, -{ 0x80d4, 16, {0xe5, 0x56, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0x23, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x80e4, 16, {0x80, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} }, -{ 0x80f4, 16, {0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} }, -{ 0x8104, 12, {0x56, 0x03, 0x02, 0x80, 0x07, 0x15, 0x56, 0x02, 0x80, 0x07, 0x7f, 0x08} }, -{ 0x8110, 1, {0x22} }, -{ 0x8111, 2, {0xac, 0x07} }, -{ 0x8113, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xec, 0x25, 0xe0, 0x44, 0x41, 0x90, 0x7f, 0xa6, 0xf0} }, -{ 0x8123, 16, {0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90} }, -{ 0x8133, 16, {0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0xd4, 0x80, 0xf8, 0x90, 0x7f} }, -{ 0x8143, 16, {0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xdc, 0x20, 0xe1, 0x09, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} }, -{ 0x8153, 16, {0xf9, 0x22, 0xed, 0x30, 0xe2, 0x0c, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} }, -{ 0x8163, 16, {0xfa, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7b, 0x1e} }, -{ 0x8173, 16, {0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6} }, -{ 0x8183, 16, {0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0x86, 0x80, 0xf8, 0x90, 0x7f, 0xa5, 0xe0} }, -{ 0x8193, 16, {0xfd, 0x20, 0xe0, 0xdc, 0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x19, 0x90, 0x7f, 0xa5, 0xe0} }, -{ 0x81a3, 16, {0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03} }, -{ 0x81b3, 16, {0x02, 0x81, 0x13, 0x80, 0xf5, 0x90, 0x7f, 0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xd9, 0x30, 0xe2, 0x09} }, -{ 0x81c3, 16, {0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x81d3, 12, {0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} }, -{ 0x81df, 1, {0x22} }, -{ 0x81e0, 2, {0xae, 0x07} }, -{ 0x81e2, 16, {0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} }, -{ 0x81f2, 16, {0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} }, -{ 0x8202, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} }, -{ 0x8212, 16, {0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} }, -{ 0x8222, 14, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} }, -{ 0x8230, 1, {0x22} }, -{ 0x8231, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} }, -{ 0x8241, 15, {0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x8250, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} }, -{ 0x8260, 16, {0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5e, 0x74, 0xbf} }, -{ 0x8270, 16, {0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, -{ 0x8280, 16, {0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} }, -{ 0x8290, 16, {0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} }, -{ 0x82a0, 16, {0xef, 0x55, 0x3b, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, -{ 0x82b0, 16, {0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} }, -{ 0x82c0, 16, {0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5e, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} }, -{ 0x82d0, 4, {0x83, 0xa3, 0xe9, 0xf0} }, -{ 0x82d4, 1, {0x22} }, -{ 0x82d5, 4, {0x8f, 0x5e, 0x8d, 0x5f} }, -{ 0x82d9, 16, {0xe4, 0xf5, 0x60, 0x74, 0x3c, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24} }, -{ 0x82e9, 16, {0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, -{ 0x82f9, 16, {0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0x9c, 0xea, 0x50} }, -{ 0x8309, 16, {0x3c, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} }, -{ 0x8319, 16, {0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} }, -{ 0x8329, 16, {0x00, 0xc3, 0x12, 0x9c, 0xea, 0x40, 0x0c, 0x75, 0x60, 0x40, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76} }, -{ 0x8339, 16, {0x10, 0x80, 0x0a, 0x75, 0x60, 0x80, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76, 0x38, 0xe5, 0x60, 0x45} }, -{ 0x8349, 16, {0x5f, 0x44, 0x01, 0xff, 0xe5, 0x5e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x8359, 5, {0x20, 0xf5, 0x83, 0xef, 0xf0} }, -{ 0x835e, 1, {0x22} }, -{ 0x835f, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82} }, -{ 0x836f, 16, {0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x55, 0x8f, 0x56, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5} }, -{ 0x837f, 16, {0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7} }, -{ 0x838f, 16, {0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x54, 0xf8, 0xe4, 0xf6} }, -{ 0x839f, 16, {0xe5, 0x56, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf} }, -{ 0x83af, 16, {0x54, 0x7d, 0x06, 0x12, 0x82, 0xd5, 0xaf, 0x54, 0x7d, 0x01, 0x12, 0x82, 0x50, 0x85, 0x56, 0x82} }, -{ 0x83bf, 16, {0x85, 0x55, 0x83, 0xa3, 0xa3, 0xe0, 0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x56, 0x24, 0x05, 0xf5} }, -{ 0x83cf, 16, {0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xe5, 0x56, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x55} }, -{ 0x83df, 16, {0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x82, 0xd5, 0x74, 0xf8, 0x25, 0x54, 0xf5} }, -{ 0x83ef, 16, {0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x54, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c} }, -{ 0x83ff, 16, {0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe} }, -{ 0x840f, 16, {0xe5, 0x54, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3} }, -{ 0x841f, 16, {0xef, 0xf0, 0xaf, 0x54, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42} }, -{ 0x842f, 3, {0x30, 0x7f, 0x00} }, -{ 0x8432, 1, {0x22} }, -{ 0x8433, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xff, 0xe4, 0xfd, 0x12, 0x82, 0x50, 0x74, 0xf8} }, -{ 0x8443, 16, {0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x54, 0x75, 0xf0, 0x08} }, -{ 0x8453, 16, {0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x56, 0x8f, 0x57, 0xf5, 0x83} }, -{ 0x8463, 16, {0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf} }, -{ 0x8473, 16, {0x54, 0x7d, 0x06, 0x12, 0x82, 0xd5, 0xe5, 0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5} }, -{ 0x8483, 16, {0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x57, 0x82, 0x85, 0x56, 0x83, 0xe0, 0xf5, 0x55, 0xaf, 0x54} }, -{ 0x8493, 16, {0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x30, 0xe5, 0x54} }, -{ 0x84a3, 16, {0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5} }, -{ 0x84b3, 16, {0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} }, -{ 0x84c3, 1, {0x22} }, -{ 0x84c4, 4, {0x8e, 0x54, 0x8f, 0x55} }, -{ 0x84c8, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x56, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82} }, -{ 0x84d8, 16, {0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x70, 0x23, 0x85, 0x55, 0x82, 0x8e, 0x83, 0xa3} }, -{ 0x84e8, 16, {0xe0, 0x30, 0xe0, 0x07, 0xaf, 0x56, 0x7d, 0x02, 0x12, 0x82, 0xd5, 0x85, 0x55, 0x82, 0x85, 0x54} }, -{ 0x84f8, 15, {0x83, 0xa3, 0xe0, 0x30, 0xe1, 0x07, 0xaf, 0x56, 0x7d, 0x04, 0x12, 0x82, 0xd5, 0x7f, 0x00} }, -{ 0x8507, 1, {0x22} }, -{ 0x8508, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} }, -{ 0x8518, 16, {0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} }, -{ 0x8528, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} }, -{ 0x8538, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} }, -{ 0x8548, 16, {0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} }, -{ 0x8558, 16, {0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} }, -{ 0x8568, 16, {0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} }, -{ 0x8578, 16, {0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} }, -{ 0x8588, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} }, -{ 0x8598, 3, {0x83, 0xf0, 0x22} }, -{ 0x859b, 16, {0x79, 0x0d, 0x8e, 0x54, 0x8f, 0x55, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x75, 0xf0, 0x0d, 0xa4, 0x24} }, -{ 0x85ab, 16, {0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f} }, -{ 0x85bb, 16, {0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x55, 0xe5} }, -{ 0x85cb, 16, {0x55, 0xaa, 0x54, 0x70, 0x02, 0x05, 0x54, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9} }, -{ 0x85db, 5, {0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x85e0, 1, {0x22} }, -{ 0x85e1, 4, {0x8e, 0x54, 0x8f, 0x55} }, -{ 0x85e5, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82} }, -{ 0x85f5, 16, {0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x5c, 0x8f, 0x5d, 0xaa, 0x06, 0xa9, 0x55, 0x7b, 0x01, 0xc0} }, -{ 0x8605, 16, {0x03, 0xc0, 0x01, 0xe5, 0x5b, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0} }, -{ 0x8615, 16, {0xa8, 0x01, 0xfc, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9b, 0x49} }, -{ 0x8625, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3} }, -{ 0x8635, 16, {0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0x9c, 0xea, 0x40, 0x10} }, -{ 0x8645, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0x9d, 0x31, 0x00, 0x00, 0x00, 0x08, 0x80, 0x2e} }, -{ 0x8655, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3} }, -{ 0x8665, 16, {0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0x9c, 0xea, 0x50, 0x0e} }, -{ 0x8675, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0x9d, 0x31, 0x00, 0x07, 0x08, 0x00, 0x85, 0x55} }, -{ 0x8685, 16, {0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} }, -{ 0x8695, 16, {0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0x9c, 0x58, 0x8f, 0x59, 0x8e, 0x58, 0x8d} }, -{ 0x86a5, 16, {0x57, 0x8c, 0x56, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0x9c, 0x58, 0xaf, 0x03} }, -{ 0x86b5, 16, {0x8f, 0x5a, 0xaf, 0x59, 0xae, 0x58, 0xad, 0x57, 0xac, 0x56, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x86c5, 16, {0x78, 0x00, 0x12, 0x9c, 0x58, 0x8f, 0x59, 0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56, 0xe5, 0x5a, 0xc3} }, -{ 0x86d5, 16, {0x94, 0x05, 0x40, 0x15, 0xe5, 0x59, 0x24, 0x01, 0xf5, 0x59, 0xe4, 0x35, 0x58, 0xf5, 0x58, 0xe4} }, -{ 0x86e5, 16, {0x35, 0x57, 0xf5, 0x57, 0xe4, 0x35, 0x56, 0xf5, 0x56, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3} }, -{ 0x86f5, 16, {0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85} }, -{ 0x8705, 16, {0x5d, 0x82, 0x85, 0x5c, 0x83, 0xe5, 0x59, 0xf0, 0xaf, 0x59, 0xae, 0x58, 0xad, 0x57, 0xac, 0x56} }, -{ 0x8715, 16, {0x78, 0x08, 0x12, 0x9c, 0xfb, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xef, 0xf0, 0x85, 0x5d} }, -{ 0x8725, 16, {0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5, 0x5a, 0xe5, 0x55} }, -{ 0x8735, 16, {0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62, 0x05, 0x43, 0x5a} }, -{ 0x8745, 16, {0x0a, 0x80, 0x10, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5a, 0x08, 0x80, 0x07, 0xef, 0xb4, 0x74, 0x03} }, -{ 0x8755, 16, {0x43, 0x5a, 0x02, 0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff} }, -{ 0x8765, 16, {0x30, 0xe3, 0x03, 0x43, 0x5a, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5a, 0x40, 0xe5, 0x5d, 0x24} }, -{ 0x8775, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x55, 0x24, 0x0b} }, -{ 0x8785, 16, {0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf} }, -{ 0x8795, 16, {0x5b, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0xe5, 0x5d} }, -{ 0x87a5, 16, {0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5a} }, -{ 0x87b5, 16, {0x80, 0x10, 0xaf, 0x5b, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4} }, -{ 0x87c5, 16, {0x52, 0x3b, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5d} }, -{ 0x87d5, 16, {0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5a, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5} }, -{ 0x87e5, 16, {0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} }, -{ 0x87f5, 16, {0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83} }, -{ 0x8805, 16, {0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5} }, -{ 0x8815, 16, {0x55, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x06} }, -{ 0x8825, 16, {0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09, 0xf5, 0x82, 0xe4} }, -{ 0x8835, 16, {0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5} }, -{ 0x8845, 16, {0x83, 0xef, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5d} }, -{ 0x8855, 16, {0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5b, 0x7d, 0x06, 0x12, 0x82, 0xd5, 0x75, 0x5a} }, -{ 0x8865, 16, {0x08, 0xe5, 0x55, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43} }, -{ 0x8875, 16, {0x5a, 0x10, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x54, 0x03} }, -{ 0x8885, 16, {0x45, 0x5a, 0xf0, 0xe5, 0x55, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0x14} }, -{ 0x8895, 16, {0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xe5, 0x55, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5} }, -{ 0x88a5, 16, {0x83, 0xe0, 0x24, 0xfb, 0x4f, 0xf5, 0x5a, 0xe5, 0x55, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x54} }, -{ 0x88b5, 16, {0xf5, 0x83, 0xe0, 0x24, 0xd0, 0x60, 0x15, 0x14, 0x60, 0x17, 0x24, 0xc2, 0x60, 0x09, 0x24, 0x0a} }, -{ 0x88c5, 16, {0x70, 0x12, 0x43, 0x5a, 0x18, 0x80, 0x0d, 0x43, 0x5a, 0x08, 0x80, 0x08, 0x43, 0x5a, 0x38, 0x80} }, -{ 0x88d5, 16, {0x03, 0x43, 0x5a, 0x28, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5a, 0xf0} }, -{ 0x88e5, 9, {0xaf, 0x5b, 0x7d, 0x01, 0x12, 0x82, 0x50, 0x7f, 0x00} }, -{ 0x88ee, 1, {0x22} }, -{ 0x88ef, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4} }, -{ 0x88ff, 16, {0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01, 0x2c, 0x74, 0x08, 0xf0, 0xef, 0x04, 0xa3, 0xf0, 0xe4} }, -{ 0x890f, 16, {0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5} }, -{ 0x891f, 16, {0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82} }, -{ 0x892f, 16, {0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2f, 0xf8} }, -{ 0x893f, 16, {0xe6, 0xa3, 0xf0, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x54} }, -{ 0x894f, 16, {0x7f, 0x02, 0x12, 0x81, 0x11, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xe5, 0x54, 0x5f} }, -{ 0x895f, 16, {0x90, 0x01, 0x32, 0xf0, 0x7e, 0x01, 0x7f, 0x2c, 0x75, 0x60, 0x00, 0x75, 0x5f, 0x00, 0x75, 0x5e} }, -{ 0x896f, 11, {0x00, 0x75, 0x5d, 0x00, 0x7d, 0x07, 0x12, 0x8e, 0x0c, 0x7f, 0x00} }, -{ 0x897a, 1, {0x22} }, -{ 0x897b, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0xf8, 0xf5, 0x82, 0xe4, 0x34, 0x1f} }, -{ 0x898b, 16, {0xaf, 0x82, 0xfe, 0x90, 0x01, 0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24} }, -{ 0x899b, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f} }, -{ 0x89ab, 16, {0x33, 0x75, 0x60, 0x00, 0x75, 0x5f, 0x00, 0x75, 0x5e, 0x00, 0x75, 0x5d, 0x00, 0x7d, 0x02, 0x12} }, -{ 0x89bb, 4, {0x8e, 0x0c, 0x7f, 0x00} }, -{ 0x89bf, 1, {0x22} }, -{ 0x89c0, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0xf8, 0xf5, 0x82, 0xe4, 0x34, 0x1f} }, -{ 0x89d0, 16, {0xad, 0x82, 0xfc, 0x8f, 0x82, 0xa3, 0xe0, 0x60, 0x0f, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c} }, -{ 0x89e0, 16, {0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x11, 0xae, 0x04, 0xaf, 0x05, 0xef, 0x24, 0x04, 0xf5} }, -{ 0x89f0, 11, {0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0x7f, 0x00} }, -{ 0x89fb, 1, {0x22} }, -{ 0x89fc, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0xf8, 0xf5, 0x82, 0xe4, 0x34, 0x1f} }, -{ 0x8a0c, 16, {0xad, 0x82, 0xfc, 0x8f, 0x82, 0xa3, 0xe0, 0x60, 0x0f, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c} }, -{ 0x8a1c, 16, {0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x11, 0xae, 0x04, 0xaf, 0x05, 0xef, 0x24, 0x04, 0xf5} }, -{ 0x8a2c, 11, {0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x00} }, -{ 0x8a37, 1, {0x22} }, -{ 0x8a38, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0xf8, 0xf5, 0x82, 0xe4, 0x34, 0x1f} }, -{ 0x8a48, 16, {0xad, 0x82, 0xfc, 0x8f, 0x82, 0xa3, 0xe0, 0x60, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xa3} }, -{ 0x8a58, 16, {0xe0, 0x44, 0x40, 0xf0, 0x80, 0x0f, 0xae, 0x04, 0xaf, 0x05, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3} }, -{ 0x8a68, 7, {0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} }, -{ 0x8a6f, 1, {0x22} }, -{ 0x8a70, 4, {0x8e, 0x54, 0x8f, 0x55} }, -{ 0x8a74, 16, {0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x58, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x24, 0xfe, 0x60} }, -{ 0x8a84, 16, {0x16, 0x14, 0x60, 0x1f, 0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75} }, -{ 0x8a94, 16, {0x56, 0x7e, 0x75, 0x57, 0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x56, 0x7e, 0x75, 0x57} }, -{ 0x8aa4, 16, {0x00, 0x80, 0x16, 0x7e, 0x7d, 0x7f, 0x80, 0x75, 0x56, 0x7d, 0x75, 0x57, 0x80, 0x80, 0x0a, 0x7e} }, -{ 0x8ab4, 16, {0x7d, 0x7f, 0x00, 0x75, 0x56, 0x7d, 0x75, 0x57, 0x00, 0xe5, 0x58, 0x70, 0x20, 0x85, 0x57, 0x82} }, -{ 0x8ac4, 16, {0x85, 0x56, 0x83, 0x74, 0xff, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0x25, 0xe0, 0x24} }, -{ 0x8ad4, 16, {0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x4d, 0xe5, 0x55, 0x24} }, -{ 0x8ae4, 16, {0x02, 0xff, 0xe4, 0x35, 0x54, 0xfe, 0xe5, 0x58, 0x60, 0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} }, -{ 0x8af4, 16, {0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x57, 0xe5, 0x57, 0xaa, 0x56, 0x70, 0x02} }, -{ 0x8b04, 16, {0x05, 0x56, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x15, 0x58, 0x80, 0xd9, 0x85, 0x55, 0x82} }, -{ 0x8b14, 16, {0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0x25, 0xe0, 0x24} }, -{ 0x8b24, 12, {0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} }, -{ 0x8b30, 1, {0x22} }, -{ 0x8b31, 16, {0xef, 0x24, 0x05, 0xf5, 0x55, 0xe4, 0x3e, 0xf5, 0x54, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} }, -{ 0x8b41, 16, {0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} }, -{ 0x8b51, 16, {0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x56, 0xf5, 0x57, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, -{ 0x8b61, 16, {0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8c, 0x12} }, -{ 0x8b71, 16, {0x24, 0x14, 0x60, 0x03, 0x02, 0x8c, 0x5e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe} }, -{ 0x8b81, 16, {0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x59, 0x74, 0x01, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59} }, -{ 0x8b91, 16, {0x94, 0x40, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5} }, -{ 0x8ba1, 16, {0x57, 0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x50, 0x03, 0x02, 0x8c, 0x61, 0xae, 0x58, 0xaf, 0x59} }, -{ 0x8bb1, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} }, -{ 0x8bc1, 16, {0x56, 0xf5, 0x57, 0x02, 0x8c, 0x61, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} }, -{ 0x8bd1, 16, {0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59, 0x94} }, -{ 0x8be1, 16, {0x10, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x10, 0xd3, 0xe5, 0x57} }, -{ 0x8bf1, 16, {0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x40, 0x68, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85} }, -{ 0x8c01, 16, {0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x80} }, -{ 0x8c11, 16, {0x4f, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} }, -{ 0x8c21, 16, {0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0x45, 0x59, 0x60, 0x0b, 0xd3, 0xe5, 0x59, 0x94, 0x40, 0xe5} }, -{ 0x8c31, 16, {0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5, 0x57, 0x95, 0x59} }, -{ 0x8c41, 16, {0xe5, 0x56, 0x95, 0x58, 0x40, 0x17, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, -{ 0x8c51, 16, {0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x7f, 0x01, 0x22} }, -{ 0x8c61, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8d, 0x21, 0x24, 0xf9} }, -{ 0x8c71, 16, {0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8d, 0x71, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0xb5} }, -{ 0x8c81, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} }, -{ 0x8c91, 16, {0x94, 0x00, 0x40, 0x03, 0x02, 0x8d, 0xb5, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57} }, -{ 0x8ca1, 16, {0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02, 0x8d, 0xb5, 0x90, 0x01, 0x75, 0xe0} }, -{ 0x8cb1, 16, {0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9b} }, -{ 0x8cc1, 16, {0xce, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, -{ 0x8cd1, 16, {0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8d} }, -{ 0x8ce1, 16, {0xb5, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8d, 0xb5, 0x90, 0x01, 0x76} }, -{ 0x8cf1, 16, {0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02} }, -{ 0x8d01, 16, {0x8d, 0xb5, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} }, -{ 0x8d11, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9b, 0xce, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} }, -{ 0x8d21, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} }, -{ 0x8d31, 16, {0x94, 0x00, 0x50, 0x03, 0x02, 0x8d, 0xb5, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} }, -{ 0x8d41, 16, {0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e} }, -{ 0x8d51, 16, {0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} }, -{ 0x8d61, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9b, 0xce, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} }, -{ 0x8d71, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} }, -{ 0x8d81, 16, {0xa3, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x60, 0x24} }, -{ 0x8d91, 16, {0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9b, 0xce, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} }, -{ 0x8da1, 16, {0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9b, 0xce, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, -{ 0x8db1, 16, {0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3} }, -{ 0x8dc1, 16, {0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x75, 0x60, 0x00, 0x75, 0x5f, 0x00, 0x75, 0x5e, 0x00, 0x75} }, -{ 0x8dd1, 7, {0x5d, 0x00, 0x12, 0x8e, 0x0c, 0x7f, 0x00} }, -{ 0x8dd8, 1, {0x22} }, -{ 0x8dd9, 16, {0x8e, 0x61, 0x8f, 0x62, 0x8c, 0x63, 0x8d, 0x64, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x62} }, -{ 0x8de9, 16, {0xe5, 0x62, 0xae, 0x61, 0x70, 0x02, 0x05, 0x61, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} }, -{ 0x8df9, 16, {0x64, 0xe5, 0x64, 0xac, 0x63, 0x70, 0x02, 0x05, 0x63, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, -{ 0x8e09, 3, {0x80, 0xd6, 0x22} }, -{ 0x8e0c, 16, {0x8d, 0x5c, 0xab, 0x07, 0xaa, 0x06, 0xaf, 0x60, 0xae, 0x5f, 0xad, 0x5e, 0xac, 0x5d, 0xec, 0x4d} }, -{ 0x8e1c, 16, {0x4e, 0x4f, 0x60, 0x1c, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x1c, 0x7f, 0xff, 0x7e, 0xff, 0x7d} }, -{ 0x8e2c, 16, {0xff, 0x7c, 0xff, 0x78, 0x5d, 0x12, 0x9d, 0x0e, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0x09, 0x80, 0xe4} }, -{ 0x8e3c, 16, {0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0xf9, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16, 0xaf, 0x03} }, -{ 0x8e4c, 16, {0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5c, 0x12, 0x8d, 0xd9, 0x90, 0x7f, 0xc3, 0xe5, 0x5c} }, -{ 0x8e5c, 7, {0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00, 0x22} }, -{ 0x8e63, 16, {0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0x90, 0x20, 0x70, 0xe0, 0x54, 0xf0, 0xff, 0xc4, 0x54, 0x0f} }, -{ 0x8e73, 16, {0x90, 0x01, 0x85, 0xf0, 0x90, 0x11, 0xfd, 0xe4, 0x93, 0x90, 0x01, 0x86, 0xf0, 0x90, 0x11, 0xfe} }, -{ 0x8e83, 16, {0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} }, -{ 0x8e93, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e} }, -{ 0x8ea3, 16, {0x01, 0x7f, 0x7c, 0x12, 0x19, 0xc1, 0x7e, 0x01, 0x7f, 0x84, 0x75, 0x60, 0x00, 0x75, 0x5f, 0x00} }, -{ 0x8eb3, 13, {0x75, 0x5e, 0x00, 0x75, 0x5d, 0x00, 0x7d, 0x14, 0x12, 0x8e, 0x0c, 0x7f, 0x00} }, -{ 0x8ec0, 1, {0x22} }, -{ 0x8ec1, 4, {0x8e, 0x4b, 0x8f, 0x4c} }, -{ 0x8ec5, 16, {0x85, 0x4b, 0x4e, 0x85, 0x4c, 0x4f, 0xe5, 0x4f, 0x24, 0x01, 0xf5, 0x53, 0xe4, 0x35, 0x4e, 0xf5} }, -{ 0x8ed5, 16, {0x52, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0x14, 0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x8f} }, -{ 0x8ee5, 16, {0xd6, 0x90, 0x8e, 0xed, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x8f, 0x1a, 0x02, 0x8f, 0x26, 0x02, 0x8f} }, -{ 0x8ef5, 16, {0x32, 0x02, 0x8f, 0x5c, 0x02, 0x8f, 0x67, 0x02, 0x8f, 0x72, 0x02, 0x8f, 0x7d, 0x02, 0x8f, 0x88} }, -{ 0x8f05, 16, {0x02, 0x8f, 0x93, 0x02, 0x8f, 0x9e, 0x02, 0x8f, 0xa9, 0x02, 0x8f, 0xb0, 0x02, 0x8f, 0xd6, 0x02} }, -{ 0x8f15, 16, {0x8f, 0xbb, 0x02, 0x8f, 0xc6, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x83, 0x5f, 0x8f, 0x4d, 0x02, 0x8f} }, -{ 0x8f25, 16, {0xd6, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x84, 0x33, 0x8f, 0x4d, 0x02, 0x8f, 0xd6, 0x85, 0x52, 0x50} }, -{ 0x8f35, 16, {0x85, 0x53, 0x51, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x50, 0xfe, 0x12, 0x85, 0x08, 0xaf} }, -{ 0x8f45, 16, {0x51, 0xae, 0x50, 0x12, 0x85, 0x9b, 0xef, 0x70, 0x03, 0x02, 0x8f, 0xd6, 0xaf, 0x51, 0xae, 0x50} }, -{ 0x8f55, 16, {0x12, 0x85, 0xe1, 0x8f, 0x4d, 0x80, 0x7a, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x89, 0xc0, 0x8f, 0x4d} }, -{ 0x8f65, 16, {0x80, 0x6f, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x89, 0xfc, 0x8f, 0x4d, 0x80, 0x64, 0xaf, 0x53, 0xae} }, -{ 0x8f75, 16, {0x52, 0x12, 0x8a, 0x38, 0x8f, 0x4d, 0x80, 0x59, 0xaf, 0x4c, 0xae, 0x4b, 0x12, 0x8b, 0x31, 0x8f} }, -{ 0x8f85, 16, {0x4d, 0x80, 0x4e, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x88, 0xef, 0x8f, 0x4d, 0x80, 0x43, 0xaf, 0x53} }, -{ 0x8f95, 16, {0xae, 0x52, 0x12, 0x84, 0xc4, 0x8f, 0x4d, 0x80, 0x38, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x89, 0x7b} }, -{ 0x8fa5, 16, {0x8f, 0x4d, 0x80, 0x2d, 0x12, 0x8e, 0x63, 0x8f, 0x4d, 0x80, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12} }, -{ 0x8fb5, 16, {0x11, 0xe5, 0x8f, 0x4d, 0x80, 0x1b, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0x70, 0x8f, 0x4d, 0x80} }, -{ 0x8fc5, 16, {0x10, 0xaf, 0x4c, 0xae, 0x4b, 0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8d, 0xd9, 0xe4, 0xf5} }, -{ 0x8fd5, 16, {0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24, 0xfe} }, -{ 0x8fe5, 16, {0x70, 0x2b, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, -{ 0x8ff5, 16, {0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x75, 0x60, 0x00, 0x75, 0x5f, 0x00} }, -{ 0x9005, 15, {0x75, 0x5e, 0x00, 0x75, 0x5d, 0x00, 0x7d, 0x03, 0x12, 0x8e, 0x0c, 0x8f, 0x4d, 0xaf, 0x4d} }, -{ 0x9014, 1, {0x22} }, -{ 0x9015, 8, {0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b} }, -{ 0x901d, 16, {0x75, 0x55, 0x01, 0x75, 0x56, 0x9c, 0xe4, 0xf5, 0x54, 0xaf, 0x50, 0x15, 0x50, 0xef, 0x70, 0x03} }, -{ 0x902d, 16, {0x02, 0x90, 0xb3, 0xaf, 0x4f, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4e} }, -{ 0x903d, 16, {0xae, 0x4d, 0xad, 0x4c, 0xac, 0x4b, 0x12, 0x9c, 0x58, 0xaf, 0x03, 0x8f, 0x53, 0xaf, 0x4e, 0xae} }, -{ 0x904d, 16, {0x4d, 0xad, 0x4c, 0xac, 0x4b, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x4f, 0xe4} }, -{ 0x905d, 16, {0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} }, -{ 0x906d, 16, {0x12, 0x9c, 0x58, 0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b, 0xe5, 0x53, 0x24, 0x30, 0xf5} }, -{ 0x907d, 16, {0x53, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x53, 0xf5, 0x53, 0x05, 0x56, 0xe5, 0x56} }, -{ 0x908d, 16, {0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x56, 0xe5} }, -{ 0x909d, 16, {0x56, 0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x53, 0xf0, 0x05} }, -{ 0x90ad, 16, {0x54, 0x05, 0x54, 0x02, 0x90, 0x26, 0xe5, 0x56, 0x15, 0x56, 0x70, 0x02, 0x15, 0x55, 0xaf, 0x54} }, -{ 0x90bd, 16, {0x15, 0x54, 0xef, 0x60, 0x23, 0xe5, 0x56, 0x15, 0x56, 0xae, 0x55, 0x70, 0x02, 0x15, 0x55, 0xf5} }, -{ 0x90cd, 16, {0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x52, 0xe5, 0x52, 0xac, 0x51, 0x70, 0x02, 0x05, 0x51, 0x14} }, -{ 0x90dd, 8, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} }, -{ 0x90e5, 1, {0x22} }, -{ 0x90e6, 16, {0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} }, -{ 0x90f6, 10, {0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, -{ 0x9100, 16, {0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} }, -{ 0x9110, 16, {0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} }, -{ 0x9120, 16, {0xe4, 0xef, 0x55, 0x30, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} }, -{ 0x9130, 16, {0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, -{ 0x9140, 16, {0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9b, 0xb8, 0xfc, 0xd3, 0xe5, 0xf0} }, -{ 0x9150, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, -{ 0x9160, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x9170, 1, {0x22} }, -{ 0x9171, 16, {0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} }, -{ 0x9181, 16, {0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} }, -{ 0x9191, 16, {0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} }, -{ 0x91a1, 16, {0x9b, 0x49, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9b, 0xb8, 0xfc, 0xd3, 0xe5, 0xf0} }, -{ 0x91b1, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, -{ 0x91c1, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x91d1, 1, {0x22} }, -{ 0x91d2, 16, {0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x5e, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x50, 0x7b, 0x75, 0x51} }, -{ 0x91e2, 16, {0x80, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x50, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x52, 0xf5} }, -{ 0x91f2, 16, {0x53, 0x89, 0x54, 0xfe, 0x12, 0x91, 0x71, 0xef, 0x60, 0x3b, 0xab, 0x52, 0xaa, 0x53, 0xa9, 0x54} }, -{ 0x9202, 16, {0x12, 0x9b, 0x72, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0x9b, 0x8b, 0xb4, 0x02, 0x16, 0xc2, 0xaf} }, -{ 0x9212, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} }, -{ 0x9222, 16, {0x04, 0xf0, 0xd2, 0xaf, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3} }, -{ 0x9232, 5, {0x74, 0x04, 0xf0, 0xd2, 0xaf} }, -{ 0x9237, 1, {0x22} }, -{ 0x9238, 16, {0x12, 0x91, 0xd2, 0xe4, 0xf5, 0x4b, 0x74, 0x36, 0x25, 0x4b, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4c} }, -{ 0x9248, 16, {0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4c, 0xff, 0xc4} }, -{ 0x9258, 16, {0x54, 0x0f, 0xf5, 0x4d, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} }, -{ 0x9268, 16, {0x83, 0xe5, 0x4c, 0xf0, 0xaf, 0x4b, 0x7d, 0x01, 0xe5, 0x4c, 0x45, 0x4d, 0xfb, 0x12, 0x91, 0x00} }, -{ 0x9278, 16, {0xef, 0x70, 0x05, 0x12, 0x91, 0xd2, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40} }, -{ 0x9288, 16, {0xb5, 0x12, 0x91, 0xd2, 0xe5, 0x3a, 0x60, 0x48, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} }, -{ 0x9298, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x55, 0x3a, 0x60, 0x29, 0xe5, 0x4b} }, -{ 0x92a8, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} }, -{ 0x92b8, 16, {0x16, 0xaf, 0x4b, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x91, 0x00, 0xef, 0x70, 0x05, 0x12, 0x91, 0xd2} }, -{ 0x92c8, 16, {0x80, 0xef, 0xe5, 0x4c, 0xf4, 0x52, 0x3a, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xbb} }, -{ 0x92d8, 16, {0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x93, 0xa5, 0x74, 0x19, 0xf0, 0x7f, 0x02, 0x12, 0x81} }, -{ 0x92e8, 16, {0x11, 0x8e, 0x4e, 0x8f, 0x4f, 0xc3, 0xe5, 0x4e, 0x64, 0x80, 0x94, 0x80, 0x40, 0xee, 0x90, 0x01} }, -{ 0x92f8, 16, {0xbc, 0xe0, 0x65, 0x4f, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8, 0x07} }, -{ 0x9308, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xbc, 0xe0, 0x55, 0x4c, 0x60} }, -{ 0x9318, 16, {0x14, 0xaf, 0x4b, 0x7d, 0x08, 0xe5, 0x4c, 0x55, 0x4f, 0xfb, 0x12, 0x91, 0x00, 0xef, 0x70, 0x05} }, -{ 0x9328, 16, {0x12, 0x91, 0xd2, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xcc, 0x90, 0x01} }, -{ 0x9338, 16, {0xbc, 0xe5, 0x4f, 0xf0, 0xe4, 0xf5, 0x4b, 0xc2, 0xaf, 0x74, 0x32, 0x25, 0x4b, 0xf8, 0xe6, 0xf5} }, -{ 0x9348, 16, {0x4c, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4c, 0x1e, 0xe5, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x02} }, -{ 0x9358, 16, {0xab, 0x4c, 0x12, 0x91, 0x00, 0xef, 0x70, 0x05, 0x12, 0x91, 0xd2, 0x80, 0xef, 0x74, 0x2c, 0x25} }, -{ 0x9368, 16, {0x4b, 0xf8, 0xe6, 0xf5, 0x4c, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} }, -{ 0x9378, 16, {0xe0, 0x65, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x04, 0xab, 0x4c, 0x12, 0x91, 0x00, 0xef, 0x70} }, -{ 0x9388, 16, {0x05, 0x12, 0x91, 0xd2, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5} }, -{ 0x9398, 16, {0x83, 0xe5, 0x4c, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0x9a, 0x12, 0x91, 0xd2} }, -{ 0x93a8, 1, {0x22} }, -{ 0x93a9, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x64, 0x02, 0x93, 0xf0} }, -{ 0x93b5, 16, {0x02, 0x05, 0xa3, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} }, -{ 0x93c5, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} }, -{ 0x93d5, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} }, -{ 0x93e5, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x94, 0x35, 0xe4, 0x7e} }, -{ 0x93f5, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} }, -{ 0x9405, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} }, -{ 0x9415, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} }, -{ 0x9425, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} }, -{ 0x9435, 16, {0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} }, -{ 0x9445, 16, {0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} }, -{ 0x9455, 8, {0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} }, -{ 0x945d, 1, {0x00} }, -{ 0x945e, 11, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} }, -{ 0x9469, 16, {0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} }, -{ 0x9479, 16, {0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} }, -{ 0x9489, 16, {0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} }, -{ 0x9499, 10, {0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} }, -{ 0x94a3, 9, {0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x94ac, 2, {0xa9, 0x03} }, -{ 0x94ae, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} }, -{ 0x94be, 16, {0x57, 0x45, 0x58, 0xf5, 0x59, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} }, -{ 0x94ce, 16, {0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} }, -{ 0x94de, 16, {0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x59, 0xeb} }, -{ 0x94ee, 16, {0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x59, 0xfc, 0xb5, 0x06, 0x03, 0xaf} }, -{ 0x94fe, 16, {0x05, 0x22, 0xe5, 0x57, 0x5c, 0xfe, 0xe5, 0x58, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} }, -{ 0x950e, 16, {0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} }, -{ 0x951e, 16, {0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x57, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x58, 0x22, 0x7f} }, -{ 0x952e, 1, {0x00} }, -{ 0x952f, 1, {0x22} }, -{ 0x9530, 16, {0x75, 0x50, 0x02, 0x75, 0x51, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x51, 0x82, 0x85} }, -{ 0x9540, 16, {0x50, 0x83, 0xe0, 0xff, 0x90, 0x03, 0x36, 0xf0, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0} }, -{ 0x9550, 16, {0x90, 0x03, 0x37, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0x75, 0x52, 0x03, 0x75, 0x53, 0x39, 0xef, 0x14} }, -{ 0x9560, 16, {0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x99, 0x98, 0x90, 0x95, 0x6f, 0xf8, 0x28, 0x28, 0x73, 0x02} }, -{ 0x9570, 16, {0x95, 0x90, 0x02, 0x96, 0x2f, 0x02, 0x97, 0x34, 0x02, 0x97, 0x54, 0x02, 0x97, 0x54, 0x02, 0x97} }, -{ 0x9580, 16, {0xef, 0x02, 0x98, 0x2a, 0x02, 0x98, 0x4f, 0x02, 0x99, 0x0d, 0x02, 0x99, 0x39, 0x02, 0x99, 0x65} }, -{ 0x9590, 16, {0xe4, 0xf5, 0x4b, 0xe5, 0x4b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20} }, -{ 0x95a0, 16, {0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74, 0x8a, 0x2e} }, -{ 0x95b0, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4c, 0x80, 0x0d, 0x74, 0x8a, 0x2e} }, -{ 0x95c0, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4c, 0xe5, 0x4f, 0x24, 0x07, 0xf5, 0x82} }, -{ 0x95d0, 16, {0xe4, 0x35, 0x4e, 0xf5, 0x83, 0xe5, 0x4c, 0xf0, 0xe0, 0xf5, 0x4d, 0x65, 0x4c, 0x60, 0x38, 0xe4} }, -{ 0x95e0, 16, {0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfd, 0x05, 0x53, 0xe5, 0x53, 0xaa, 0x52, 0x70, 0x02} }, -{ 0x95f0, 16, {0x05, 0x52, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70} }, -{ 0x9600, 16, {0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4c, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, -{ 0x9610, 16, {0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x99, 0x9e, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64, 0x02, 0x70} }, -{ 0x9620, 16, {0x87, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60, 0x03, 0x02, 0x95, 0x93, 0x02, 0x99, 0x9e, 0xe4} }, -{ 0x9630, 16, {0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0x50, 0x05, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x03} }, -{ 0x9640, 16, {0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x94, 0xf0, 0xa3, 0x74, 0x5e, 0xf0, 0xe4, 0xf5, 0x4d, 0x7e} }, -{ 0x9650, 16, {0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} }, -{ 0x9660, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xc4, 0xf0, 0x90, 0x01} }, -{ 0x9670, 16, {0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0x74, 0x02} }, -{ 0x9680, 16, {0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4c, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0} }, -{ 0x9690, 16, {0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52} }, -{ 0x96a0, 16, {0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, -{ 0x96b0, 16, {0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4d, 0xff, 0x90, 0x01, 0xc4, 0xe0} }, -{ 0x96c0, 16, {0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfe, 0x05, 0x53, 0xe5, 0x53} }, -{ 0x96d0, 16, {0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05, 0x53, 0xe5} }, -{ 0x96e0, 16, {0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53} }, -{ 0x96f0, 16, {0x82, 0x85, 0x52, 0x83, 0xe5, 0x4c, 0xf0, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x70, 0x16, 0x74, 0x08} }, -{ 0x9700, 16, {0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35, 0x4e, 0xf5, 0x4e, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60} }, -{ 0x9710, 16, {0x03, 0x02, 0x96, 0x5b, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x7d, 0x01, 0x12, 0x82, 0x50, 0x05, 0x4b} }, -{ 0x9720, 16, {0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3, 0x74, 0x12} }, -{ 0x9730, 16, {0xf0, 0x02, 0x99, 0x9e, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0, 0x14, 0xff, 0x74, 0x01} }, -{ 0x9740, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01, 0xc4} }, -{ 0x9750, 16, {0xf0, 0x02, 0x99, 0x9e, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4, 0xf5} }, -{ 0x9760, 16, {0x4d, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01, 0xc0} }, -{ 0x9770, 16, {0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, -{ 0x9780, 16, {0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4d, 0xe5, 0x4d, 0x60, 0x03, 0x02, 0x99, 0x9e, 0x90, 0x01, 0xc0} }, -{ 0x9790, 16, {0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7f} }, -{ 0x97a0, 16, {0x02, 0x12, 0x81, 0x11, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xef, 0x54, 0x0f, 0xf5} }, -{ 0x97b0, 16, {0x4d, 0x90, 0x02, 0xf7, 0xe0, 0x55, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f} }, -{ 0x97c0, 16, {0x4c, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4c, 0x70, 0x04, 0x7f} }, -{ 0x97d0, 16, {0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4c, 0xe5, 0x4c, 0x70, 0x03, 0x02, 0x99, 0x9e, 0xe4, 0x90} }, -{ 0x97e0, 16, {0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x99, 0x9e, 0xe4} }, -{ 0x97f0, 16, {0xff, 0xfd, 0x12, 0x82, 0x50, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0x85} }, -{ 0x9800, 16, {0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x4f, 0x82, 0x85} }, -{ 0x9810, 16, {0x4e, 0x83, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3} }, -{ 0x9820, 16, {0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xd2, 0x04, 0x02, 0x99, 0x9e, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00} }, -{ 0x9830, 16, {0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xe5, 0x4f, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x4e, 0xf5} }, -{ 0x9840, 16, {0x83, 0xe0, 0x30, 0xe6, 0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0x50, 0x02, 0x99, 0x9e, 0xe4} }, -{ 0x9850, 16, {0xf5, 0x4d, 0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0x50, 0xe5, 0x4b, 0x75, 0xf0, 0x08} }, -{ 0x9860, 16, {0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xf5, 0x83} }, -{ 0x9870, 16, {0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf} }, -{ 0x9880, 16, {0x4b, 0x7d, 0x01, 0x7b, 0x01, 0x75, 0x57, 0x80, 0x75, 0x58, 0x40, 0x12, 0x94, 0xac, 0x8f, 0x4d} }, -{ 0x9890, 16, {0xe5, 0x4d, 0x70, 0x11, 0xaf, 0x4b, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20} }, -{ 0x98a0, 16, {0x12, 0x94, 0xac, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d, 0x01, 0xfb, 0x75, 0x57} }, -{ 0x98b0, 16, {0x80, 0x75, 0x58, 0x40, 0x12, 0x94, 0xac, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d} }, -{ 0x98c0, 16, {0x02, 0xfb, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20, 0x12, 0x94, 0xac, 0x8f, 0x4d, 0xaf, 0x4b, 0x7d} }, -{ 0x98d0, 16, {0x01, 0x12, 0x82, 0x50, 0xe5, 0x4d, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04} }, -{ 0x98e0, 16, {0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83} }, -{ 0x98f0, 16, {0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x99, 0x9e, 0x05, 0x4b} }, -{ 0x9900, 16, {0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x50, 0x03, 0x02, 0x98, 0x54, 0x02, 0x99, 0x9e, 0xe4, 0x90, 0x03} }, -{ 0x9910, 16, {0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74} }, -{ 0x9920, 16, {0x1b, 0xf0, 0xa3, 0x74, 0x29, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x80, 0x00, 0xef, 0x64, 0x08} }, -{ 0x9930, 16, {0x60, 0x6c, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x65, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} }, -{ 0x9940, 16, {0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5, 0x52, 0xf0, 0xa3, 0xe5} }, -{ 0x9950, 16, {0x53, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x40, 0xe4, 0x90} }, -{ 0x9960, 16, {0x03, 0x38, 0xf0, 0x80, 0x39, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0} }, -{ 0x9970, 16, {0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5, 0x51, 0x24, 0x02, 0x90, 0x03, 0x60, 0xf0, 0xe4, 0x35} }, -{ 0x9980, 16, {0x50, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x80, 0x00, 0xef, 0x64, 0x08, 0x60} }, -{ 0x9990, 16, {0x0d, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01} }, -{ 0x99a0, 16, {0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70} }, -{ 0x99b0, 16, {0xf6, 0x7e, 0x03, 0x7f, 0x35, 0x75, 0x60, 0x00, 0x75, 0x5f, 0x00, 0x75, 0x5e, 0x00, 0x75, 0x5d} }, -{ 0x99c0, 11, {0x00, 0x7d, 0x24, 0x12, 0x8e, 0x0c, 0xe4, 0x90, 0x02, 0xaf, 0xf0} }, -{ 0x99cb, 1, {0x22} }, -{ 0x99cc, 16, {0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} }, -{ 0x99dc, 16, {0x9a, 0x6f, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9a, 0x6f, 0xef, 0x75, 0xf0} }, -{ 0x99ec, 16, {0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} }, -{ 0x99fc, 16, {0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} }, -{ 0x9a0c, 16, {0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} }, -{ 0x9a1c, 16, {0x12, 0x9b, 0xce, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} }, -{ 0x9a2c, 16, {0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} }, -{ 0x9a3c, 16, {0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} }, -{ 0x9a4c, 16, {0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} }, -{ 0x9a5c, 16, {0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} }, -{ 0x9a6c, 12, {0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x99, 0xce} }, -{ 0x9a78, 1, {0x22} }, -{ 0x9a79, 16, {0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} }, -{ 0x9a89, 16, {0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} }, -{ 0x9a99, 16, {0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} }, -{ 0x9aa9, 16, {0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} }, -{ 0x9ab9, 16, {0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} }, -{ 0x9ac9, 16, {0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} }, -{ 0x9ad9, 16, {0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} }, -{ 0x9ae9, 16, {0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} }, -{ 0x9af9, 16, {0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} }, -{ 0x9b09, 16, {0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} }, -{ 0x9b19, 16, {0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} }, -{ 0x9b29, 16, {0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} }, -{ 0x9b39, 16, {0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} }, -{ 0x9b49, 16, {0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} }, -{ 0x9b59, 16, {0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} }, -{ 0x9b69, 9, {0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9a, 0xc9, 0x73} }, -{ 0x9b72, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} }, -{ 0x9b82, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} }, -{ 0x9b8b, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} }, -{ 0x9b9b, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} }, -{ 0x9bab, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} }, -{ 0x9bb8, 16, {0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} }, -{ 0x9bc8, 6, {0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} }, -{ 0x9bce, 16, {0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} }, -{ 0x9bde, 6, {0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} }, -{ 0x9be4, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} }, -{ 0x9bf4, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} }, -{ 0x9c04, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} }, -{ 0x9c14, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} }, -{ 0x9c1c, 16, {0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} }, -{ 0x9c2c, 16, {0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} }, -{ 0x9c3c, 16, {0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} }, -{ 0x9c4c, 16, {0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} }, -{ 0x9c5c, 16, {0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} }, -{ 0x9c6c, 16, {0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} }, -{ 0x9c7c, 16, {0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} }, -{ 0x9c8c, 16, {0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} }, -{ 0x9c9c, 16, {0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} }, -{ 0x9cac, 16, {0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} }, -{ 0x9cbc, 16, {0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} }, -{ 0x9ccc, 16, {0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} }, -{ 0x9cdc, 14, {0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} }, -{ 0x9cea, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} }, -{ 0x9cfa, 1, {0x22} }, -{ 0x9cfb, 16, {0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} }, -{ 0x9d0b, 3, {0xd8, 0xf1, 0x22} }, -{ 0x9d0e, 16, {0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} }, -{ 0x9d1e, 7, {0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} }, -{ 0x9d25, 12, {0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, -{ 0x9d31, 16, {0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0x9d, 0x48, 0x12, 0x9d, 0x48, 0x12} }, -{ 0x9d41, 16, {0x9d, 0x48, 0x12, 0x9d, 0x48, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} }, -{ 0x9d51, 16, {0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} }, -{ 0x9d61, 1, {0x22} }, +{ 0x19c1, 4, {0x8e, 0x54, 0x8f, 0x55} }, +{ 0x19c5, 16, {0x75, 0x56, 0x03, 0xe5, 0x55, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe} }, +{ 0x19d5, 16, {0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x1a, 0xcf, 0xe5, 0x56, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} }, +{ 0x19e5, 16, {0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x1a, 0x73, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} }, +{ 0x19f5, 16, {0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} }, +{ 0x1a05, 16, {0x80, 0x6c, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} }, +{ 0x1a15, 16, {0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x56, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} }, +{ 0x1a25, 16, {0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x55, 0x24, 0x06, 0xf5, 0x82} }, +{ 0x1a35, 16, {0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5} }, +{ 0x1a45, 16, {0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x55, 0x24} }, +{ 0x1a55, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0x9f, 0x8e, 0x85} }, +{ 0x1a65, 16, {0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0x8e, 0x90, 0x7f} }, +{ 0x1a75, 16, {0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} }, +{ 0x1a85, 16, {0x22, 0xe5, 0x57, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} }, +{ 0x1a95, 16, {0xe5, 0x56, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x1aa5, 16, {0x80, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} }, +{ 0x1ab5, 16, {0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} }, +{ 0x1ac5, 12, {0x56, 0x03, 0x02, 0x19, 0xc8, 0x15, 0x56, 0x02, 0x19, 0xc8, 0x7f, 0x08} }, +{ 0x1ad1, 1, {0x22} }, +{ 0x1ad2, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} }, +{ 0x1ae2, 15, {0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x1af1, 4, {0x8e, 0x54, 0x8f, 0x55} }, +{ 0x1af5, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x56, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x1b05, 16, {0xe5, 0x56, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} }, +{ 0x1b15, 16, {0x54, 0x03, 0x70, 0x24, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} }, +{ 0x1b25, 16, {0x56, 0x7d, 0x02, 0x12, 0x83, 0x2d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe1} }, +{ 0x1b35, 10, {0x07, 0xaf, 0x56, 0x7d, 0x04, 0x12, 0x83, 0x2d, 0x7f, 0x00} }, +{ 0x1b3f, 1, {0x22} }, +{ 0x8000, 16, {0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0xfd, 0x8b, 0x4d, 0x75} }, +{ 0x8010, 16, {0x4e, 0x12, 0x75, 0x4f, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4b} }, +{ 0x8020, 16, {0xf5, 0x4c, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} }, +{ 0x8030, 16, {0xa9, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0xe4, 0xfc, 0xec, 0x25, 0xe0, 0x24, 0xb4, 0xf5} }, +{ 0x8040, 16, {0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x0c, 0xbc, 0x10, 0xee, 0xe4, 0x90, 0x7f, 0xdd} }, +{ 0x8050, 16, {0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4d, 0xaa, 0x4e, 0xa9, 0x4f} }, +{ 0x8060, 16, {0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} }, +{ 0x8070, 16, {0x12, 0x9f, 0x61, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61} }, +{ 0x8080, 16, {0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x81, 0x16, 0xec, 0xc3, 0x94, 0x10} }, +{ 0x8090, 16, {0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4c, 0xae, 0x4b, 0x78, 0x02, 0xce} }, +{ 0x80a0, 16, {0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xf0, 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} }, +{ 0x80b0, 16, {0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe0, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01, 0xa8, 0x06} }, +{ 0x80c0, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe0, 0xf0, 0x90, 0x02, 0xae, 0xe0} }, +{ 0x80d0, 16, {0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4c, 0xae, 0x4b, 0x78} }, +{ 0x80e0, 16, {0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xe8, 0x2c, 0xf5, 0x82, 0xe4, 0x34} }, +{ 0x80f0, 16, {0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe1, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01} }, +{ 0x8100, 16, {0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x02} }, +{ 0x8110, 16, {0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0x25} }, +{ 0x8120, 16, {0x4c, 0xf5, 0x4c, 0xe4, 0x35, 0x4b, 0xf5, 0x4b, 0x90, 0x00, 0x05, 0x12, 0x9f, 0x61, 0xfe, 0xe4} }, +{ 0x8130, 16, {0x25, 0x4c, 0xf5, 0x4c, 0xee, 0x35, 0x4b, 0xf5, 0x4b, 0x02, 0x81, 0xb8, 0xab, 0x4d, 0xaa, 0x4e} }, +{ 0x8140, 16, {0xa9, 0x4f, 0x90, 0x00, 0x03, 0x12, 0x9f, 0x61, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} }, +{ 0x8150, 16, {0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} }, +{ 0x8160, 16, {0x4e, 0xef, 0x30, 0xe7, 0x1e, 0x90, 0x7f, 0xde, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80} }, +{ 0x8170, 16, {0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x4e} }, +{ 0x8180, 16, {0xf0, 0x80, 0x35, 0x90, 0x7f, 0xdf, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80, 0x02, 0xc3} }, +{ 0x8190, 16, {0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xad, 0xe0, 0x4e, 0xf0, 0xec} }, +{ 0x81a0, 16, {0x25, 0xe0, 0x24, 0xc5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x09, 0x7f} }, +{ 0x81b0, 16, {0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35} }, +{ 0x81c0, 16, {0x4e, 0xf5, 0x4e, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} }, +{ 0x81d0, 8, {0x7f, 0xae, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x00} }, +{ 0x81d8, 1, {0x22} }, +{ 0x81d9, 2, {0xac, 0x07} }, +{ 0x81db, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xec, 0x25, 0xe0, 0x44, 0x41, 0x90, 0x7f, 0xa6, 0xf0} }, +{ 0x81eb, 16, {0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90} }, +{ 0x81fb, 16, {0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0xd4, 0x80, 0xf8, 0x90, 0x7f} }, +{ 0x820b, 16, {0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xdc, 0x20, 0xe1, 0x09, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} }, +{ 0x821b, 16, {0xf9, 0x22, 0xed, 0x30, 0xe2, 0x0c, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} }, +{ 0x822b, 16, {0xfa, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7b, 0x1e} }, +{ 0x823b, 16, {0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6} }, +{ 0x824b, 16, {0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0x86, 0x80, 0xf8, 0x90, 0x7f, 0xa5, 0xe0} }, +{ 0x825b, 16, {0xfd, 0x20, 0xe0, 0xdc, 0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x19, 0x90, 0x7f, 0xa5, 0xe0} }, +{ 0x826b, 16, {0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03} }, +{ 0x827b, 16, {0x02, 0x81, 0xdb, 0x80, 0xf5, 0x90, 0x7f, 0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xd9, 0x30, 0xe2, 0x09} }, +{ 0x828b, 16, {0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, +{ 0x829b, 12, {0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} }, +{ 0x82a7, 1, {0x22} }, +{ 0x82a8, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} }, +{ 0x82b8, 16, {0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5e, 0x74, 0xbf} }, +{ 0x82c8, 16, {0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, +{ 0x82d8, 16, {0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} }, +{ 0x82e8, 16, {0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} }, +{ 0x82f8, 16, {0xef, 0x55, 0x3b, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, +{ 0x8308, 16, {0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} }, +{ 0x8318, 16, {0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5e, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} }, +{ 0x8328, 4, {0x83, 0xa3, 0xe9, 0xf0} }, +{ 0x832c, 1, {0x22} }, +{ 0x832d, 4, {0x8f, 0x5e, 0x8d, 0x5f} }, +{ 0x8331, 16, {0xe4, 0xf5, 0x60, 0x74, 0x3c, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24} }, +{ 0x8341, 16, {0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, +{ 0x8351, 16, {0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x50} }, +{ 0x8361, 16, {0x3c, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} }, +{ 0x8371, 16, {0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} }, +{ 0x8381, 16, {0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x40, 0x0c, 0x75, 0x60, 0x40, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76} }, +{ 0x8391, 16, {0x10, 0x80, 0x0a, 0x75, 0x60, 0x80, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76, 0x38, 0xe5, 0x60, 0x45} }, +{ 0x83a1, 16, {0x5f, 0x44, 0x01, 0xff, 0xe5, 0x5e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} }, +{ 0x83b1, 5, {0x20, 0xf5, 0x83, 0xef, 0xf0} }, +{ 0x83b6, 1, {0x22} }, +{ 0x83b7, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x83c7, 16, {0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} }, +{ 0x83d7, 16, {0x55, 0x8f, 0x56, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} }, +{ 0x83e7, 16, {0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} }, +{ 0x83f7, 16, {0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x54, 0xf8, 0xe4, 0xf6, 0xe5, 0x56, 0x24, 0x04, 0xf5, 0x82} }, +{ 0x8407, 16, {0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d} }, +{ 0x8417, 16, {0xaf, 0x54, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xe0} }, +{ 0x8427, 16, {0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83} }, +{ 0x8437, 16, {0xe0, 0xe5, 0x56, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x54} }, +{ 0x8447, 16, {0x7d, 0x06, 0x12, 0x83, 0x2d, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} }, +{ 0x8457, 16, {0xe4, 0xf0, 0xe5, 0x54, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} }, +{ 0x8467, 16, {0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xef} }, +{ 0x8477, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x54, 0x74, 0x01} }, +{ 0x8487, 13, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7f, 0x00} }, +{ 0x8494, 1, {0x22} }, +{ 0x8495, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x84a5, 16, {0xaf, 0x54, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02} }, +{ 0x84b5, 16, {0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} }, +{ 0x84c5, 16, {0x20, 0xaf, 0x82, 0xf5, 0x56, 0x8f, 0x57, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} }, +{ 0x84d5, 16, {0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0xe5} }, +{ 0x84e5, 16, {0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x57} }, +{ 0x84f5, 16, {0x82, 0x85, 0x56, 0x83, 0xe0, 0xf5, 0x55, 0xaf, 0x54, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} }, +{ 0x8505, 16, {0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x30, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} }, +{ 0x8515, 16, {0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} }, +{ 0x8525, 9, {0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} }, +{ 0x852e, 1, {0x22} }, +{ 0x852f, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} }, +{ 0x853f, 16, {0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} }, +{ 0x854f, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} }, +{ 0x855f, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} }, +{ 0x856f, 16, {0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} }, +{ 0x857f, 16, {0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} }, +{ 0x858f, 16, {0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} }, +{ 0x859f, 16, {0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} }, +{ 0x85af, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} }, +{ 0x85bf, 3, {0x83, 0xf0, 0x22} }, +{ 0x85c2, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x85c6, 16, {0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} }, +{ 0x85d6, 16, {0x22, 0x8c, 0x54, 0x8d, 0x55, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} }, +{ 0x85e6, 16, {0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} }, +{ 0x85f6, 16, {0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x55, 0xe5, 0x55, 0xaa, 0x54, 0x70, 0x02} }, +{ 0x8606, 16, {0x05, 0x54, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, +{ 0x8616, 1, {0x22} }, +{ 0x8617, 4, {0x8e, 0x54, 0x8f, 0x55} }, +{ 0x861b, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5b, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x862b, 16, {0xe5, 0x5b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} }, +{ 0x863b, 16, {0x5c, 0x8f, 0x5d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} }, +{ 0x864b, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa0} }, +{ 0x865b, 16, {0xc0, 0x40, 0x10, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x00} }, +{ 0x866b, 16, {0x08, 0x80, 0x2e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} }, +{ 0x867b, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa0} }, +{ 0x868b, 16, {0xc0, 0x50, 0x0e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x07, 0x08} }, +{ 0x869b, 16, {0x00, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} }, +{ 0x86ab, 16, {0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59} }, +{ 0x86bb, 16, {0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0} }, +{ 0x86cb, 16, {0x2e, 0xaf, 0x03, 0x8f, 0x5a, 0xaf, 0x59, 0xae, 0x58, 0xad, 0x57, 0xac, 0x56, 0x7b, 0x0a, 0x7a} }, +{ 0x86db, 16, {0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59, 0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56} }, +{ 0x86eb, 16, {0xe5, 0x5a, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x59, 0x24, 0x01, 0xf5, 0x59, 0xe4, 0x35, 0x58} }, +{ 0x86fb, 16, {0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0xe4, 0x35, 0x56, 0xf5, 0x56, 0x85, 0x5d, 0x82, 0x85} }, +{ 0x870b, 16, {0x5c, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} }, +{ 0x871b, 16, {0x80, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xe5, 0x59, 0xf0, 0xaf, 0x59, 0xae, 0x58, 0xad} }, +{ 0x872b, 16, {0x57, 0xac, 0x56, 0x78, 0x08, 0x12, 0xa0, 0xd1, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xef} }, +{ 0x873b, 16, {0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} }, +{ 0x874b, 16, {0x5a, 0xe5, 0x55, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} }, +{ 0x875b, 16, {0x05, 0x43, 0x5a, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5a, 0x08, 0x80, 0x11, 0xef} }, +{ 0x876b, 16, {0xb4, 0x74, 0x05, 0x43, 0x5a, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} }, +{ 0x877b, 16, {0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} }, +{ 0x878b, 16, {0x43, 0x5a, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5a, 0x40, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82} }, +{ 0x879b, 16, {0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4} }, +{ 0x87ab, 16, {0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5b, 0x74, 0x01} }, +{ 0x87bb, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0xe5, 0x5d, 0x24, 0x04, 0xf5} }, +{ 0x87cb, 16, {0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5a, 0x80, 0x10, 0xaf} }, +{ 0x87db, 16, {0x5b, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3b, 0x85} }, +{ 0x87eb, 16, {0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} }, +{ 0x87fb, 16, {0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5a, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x880b, 16, {0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83} }, +{ 0x881b, 16, {0xef, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5} }, +{ 0x882b, 16, {0x5d, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09} }, +{ 0x883b, 16, {0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x06, 0xf5, 0x82, 0xe4} }, +{ 0x884b, 16, {0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5} }, +{ 0x885b, 16, {0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0} }, +{ 0x886b, 16, {0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} }, +{ 0x887b, 16, {0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5b, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0x75, 0x5a, 0x08, 0xe5, 0x55} }, +{ 0x888b, 16, {0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5a, 0x10, 0xe5} }, +{ 0x889b, 16, {0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5a, 0xf0} }, +{ 0x88ab, 16, {0xe5, 0x55, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} }, +{ 0x88bb, 16, {0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x55, 0x24, 0x06, 0xf5} }, +{ 0x88cb, 16, {0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} }, +{ 0x88db, 16, {0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} }, +{ 0x88eb, 16, {0xfb, 0x4f, 0xf5, 0x5a, 0xe5, 0x55, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0} }, +{ 0x88fb, 16, {0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} }, +{ 0x890b, 16, {0x70, 0x14, 0x43, 0x5a, 0x18, 0x80, 0x12, 0x43, 0x5a, 0x08, 0x80, 0x0d, 0x43, 0x5a, 0x38, 0x80} }, +{ 0x891b, 16, {0x08, 0x43, 0x5a, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3} }, +{ 0x892b, 16, {0xa3, 0xa3, 0xe5, 0x5a, 0xf0, 0xaf, 0x5b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0xaa, 0x54, 0xa9, 0x55} }, +{ 0x893b, 16, {0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5b, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} }, +{ 0x894b, 15, {0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f, 0x1f, 0x7f, 0x00} }, +{ 0x895a, 1, {0x22} }, +{ 0x895b, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x896b, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} }, +{ 0x897b, 16, {0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} }, +{ 0x898b, 16, {0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} }, +{ 0x899b, 16, {0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x89ab, 16, {0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} }, +{ 0x89bb, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x54, 0x7f, 0x02, 0x12, 0x81, 0xd9} }, +{ 0x89cb, 16, {0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xe5, 0x54, 0x5f, 0x90, 0x01, 0x32, 0xf0, 0x7e} }, +{ 0x89db, 10, {0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12, 0x8e, 0xb4, 0x7f, 0x00} }, +{ 0x89e5, 1, {0x22} }, +{ 0x89e6, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x89f6, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} }, +{ 0x8a06, 16, {0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} }, +{ 0x8a16, 16, {0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8e} }, +{ 0x8a26, 3, {0xb4, 0x7f, 0x00} }, +{ 0x8a29, 1, {0x22} }, +{ 0x8a2a, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x8a2e, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x8a3e, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, +{ 0x8a4e, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} }, +{ 0x8a5e, 16, {0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x8a6e, 4, {0xfd, 0xf0, 0x7f, 0x00} }, +{ 0x8a72, 1, {0x22} }, +{ 0x8a73, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x8a77, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x8a87, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, +{ 0x8a97, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} }, +{ 0x8aa7, 16, {0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} }, +{ 0x8ab7, 4, {0xfe, 0xf0, 0x7f, 0x00} }, +{ 0x8abb, 1, {0x22} }, +{ 0x8abc, 4, {0xad, 0x07, 0xac, 0x06} }, +{ 0x8ac0, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, +{ 0x8ad0, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, +{ 0x8ae0, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} }, +{ 0x8af0, 16, {0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} }, +{ 0x8b00, 1, {0x22} }, +{ 0x8b01, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} }, +{ 0x8b11, 16, {0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3a, 0x7f, 0x00} }, +{ 0x8b21, 1, {0x22} }, +{ 0x8b22, 4, {0x8e, 0x54, 0x8f, 0x55} }, +{ 0x8b26, 16, {0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x59, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x56, 0xc3} }, +{ 0x8b36, 16, {0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} }, +{ 0x8b46, 16, {0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x57, 0x7e, 0x75, 0x58} }, +{ 0x8b56, 16, {0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x57, 0x7e, 0x75, 0x58, 0x00, 0x80, 0x16, 0x7e} }, +{ 0x8b66, 16, {0x7d, 0x7f, 0x80, 0x75, 0x57, 0x7d, 0x75, 0x58, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} }, +{ 0x8b76, 16, {0x57, 0x7d, 0x75, 0x58, 0x00, 0xe5, 0x59, 0x70, 0x1b, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0x74} }, +{ 0x8b86, 16, {0xff, 0xf0, 0xe5, 0x56, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} }, +{ 0x8b96, 16, {0x01, 0xf0, 0x80, 0x48, 0xe5, 0x55, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x54, 0xfe, 0xe5, 0x59, 0x60} }, +{ 0x8ba6, 16, {0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} }, +{ 0x8bb6, 16, {0x58, 0xe5, 0x58, 0xaa, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} }, +{ 0x8bc6, 16, {0x15, 0x59, 0x80, 0xd9, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x56, 0x25} }, +{ 0x8bd6, 14, {0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} }, +{ 0x8be4, 1, {0x22} }, +{ 0x8be5, 16, {0xef, 0x24, 0x05, 0xf5, 0x55, 0xe4, 0x3e, 0xf5, 0x54, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} }, +{ 0x8bf5, 16, {0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} }, +{ 0x8c05, 16, {0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x56, 0xf5, 0x57, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, +{ 0x8c15, 16, {0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8c, 0xc6} }, +{ 0x8c25, 16, {0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0x12, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe} }, +{ 0x8c35, 16, {0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x59, 0x74, 0x01, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59} }, +{ 0x8c45, 16, {0x94, 0x40, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5} }, +{ 0x8c55, 16, {0x57, 0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x50, 0x03, 0x02, 0x8d, 0x15, 0xae, 0x58, 0xaf, 0x59} }, +{ 0x8c65, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} }, +{ 0x8c75, 16, {0x56, 0xf5, 0x57, 0x02, 0x8d, 0x15, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} }, +{ 0x8c85, 16, {0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59, 0x94} }, +{ 0x8c95, 16, {0x10, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x10, 0xd3, 0xe5, 0x57} }, +{ 0x8ca5, 16, {0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x40, 0x68, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85} }, +{ 0x8cb5, 16, {0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x80} }, +{ 0x8cc5, 16, {0x4f, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} }, +{ 0x8cd5, 16, {0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0x45, 0x59, 0x60, 0x0b, 0xd3, 0xe5, 0x59, 0x94, 0x40, 0xe5} }, +{ 0x8ce5, 16, {0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5, 0x57, 0x95, 0x59} }, +{ 0x8cf5, 16, {0xe5, 0x56, 0x95, 0x58, 0x40, 0x17, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, +{ 0x8d05, 16, {0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x7f, 0x01, 0x22} }, +{ 0x8d15, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8d, 0xd5, 0x24, 0xf9} }, +{ 0x8d25, 16, {0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0x25, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8e, 0x69} }, +{ 0x8d35, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} }, +{ 0x8d45, 16, {0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57} }, +{ 0x8d55, 16, {0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xe0} }, +{ 0x8d65, 16, {0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f} }, +{ 0x8d75, 16, {0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} }, +{ 0x8d85, 16, {0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8e} }, +{ 0x8d95, 16, {0x69, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x76} }, +{ 0x8da5, 16, {0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02} }, +{ 0x8db5, 16, {0x8e, 0x69, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} }, +{ 0x8dc5, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} }, +{ 0x8dd5, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} }, +{ 0x8de5, 16, {0x94, 0x00, 0x50, 0x03, 0x02, 0x8e, 0x69, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} }, +{ 0x8df5, 16, {0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e} }, +{ 0x8e05, 16, {0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} }, +{ 0x8e15, 16, {0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} }, +{ 0x8e25, 16, {0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} }, +{ 0x8e35, 16, {0xa3, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x60, 0x24} }, +{ 0x8e45, 16, {0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} }, +{ 0x8e55, 16, {0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, +{ 0x8e65, 16, {0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3} }, +{ 0x8e75, 11, {0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8e, 0xb4, 0x7f, 0x00} }, +{ 0x8e80, 1, {0x22} }, +{ 0x8e81, 16, {0x8e, 0x5f, 0x8f, 0x60, 0x8c, 0x61, 0x8d, 0x62, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x60} }, +{ 0x8e91, 16, {0xe5, 0x60, 0xae, 0x5f, 0x70, 0x02, 0x05, 0x5f, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} }, +{ 0x8ea1, 16, {0x62, 0xe5, 0x62, 0xac, 0x61, 0x70, 0x02, 0x05, 0x61, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, +{ 0x8eb1, 3, {0x80, 0xd6, 0x22} }, +{ 0x8eb4, 6, {0x8d, 0x5a, 0xab, 0x07, 0xaa, 0x06} }, +{ 0x8eba, 16, {0x75, 0x5e, 0x40, 0x75, 0x5d, 0x0d, 0x75, 0x5c, 0x03, 0x75, 0x5b, 0x00, 0x90, 0x7f, 0xc2, 0xe0} }, +{ 0x8eca, 16, {0x20, 0xe1, 0xf9, 0xaf, 0x5e, 0xae, 0x5d, 0xad, 0x5c, 0xac, 0x5b, 0xec, 0x4d, 0x4e, 0x4f, 0x70} }, +{ 0x8eda, 16, {0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} }, +{ 0x8eea, 16, {0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5a, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xc3} }, +{ 0x8efa, 8, {0xe5, 0x5a, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, +{ 0x8f02, 1, {0x22} }, +{ 0x8f03, 16, {0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0x90, 0x20, 0x70, 0xe0, 0x54, 0xf0, 0xff, 0xc4, 0x54, 0x0f} }, +{ 0x8f13, 16, {0x90, 0x01, 0x85, 0xf0, 0x90, 0x95, 0xbf, 0xe4, 0x93, 0x90, 0x01, 0x86, 0xf0, 0x90, 0x95, 0xc0} }, +{ 0x8f23, 16, {0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} }, +{ 0x8f33, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e} }, +{ 0x8f43, 16, {0x01, 0x7f, 0x7c, 0x12, 0x10, 0x2c, 0x7e, 0x01, 0x7f, 0x84, 0x7d, 0x14, 0x12, 0x8e, 0xb4, 0x7f} }, +{ 0x8f53, 1, {0x00} }, +{ 0x8f54, 1, {0x22} }, +{ 0x8f55, 16, {0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4b, 0x7b, 0x75, 0x4c, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} }, +{ 0x8f65, 16, {0x4b, 0x4e, 0x85, 0x4c, 0x4f, 0xe5, 0x4f, 0x24, 0x01, 0xf5, 0x53, 0xe4, 0x35, 0x4e, 0xf5, 0x52} }, +{ 0x8f75, 16, {0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} }, +{ 0x8f85, 16, {0x5b, 0x90, 0x8f, 0x8d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xb1, 0x02, 0x8f} }, +{ 0x8f95, 16, {0xbb, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xd9, 0x02, 0x8f, 0xb1} }, +{ 0x8fa5, 16, {0x02, 0x8f, 0xcf, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xe1, 0x02, 0x8f, 0xb1, 0xef, 0x64, 0x02, 0x60} }, +{ 0x8fb5, 16, {0x2b, 0x75, 0x4d, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4d, 0xff, 0x80, 0x1c} }, +{ 0x8fc5, 16, {0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4d, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} }, +{ 0x8fd5, 16, {0x4d, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x60, 0x15} }, +{ 0x8fe5, 16, {0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} }, +{ 0x8ff5, 16, {0x8e, 0xb4, 0xaf, 0x4d, 0x22, 0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0x14} }, +{ 0x9005, 16, {0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0x23, 0x90, 0x90, 0x14, 0xf8, 0x28, 0x28, 0x73, 0x02} }, +{ 0x9015, 16, {0x90, 0x41, 0x02, 0x90, 0x4d, 0x02, 0x90, 0x59, 0x02, 0x90, 0xa7, 0x02, 0x90, 0xb2, 0x02, 0x90} }, +{ 0x9025, 16, {0xbd, 0x02, 0x90, 0xc8, 0x02, 0x90, 0xd3, 0x02, 0x90, 0xde, 0x02, 0x90, 0xe9, 0x02, 0x90, 0xf4} }, +{ 0x9035, 16, {0x02, 0x90, 0xfb, 0x02, 0x91, 0x23, 0x02, 0x91, 0x06, 0x02, 0x91, 0x11, 0xaf, 0x53, 0xae, 0x52} }, +{ 0x9045, 16, {0x12, 0x83, 0xb7, 0x8f, 0x4d, 0x02, 0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x84, 0x95, 0x8f} }, +{ 0x9055, 16, {0x4d, 0x02, 0x91, 0x26, 0x85, 0x52, 0x50, 0x85, 0x53, 0x51, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4} }, +{ 0x9065, 16, {0x35, 0x50, 0xfe, 0x12, 0x85, 0x2f, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x85, 0xc2, 0x8f, 0x4d, 0xef} }, +{ 0x9075, 16, {0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0x26, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x86, 0x17, 0x8f, 0x4d} }, +{ 0x9085, 16, {0xe5, 0x4d, 0x70, 0x03, 0x02, 0x91, 0x26, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0x75, 0xf0} }, +{ 0x9095, 16, {0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0x17, 0x02} }, +{ 0x90a5, 16, {0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0x2a, 0x8f, 0x4d, 0x80, 0x74, 0xaf, 0x53, 0xae} }, +{ 0x90b5, 16, {0x52, 0x12, 0x8a, 0x73, 0x8f, 0x4d, 0x80, 0x69, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0xbc, 0x8f} }, +{ 0x90c5, 16, {0x4d, 0x80, 0x5e, 0xaf, 0x4c, 0xae, 0x4b, 0x12, 0x8b, 0xe5, 0x8f, 0x4d, 0x80, 0x53, 0xaf, 0x53} }, +{ 0x90d5, 16, {0xae, 0x52, 0x12, 0x89, 0x5b, 0x8f, 0x4d, 0x80, 0x48, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x1a, 0xf1} }, +{ 0x90e5, 16, {0x8f, 0x4d, 0x80, 0x3d, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x89, 0xe6, 0x8f, 0x4d, 0x80, 0x32, 0x12} }, +{ 0x90f5, 16, {0x8f, 0x03, 0x8f, 0x4d, 0x80, 0x2b, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x01, 0x8f, 0x4d, 0x80} }, +{ 0x9105, 16, {0x20, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x22, 0x8f, 0x4d, 0x80, 0x15, 0xaf, 0x4c, 0xae, 0x4b} }, +{ 0x9115, 16, {0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8e, 0x81, 0xe4, 0xf5, 0x4d, 0x80, 0x03, 0x75, 0x4d} }, +{ 0x9125, 16, {0xff, 0xe5, 0x4d, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e} }, +{ 0x9135, 16, {0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8e, 0xb4, 0xaf} }, +{ 0x9145, 16, {0x4d, 0x22, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} }, +{ 0x9155, 16, {0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85} }, +{ 0x9165, 16, {0x52, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8e, 0xb4} }, +{ 0x9175, 4, {0x8f, 0x4d, 0xaf, 0x4d} }, +{ 0x9179, 1, {0x22} }, +{ 0x917a, 8, {0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b} }, +{ 0x9182, 16, {0x75, 0x55, 0x01, 0x75, 0x56, 0x9c, 0xe4, 0xf5, 0x54, 0xaf, 0x50, 0x15, 0x50, 0xef, 0x70, 0x03} }, +{ 0x9192, 16, {0x02, 0x92, 0x18, 0xaf, 0x4f, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4e} }, +{ 0x91a2, 16, {0xae, 0x4d, 0xad, 0x4c, 0xac, 0x4b, 0x12, 0xa0, 0x2e, 0xaf, 0x03, 0x8f, 0x53, 0xaf, 0x4e, 0xae} }, +{ 0x91b2, 16, {0x4d, 0xad, 0x4c, 0xac, 0x4b, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x4f, 0xe4} }, +{ 0x91c2, 16, {0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} }, +{ 0x91d2, 16, {0x12, 0xa0, 0x2e, 0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b, 0xe5, 0x53, 0x24, 0x30, 0xf5} }, +{ 0x91e2, 16, {0x53, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x53, 0xf5, 0x53, 0x05, 0x56, 0xe5, 0x56} }, +{ 0x91f2, 16, {0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x56, 0xe5} }, +{ 0x9202, 16, {0x56, 0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x53, 0xf0, 0x05} }, +{ 0x9212, 16, {0x54, 0x05, 0x54, 0x02, 0x91, 0x8b, 0xe5, 0x56, 0x15, 0x56, 0x70, 0x02, 0x15, 0x55, 0xaf, 0x54} }, +{ 0x9222, 16, {0x15, 0x54, 0xef, 0x60, 0x23, 0xe5, 0x56, 0x15, 0x56, 0xae, 0x55, 0x70, 0x02, 0x15, 0x55, 0xf5} }, +{ 0x9232, 16, {0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x52, 0xe5, 0x52, 0xac, 0x51, 0x70, 0x02, 0x05, 0x51, 0x14} }, +{ 0x9242, 8, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} }, +{ 0x924a, 1, {0x22} }, +{ 0x924b, 16, {0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} }, +{ 0x925b, 16, {0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} }, +{ 0x926b, 16, {0xe4, 0xef, 0x55, 0x30, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} }, +{ 0x927b, 16, {0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, +{ 0x928b, 16, {0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} }, +{ 0x929b, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, +{ 0x92ab, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, +{ 0x92bb, 1, {0x22} }, +{ 0x92bc, 16, {0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} }, +{ 0x92cc, 16, {0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} }, +{ 0x92dc, 16, {0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} }, +{ 0x92ec, 16, {0x9f, 0x1f, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} }, +{ 0x92fc, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, +{ 0x930c, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, +{ 0x931c, 1, {0x22} }, +{ 0x931d, 16, {0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x50, 0x7b, 0x75, 0x51} }, +{ 0x932d, 16, {0x80, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x50, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x52, 0xf5} }, +{ 0x933d, 16, {0x53, 0x89, 0x54, 0xfe, 0x12, 0x92, 0xbc, 0xef, 0x60, 0x50, 0xab, 0x52, 0xaa, 0x53, 0xa9, 0x54} }, +{ 0x934d, 16, {0x12, 0x9f, 0x48, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x02, 0x16, 0xc2, 0xaf} }, +{ 0x935d, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} }, +{ 0x936d, 16, {0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} }, +{ 0x937d, 16, {0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x30, 0x60, 0x0f, 0x85, 0x51, 0x82, 0x85, 0x50} }, +{ 0x938d, 10, {0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} }, +{ 0x9397, 1, {0x22} }, +{ 0x9398, 16, {0x12, 0x93, 0x1d, 0xe4, 0xf5, 0x4b, 0x74, 0x36, 0x25, 0x4b, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4c} }, +{ 0x93a8, 16, {0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4c, 0xff, 0xc4} }, +{ 0x93b8, 16, {0x54, 0x0f, 0xf5, 0x4d, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} }, +{ 0x93c8, 16, {0x83, 0xe5, 0x4c, 0xf0, 0xaf, 0x4b, 0x7d, 0x01, 0xe5, 0x4c, 0x45, 0x4d, 0xfb, 0x12, 0x92, 0x4b} }, +{ 0x93d8, 16, {0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40} }, +{ 0x93e8, 16, {0xb5, 0x12, 0x93, 0x1d, 0xe5, 0x3a, 0x60, 0x48, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} }, +{ 0x93f8, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x55, 0x3a, 0x60, 0x29, 0xe5, 0x4b} }, +{ 0x9408, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} }, +{ 0x9418, 16, {0x16, 0xaf, 0x4b, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d} }, +{ 0x9428, 16, {0x80, 0xef, 0xe5, 0x4c, 0xf4, 0x52, 0x3a, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xbb} }, +{ 0x9438, 16, {0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0x05, 0x74, 0x19, 0xf0, 0x7f, 0x02, 0x12, 0x81} }, +{ 0x9448, 16, {0xd9, 0x8e, 0x4e, 0x8f, 0x4f, 0xc3, 0xe5, 0x4e, 0x64, 0x80, 0x94, 0x80, 0x40, 0xee, 0x90, 0x01} }, +{ 0x9458, 16, {0xbc, 0xe0, 0x65, 0x4f, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8, 0x07} }, +{ 0x9468, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xbc, 0xe0, 0x55, 0x4c, 0x60} }, +{ 0x9478, 16, {0x14, 0xaf, 0x4b, 0x7d, 0x08, 0xe5, 0x4c, 0x55, 0x4f, 0xfb, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05} }, +{ 0x9488, 16, {0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xcc, 0x90, 0x01} }, +{ 0x9498, 16, {0xbc, 0xe5, 0x4f, 0xf0, 0xe4, 0xf5, 0x4b, 0xc2, 0xaf, 0x74, 0x32, 0x25, 0x4b, 0xf8, 0xe6, 0xf5} }, +{ 0x94a8, 16, {0x4c, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4c, 0x1e, 0xe5, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x02} }, +{ 0x94b8, 16, {0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0x2c, 0x25} }, +{ 0x94c8, 16, {0x4b, 0xf8, 0xe6, 0xf5, 0x4c, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} }, +{ 0x94d8, 16, {0xe0, 0x65, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x04, 0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70} }, +{ 0x94e8, 16, {0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5} }, +{ 0x94f8, 16, {0x83, 0xe5, 0x4c, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0x9a, 0x12, 0x93, 0x1d} }, +{ 0x9508, 1, {0x22} }, +{ 0x9509, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x62, 0x02, 0x95, 0x50} }, +{ 0x9515, 16, {0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} }, +{ 0x9525, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} }, +{ 0x9535, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} }, +{ 0x9545, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x95, 0x95, 0xe4, 0x7e} }, +{ 0x9555, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} }, +{ 0x9565, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} }, +{ 0x9575, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} }, +{ 0x9585, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} }, +{ 0x9595, 16, {0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} }, +{ 0x95a5, 16, {0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} }, +{ 0x95b5, 8, {0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} }, +{ 0x95bd, 1, {0x00} }, +{ 0x95be, 3, {0x00, 0x03, 0x1d} }, +{ 0x95c1, 8, {0x8b, 0x54, 0x8a, 0x55, 0x89, 0x56, 0x8d, 0x57} }, +{ 0x95c9, 16, {0xe4, 0xf5, 0x58, 0xf5, 0x59, 0xaf, 0x57, 0x15, 0x57, 0xef, 0x60, 0x36, 0xab, 0x54, 0x05, 0x56} }, +{ 0x95d9, 16, {0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf9, 0x12, 0x9f, 0x48, 0xff, 0xe5, 0x58} }, +{ 0x95e9, 16, {0xe5, 0x59, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0xa2, 0x2f, 0xf5, 0x82, 0xee, 0x34} }, +{ 0x95f9, 16, {0x9b, 0xf5, 0x83, 0xe5, 0x58, 0xff, 0xe4, 0x93, 0xf5, 0x58, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x59} }, +{ 0x9609, 6, {0x80, 0xc3, 0xae, 0x58, 0xaf, 0x59} }, +{ 0x960f, 1, {0x22} }, +{ 0x9610, 11, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} }, +{ 0x961b, 16, {0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} }, +{ 0x962b, 16, {0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} }, +{ 0x963b, 16, {0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} }, +{ 0x964b, 10, {0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} }, +{ 0x9655, 9, {0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, +{ 0x965e, 2, {0xa9, 0x03} }, +{ 0x9660, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} }, +{ 0x9670, 16, {0x57, 0x45, 0x58, 0xf5, 0x59, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} }, +{ 0x9680, 16, {0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} }, +{ 0x9690, 16, {0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x59, 0xeb} }, +{ 0x96a0, 16, {0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x59, 0xfc, 0xb5, 0x06, 0x03, 0xaf} }, +{ 0x96b0, 16, {0x05, 0x22, 0xe5, 0x57, 0x5c, 0xfe, 0xe5, 0x58, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} }, +{ 0x96c0, 16, {0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} }, +{ 0x96d0, 16, {0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x57, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x58, 0x22, 0x7f} }, +{ 0x96e0, 1, {0x00} }, +{ 0x96e1, 1, {0x22} }, +{ 0x96e2, 16, {0x75, 0x50, 0x02, 0x75, 0x51, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x51, 0x82, 0x85} }, +{ 0x96f2, 16, {0x50, 0x83, 0xe0, 0xff, 0x90, 0x03, 0x36, 0xf0, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0} }, +{ 0x9702, 16, {0x90, 0x03, 0x37, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0x75, 0x52, 0x03, 0x75, 0x53, 0x39, 0xef, 0x14} }, +{ 0x9712, 16, {0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9b, 0x6a, 0x90, 0x97, 0x21, 0xf8, 0x28, 0x28, 0x73, 0x02} }, +{ 0x9722, 16, {0x97, 0x42, 0x02, 0x97, 0xe1, 0x02, 0x98, 0xe6, 0x02, 0x99, 0x06, 0x02, 0x99, 0x06, 0x02, 0x99} }, +{ 0x9732, 16, {0xa1, 0x02, 0x99, 0xdc, 0x02, 0x9a, 0x01, 0x02, 0x9a, 0xbf, 0x02, 0x9a, 0xef, 0x02, 0x9b, 0x1b} }, +{ 0x9742, 16, {0xe4, 0xf5, 0x4b, 0xe5, 0x4b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20} }, +{ 0x9752, 16, {0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74, 0x8a, 0x2e} }, +{ 0x9762, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4c, 0x80, 0x0d, 0x74, 0x8a, 0x2e} }, +{ 0x9772, 16, {0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4c, 0xe5, 0x4f, 0x24, 0x07, 0xf5, 0x82} }, +{ 0x9782, 16, {0xe4, 0x35, 0x4e, 0xf5, 0x83, 0xe5, 0x4c, 0xf0, 0xe0, 0xf5, 0x4d, 0x65, 0x4c, 0x60, 0x38, 0xe4} }, +{ 0x9792, 16, {0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfd, 0x05, 0x53, 0xe5, 0x53, 0xaa, 0x52, 0x70, 0x02} }, +{ 0x97a2, 16, {0x05, 0x52, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70} }, +{ 0x97b2, 16, {0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4c, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, +{ 0x97c2, 16, {0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64, 0x02, 0x70} }, +{ 0x97d2, 16, {0x87, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60, 0x03, 0x02, 0x97, 0x45, 0x02, 0x9b, 0x70, 0xe4} }, +{ 0x97e2, 16, {0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x05, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x03} }, +{ 0x97f2, 16, {0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe4, 0xf5, 0x4d, 0x7e} }, +{ 0x9802, 16, {0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} }, +{ 0x9812, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xc4, 0xf0, 0x90, 0x01} }, +{ 0x9822, 16, {0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0x74, 0x02} }, +{ 0x9832, 16, {0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4c, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0} }, +{ 0x9842, 16, {0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52} }, +{ 0x9852, 16, {0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, +{ 0x9862, 16, {0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4d, 0xff, 0x90, 0x01, 0xc4, 0xe0} }, +{ 0x9872, 16, {0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfe, 0x05, 0x53, 0xe5, 0x53} }, +{ 0x9882, 16, {0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05, 0x53, 0xe5} }, +{ 0x9892, 16, {0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53} }, +{ 0x98a2, 16, {0x82, 0x85, 0x52, 0x83, 0xe5, 0x4c, 0xf0, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x70, 0x16, 0x74, 0x08} }, +{ 0x98b2, 16, {0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35, 0x4e, 0xf5, 0x4e, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60} }, +{ 0x98c2, 16, {0x03, 0x02, 0x98, 0x0d, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x05, 0x4b} }, +{ 0x98d2, 16, {0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3, 0x74, 0x12} }, +{ 0x98e2, 16, {0xf0, 0x02, 0x9b, 0x70, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0, 0x14, 0xff, 0x74, 0x01} }, +{ 0x98f2, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01, 0xc4} }, +{ 0x9902, 16, {0xf0, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4, 0xf5} }, +{ 0x9912, 16, {0x4d, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01, 0xc0} }, +{ 0x9922, 16, {0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} }, +{ 0x9932, 16, {0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4d, 0xe5, 0x4d, 0x60, 0x03, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0} }, +{ 0x9942, 16, {0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7f} }, +{ 0x9952, 16, {0x02, 0x12, 0x81, 0xd9, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xef, 0x54, 0x0f, 0xf5} }, +{ 0x9962, 16, {0x4d, 0x90, 0x02, 0xf7, 0xe0, 0x55, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f} }, +{ 0x9972, 16, {0x4c, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4c, 0x70, 0x04, 0x7f} }, +{ 0x9982, 16, {0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4c, 0xe5, 0x4c, 0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90} }, +{ 0x9992, 16, {0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0xe4} }, +{ 0x99a2, 16, {0xff, 0xfd, 0x12, 0x82, 0xa8, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0x85} }, +{ 0x99b2, 16, {0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x4f, 0x82, 0x85} }, +{ 0x99c2, 16, {0x4e, 0x83, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3} }, +{ 0x99d2, 16, {0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xd2, 0x04, 0x02, 0x9b, 0x70, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00} }, +{ 0x99e2, 16, {0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xe5, 0x4f, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x4e, 0xf5} }, +{ 0x99f2, 16, {0x83, 0xe0, 0x30, 0xe6, 0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x02, 0x9b, 0x70, 0xe4} }, +{ 0x9a02, 16, {0xf5, 0x4d, 0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0xe5, 0x4b, 0x75, 0xf0, 0x08} }, +{ 0x9a12, 16, {0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xf5, 0x83} }, +{ 0x9a22, 16, {0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf} }, +{ 0x9a32, 16, {0x4b, 0x7d, 0x01, 0x7b, 0x01, 0x75, 0x57, 0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d} }, +{ 0x9a42, 16, {0xe5, 0x4d, 0x70, 0x11, 0xaf, 0x4b, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20} }, +{ 0x9a52, 16, {0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d, 0x01, 0xfb, 0x75, 0x57} }, +{ 0x9a62, 16, {0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d} }, +{ 0x9a72, 16, {0x02, 0xfb, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xaf, 0x4b, 0x7d} }, +{ 0x9a82, 16, {0x01, 0x12, 0x82, 0xa8, 0xe5, 0x4d, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04} }, +{ 0x9a92, 16, {0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83} }, +{ 0x9aa2, 16, {0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x05, 0x4b} }, +{ 0x9ab2, 16, {0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x50, 0x03, 0x02, 0x9a, 0x06, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} }, +{ 0x9ac2, 16, {0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74} }, +{ 0x9ad2, 16, {0x9b, 0xf0, 0xa3, 0x74, 0x92, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08} }, +{ 0x9ae2, 16, {0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} }, +{ 0x9af2, 16, {0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5} }, +{ 0x9b02, 16, {0x52, 0xf0, 0xa3, 0xe5, 0x53, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0x2c, 0xef, 0x64, 0x08} }, +{ 0x9b12, 16, {0x60, 0x5c, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x51, 0x24, 0x02, 0xff, 0xe4, 0x35} }, +{ 0x9b22, 16, {0x50, 0xfa, 0xa9, 0x07, 0x7b, 0x01, 0x7d, 0x10, 0x12, 0x95, 0xc1, 0xef, 0x4e, 0x70, 0x32, 0x90} }, +{ 0x9b32, 16, {0x03, 0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5} }, +{ 0x9b42, 16, {0x51, 0x24, 0x02, 0x90, 0x03, 0x60, 0xf0, 0xe4, 0x35, 0x50, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03} }, +{ 0x9b52, 16, {0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80} }, +{ 0x9b62, 16, {0x0d, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01} }, +{ 0x9b72, 16, {0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70} }, +{ 0x9b82, 15, {0xf6, 0x7e, 0x03, 0x7f, 0x35, 0x7d, 0x24, 0x12, 0x8e, 0xb4, 0xe4, 0x90, 0x02, 0xaf, 0xf0} }, +{ 0x9b91, 1, {0x22} }, +{ 0x9b92, 16, {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} }, +{ 0x9ba2, 16, {0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} }, +{ 0x9bb2, 16, {0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} }, +{ 0x9bc2, 16, {0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} }, +{ 0x9bd2, 16, {0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} }, +{ 0x9be2, 16, {0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} }, +{ 0x9bf2, 16, {0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} }, +{ 0x9c02, 16, {0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} }, +{ 0x9c12, 16, {0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} }, +{ 0x9c22, 16, {0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} }, +{ 0x9c32, 16, {0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} }, +{ 0x9c42, 16, {0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} }, +{ 0x9c52, 16, {0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} }, +{ 0x9c62, 16, {0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} }, +{ 0x9c72, 16, {0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} }, +{ 0x9c82, 16, {0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} }, +{ 0x9c92, 16, {0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} }, +{ 0x9ca2, 16, {0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} }, +{ 0x9cb2, 16, {0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} }, +{ 0x9cc2, 16, {0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} }, +{ 0x9cd2, 16, {0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} }, +{ 0x9ce2, 16, {0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} }, +{ 0x9cf2, 16, {0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} }, +{ 0x9d02, 16, {0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} }, +{ 0x9d12, 16, {0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} }, +{ 0x9d22, 16, {0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} }, +{ 0x9d32, 16, {0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} }, +{ 0x9d42, 16, {0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} }, +{ 0x9d52, 16, {0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} }, +{ 0x9d62, 16, {0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} }, +{ 0x9d72, 16, {0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} }, +{ 0x9d82, 16, {0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} }, +{ 0x9d92, 16, {0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} }, +{ 0x9da2, 16, {0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} }, +{ 0x9db2, 16, {0x9e, 0x45, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9e, 0x45, 0xef, 0x75, 0xf0} }, +{ 0x9dc2, 16, {0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} }, +{ 0x9dd2, 16, {0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} }, +{ 0x9de2, 16, {0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} }, +{ 0x9df2, 16, {0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} }, +{ 0x9e02, 16, {0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} }, +{ 0x9e12, 16, {0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} }, +{ 0x9e22, 16, {0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} }, +{ 0x9e32, 16, {0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} }, +{ 0x9e42, 12, {0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9d, 0xa4} }, +{ 0x9e4e, 1, {0x22} }, +{ 0x9e4f, 16, {0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} }, +{ 0x9e5f, 16, {0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} }, +{ 0x9e6f, 16, {0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} }, +{ 0x9e7f, 16, {0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} }, +{ 0x9e8f, 16, {0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} }, +{ 0x9e9f, 16, {0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} }, +{ 0x9eaf, 16, {0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} }, +{ 0x9ebf, 16, {0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} }, +{ 0x9ecf, 16, {0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} }, +{ 0x9edf, 16, {0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} }, +{ 0x9eef, 16, {0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} }, +{ 0x9eff, 16, {0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} }, +{ 0x9f0f, 16, {0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} }, +{ 0x9f1f, 16, {0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} }, +{ 0x9f2f, 16, {0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} }, +{ 0x9f3f, 9, {0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9e, 0x9f, 0x73} }, +{ 0x9f48, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} }, +{ 0x9f58, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} }, +{ 0x9f61, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} }, +{ 0x9f71, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} }, +{ 0x9f81, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} }, +{ 0x9f8e, 16, {0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} }, +{ 0x9f9e, 6, {0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} }, +{ 0x9fa4, 16, {0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} }, +{ 0x9fb4, 6, {0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} }, +{ 0x9fba, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} }, +{ 0x9fca, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} }, +{ 0x9fda, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} }, +{ 0x9fea, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} }, +{ 0x9ff2, 16, {0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} }, +{ 0xa002, 16, {0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} }, +{ 0xa012, 16, {0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} }, +{ 0xa022, 16, {0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} }, +{ 0xa032, 16, {0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} }, +{ 0xa042, 16, {0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} }, +{ 0xa052, 16, {0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} }, +{ 0xa062, 16, {0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} }, +{ 0xa072, 16, {0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} }, +{ 0xa082, 16, {0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} }, +{ 0xa092, 16, {0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} }, +{ 0xa0a2, 16, {0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} }, +{ 0xa0b2, 14, {0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} }, +{ 0xa0c0, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} }, +{ 0xa0d0, 1, {0x22} }, +{ 0xa0d1, 16, {0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} }, +{ 0xa0e1, 3, {0xd8, 0xf1, 0x22} }, +{ 0xa0e4, 16, {0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} }, +{ 0xa0f4, 7, {0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} }, +{ 0xa0fb, 12, {0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, +{ 0xa107, 16, {0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0x12} }, +{ 0xa117, 16, {0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} }, +{ 0xa127, 16, {0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} }, +{ 0xa137, 1, {0x22} }, { 0xffff, 0, {0x00} } }; diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 860c38158..912ae94c4 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -1,6 +1,6 @@ /* Driver for Freecom USB/IDE adaptor * - * $Id: freecom.c,v 1.12 2000/09/22 01:16:17 mdharm Exp $ + * $Id: freecom.c,v 1.13 2000/10/03 01:06:07 mdharm Exp $ * * Freecom v0.1: * @@ -28,6 +28,7 @@ * (http://www.freecom.de/) */ +#include <linux/config.h> #include "transport.h" #include "protocol.h" #include "usb.h" @@ -35,7 +36,9 @@ #include "freecom.h" #include "linux/hdreg.h" +#ifdef CONFIG_USB_STORAGE_DEBUG static void pdump (void *, int); +#endif struct freecom_udata { __u8 buffer[64]; /* Common command block. */ @@ -104,7 +107,7 @@ struct freecom_status { * Transfer an entire SCSI command's worth of data payload over the bulk * pipe. * - * Note that this uses us_transfer_partial to achieve it's goals -- this + * Note that this uses usb_stor_transfer_partial to achieve it's goals -- this * function simply determines if we're going to use scatter-gather or not, * and acts appropriately. For now, it also re-interprets the error codes. */ @@ -133,11 +136,12 @@ static void us_transfer_freecom(Scsi_Cmnd *srb, struct us_data* us, int transfer * remaining data */ if (transfer_amount - total_transferred >= sg[i].length) { - result = us_transfer_partial(us, sg[i].address, - sg[i].length); + result = usb_stor_transfer_partial(us, + sg[i].address, sg[i].length); total_transferred += sg[i].length; } else - result = us_transfer_partial(us, sg[i].address, + result = usb_stor_transfer_partial(us, + sg[i].address, transfer_amount - total_transferred); /* if we get an error, end the loop here */ @@ -147,7 +151,7 @@ static void us_transfer_freecom(Scsi_Cmnd *srb, struct us_data* us, int transfer } else /* no scatter-gather, just make the request */ - result = us_transfer_partial(us, srb->request_buffer, + result = usb_stor_transfer_partial(us, srb->request_buffer, transfer_amount); /* return the result in the data structure itself */ @@ -165,7 +169,7 @@ freecom_ide_write (struct us_data *us, int reg, int value) int opipe; int result, partial; - printk (KERN_DEBUG "IDE out 0x%02x <- 0x%02x\n", reg, value); + US_DEBUGP("IDE out 0x%02x <- 0x%02x\n", reg, value); /* Get handles for both transports. */ opipe = usb_sndbulkpipe (us->pusb_dev, us->ep_out); @@ -247,7 +251,7 @@ freecom_ide_read (struct us_data *us, int reg, int *value) else *value = le16_to_cpu (*(__u16 *) buffer); - printk (KERN_DEBUG "IDE in 0x%02x -> 0x%02x\n", reg, *value); + US_DEBUGP("IDE in 0x%02x -> 0x%02x\n", reg, *value); return USB_STOR_TRANSPORT_GOOD; } @@ -260,16 +264,13 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, struct freecom_xfer_wrap *fxfr = (struct freecom_xfer_wrap *) extra->buffer; int result, partial; - int offset; - int this_read; - __u8 *buffer = extra->buffer; fxfr->Type = FCM_PACKET_INPUT | 0x00; fxfr->Timeout = 0; /* Short timeout for debugging. */ fxfr->Count = cpu_to_le32 (count); memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); - printk (KERN_DEBUG "Read data Freecom! (c=%d)\n", count); + US_DEBUGP("Read data Freecom! (c=%d)\n", count); /* Issue the transfer command. */ result = usb_stor_bulk_msg (us, fxfr, opipe, @@ -280,78 +281,19 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, /* -ENOENT -- we canceled this transfer */ if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + US_DEBUGP("freecom_readdata(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } return USB_STOR_TRANSPORT_ERROR; } - printk (KERN_DEBUG "Done issuing read request: %d %d\n", - result, partial); + US_DEBUGP("Done issuing read request: %d %d\n", result, partial); /* Now transfer all of our blocks. */ - printk (KERN_DEBUG "Start of read\n"); + US_DEBUGP("Start of read\n"); us_transfer_freecom(srb, us, count); -#if 0 - if (srb->use_sg) { - US_DEBUGP ("Need to implement scatter-gather\n"); - return USB_STOR_TRANSPORT_ERROR; - } else { - offset = 0; - - while (offset < count) { -#if 0 - this_read = count - offset; - if (this_read > 64) - this_read = 64; -#else - this_read = 64; -#endif - - printk (KERN_DEBUG "Start of read\n"); - /* Use the given buffer directly, but only if there - * is space for an entire packet. */ - - if (offset + 64 <= srb->request_bufflen) { - result = usb_stor_bulk_msg ( - us, srb->request_buffer+offset, - ipipe, this_read, &partial); - printk (KERN_DEBUG "Read111 = %d, %d\n", - result, partial); - pdump (srb->request_buffer+offset, - partial); - } else { - result = usb_stor_bulk_msg ( - us, buffer, - ipipe, this_read, &partial); - printk (KERN_DEBUG "Read112 = %d, %d\n", - result, partial); - memcpy (srb->request_buffer+offset, - buffer, - srb->request_bufflen - offset); - pdump (srb->request_buffer+offset, - srb->request_bufflen - offset); - } - - if (result != 0) { - US_DEBUGP ("Freecom readblock r=%d, p=%d\n", - result, partial); - - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); - return US_BULK_TRANSFER_ABORTED; - } + US_DEBUGP("freecom_readdata done!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - offset += this_read; - } - } -#endif - - printk (KERN_DEBUG "freecom_readdata done!\n"); return USB_STOR_TRANSPORT_GOOD; } @@ -363,16 +305,13 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, struct freecom_xfer_wrap *fxfr = (struct freecom_xfer_wrap *) extra->buffer; int result, partial; - int offset; - int this_write; - __u8 *buffer = extra->buffer; fxfr->Type = FCM_PACKET_OUTPUT | 0x00; fxfr->Timeout = 0; /* Short timeout for debugging. */ fxfr->Count = cpu_to_le32 (count); memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); - printk (KERN_DEBUG "Write data Freecom! (c=%d)\n", count); + US_DEBUGP("Write data Freecom! (c=%d)\n", count); /* Issue the transfer command. */ result = usb_stor_bulk_msg (us, fxfr, opipe, @@ -383,78 +322,20 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, /* -ENOENT -- we canceled this transfer */ if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + US_DEBUGP("freecom_writedata(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } return USB_STOR_TRANSPORT_ERROR; } - printk (KERN_DEBUG "Done issuing write request: %d %d\n", + US_DEBUGP("Done issuing write request: %d %d\n", result, partial); /* Now transfer all of our blocks. */ - printk (KERN_DEBUG "Start of write\n"); + US_DEBUGP("Start of write\n"); us_transfer_freecom(srb, us, count); -#if 0 - if (srb->use_sg) { - US_DEBUGP ("Need to implement scatter-gather\n"); - return USB_STOR_TRANSPORT_ERROR; - } else { - offset = 0; - - while (offset < count) { -#if 1 - this_write = count - offset; - if (this_write > 64) - this_write = 64; -#else - this_write = 64; -#endif - - printk (KERN_DEBUG "Start of write\n"); - /* Use the given buffer directly, but only if there - * is space for an entire packet. */ - - if (offset + 64 <= srb->request_bufflen) { - result = usb_stor_bulk_msg ( - us, srb->request_buffer+offset, - opipe, this_write, &partial); - printk (KERN_DEBUG "Write111 = %d, %d\n", - result, partial); - pdump (srb->request_buffer+offset, - partial); - } else { - result = usb_stor_bulk_msg ( - us, buffer, - opipe, this_write, &partial); - printk (KERN_DEBUG "Write112 = %d, %d\n", - result, partial); - memcpy (buffer, - srb->request_buffer+offset, - srb->request_bufflen - offset); - pdump (srb->request_buffer+offset, - srb->request_bufflen - offset); - } - - if (result != 0) { - US_DEBUGP ("Freecom writeblock r=%d, p=%d\n", - result, partial); - - /* -ENOENT -- we canceled this transfer */ - if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); - return US_BULK_TRANSFER_ABORTED; - } - - return USB_STOR_TRANSPORT_ERROR; - } - - offset += this_write; - } - } -#endif - printk (KERN_DEBUG "freecom_writedata done!\n"); + US_DEBUGP("freecom_writedata done!\n"); return USB_STOR_TRANSPORT_GOOD; } @@ -477,7 +358,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) fcb = (struct freecom_cb_wrap *) extra->buffer; fst = (struct freecom_status *) extra->buffer; - printk (KERN_DEBUG "Freecom TRANSPORT STARTED\n"); + US_DEBUGP("Freecom TRANSPORT STARTED\n"); /* Get handles for both transports. */ opipe = usb_sndbulkpipe (us->pusb_dev, us->ep_out); @@ -496,7 +377,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) memcpy (fcb->Atapi, srb->cmnd, 12); memset (fcb->Filler, 0, sizeof (fcb->Filler)); - pdump (srb->cmnd, 12); + US_DEBUG(pdump (srb->cmnd, 12)); /* Send it out. */ result = usb_stor_bulk_msg (us, fcb, opipe, @@ -511,7 +392,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) /* -ENOENT -- we canceled this transfer */ if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + US_DEBUGP("freecom_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -522,14 +403,14 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) * doesn't hurt us to always do it now. */ result = usb_stor_bulk_msg (us, fst, ipipe, FCM_PACKET_LENGTH, &partial); - printk (KERN_DEBUG "foo Status result %d %d\n", result, partial); + US_DEBUGP("foo Status result %d %d\n", result, partial); /* -ENOENT -- we canceled this transfer */ if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + US_DEBUGP("freecom_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } - pdump ((void *) fst, partial); + US_DEBUG(pdump ((void *) fst, partial)); /* while we haven't recieved the IRQ */ while (!(fst->Status & 0x2)) { @@ -545,16 +426,17 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) result = usb_stor_bulk_msg (us, fcb, opipe, FCM_PACKET_LENGTH, &partial); - /* The Freecom device will only fail if there is something wrong in - * USB land. It returns the status in its own registers, which - * come back in the bulk pipe. */ + /* The Freecom device will only fail if there is something + * wrong in USB land. It returns the status in its own + * registers, which come back in the bulk pipe. + */ if (result != 0) { US_DEBUGP ("freecom xport failure: r=%d, p=%d\n", result, partial); /* -ENOENT -- we canceled this transfer */ if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + US_DEBUGP("freecom_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } @@ -564,35 +446,35 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) /* actually get the status info */ result = usb_stor_bulk_msg (us, fst, ipipe, FCM_PACKET_LENGTH, &partial); - printk (KERN_DEBUG "bar Status result %d %d\n", result, partial); + US_DEBUGP("bar Status result %d %d\n", result, partial); /* -ENOENT -- we canceled this transfer */ if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + US_DEBUGP("freecom_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } - pdump ((void *) fst, partial); + US_DEBUG(pdump ((void *) fst, partial)); } if (partial != 4 || result != 0) { return USB_STOR_TRANSPORT_ERROR; } if ((fst->Status & 1) != 0) { - printk (KERN_DEBUG "operation failed\n"); + US_DEBUGP("operation failed\n"); return USB_STOR_TRANSPORT_FAILED; } /* The device might not have as much data available as we * requested. If you ask for more than the device has, this reads * and such will hang. */ - printk (KERN_DEBUG "Device indicates that it has %d bytes available\n", + US_DEBUGP("Device indicates that it has %d bytes available\n", le16_to_cpu (fst->Count)); /* Find the length we desire to read. It is the lesser of the SCSI * layer's requested length, and the length the device claims to * have available. */ - length = us_transfer_length (srb); - printk (KERN_DEBUG "SCSI requested %d\n", length); + length = usb_stor_transfer_length (srb); + US_DEBUGP("SCSI requested %d\n", length); if (length > le16_to_cpu (fst->Count)) length = le16_to_cpu (fst->Count); @@ -604,17 +486,17 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) /* Make sure that the status indicates that the device * wants data as well. */ if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { - printk (KERN_DEBUG "SCSI wants data, drive doesn't have any\n"); + US_DEBUGP("SCSI wants data, drive doesn't have any\n"); return USB_STOR_TRANSPORT_FAILED; } result = freecom_readdata (srb, us, ipipe, opipe, length); if (result != USB_STOR_TRANSPORT_GOOD) return result; - printk (KERN_DEBUG "FCM: Waiting for status\n"); + US_DEBUGP("FCM: Waiting for status\n"); result = usb_stor_bulk_msg (us, fst, ipipe, FCM_PACKET_LENGTH, &partial); - pdump ((void *) fst, partial); + US_DEBUG(pdump ((void *) fst, partial)); if (result == -ENOENT) { US_DEBUGP ("freecom_transport: transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; @@ -622,14 +504,14 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) if (partial != 4 || result != 0) return USB_STOR_TRANSPORT_ERROR; if ((fst->Status & ERR_STAT) != 0) { - printk (KERN_DEBUG "operation failed\n"); + US_DEBUGP("operation failed\n"); return USB_STOR_TRANSPORT_FAILED; } if ((fst->Reason & 3) != 3) { - printk (KERN_DEBUG "Drive seems still hungry\n"); + US_DEBUGP("Drive seems still hungry\n"); return USB_STOR_TRANSPORT_FAILED; } - printk (KERN_DEBUG "Transfer happy\n"); + US_DEBUGP("Transfer happy\n"); break; case SCSI_DATA_WRITE: @@ -641,7 +523,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) return result; #if 1 - printk (KERN_DEBUG "FCM: Waiting for status\n"); + US_DEBUGP("FCM: Waiting for status\n"); result = usb_stor_bulk_msg (us, fst, ipipe, FCM_PACKET_LENGTH, &partial); if (result == -ENOENT) { @@ -651,15 +533,15 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) if (partial != 4 || result != 0) return USB_STOR_TRANSPORT_ERROR; if ((fst->Status & ERR_STAT) != 0) { - printk (KERN_DEBUG "operation failed\n"); + US_DEBUGP("operation failed\n"); return USB_STOR_TRANSPORT_FAILED; } if ((fst->Reason & 3) != 3) { - printk (KERN_DEBUG "Drive seems still hungry\n"); + US_DEBUGP("Drive seems still hungry\n"); return USB_STOR_TRANSPORT_FAILED; } #endif - printk (KERN_DEBUG "Transfer happy\n"); + US_DEBUGP("Transfer happy\n"); break; @@ -675,27 +557,12 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) break; } -#if 0 - /* After the transfer, we can read our status register. */ - printk (KERN_DEBUG "Going to read status register\n"); - result = usb_stor_bulk_msg (us, &fst, ipipe, - FCM_PACKET_LENGTH, &partial); - printk (KERN_DEBUG "Result from read %d %d\n", result, partial); - if (result != 0) { - return USB_STOR_TRANSPORT_ERROR; - } - if ((fst.Reason & 1) != 0) { - return USB_STOR_TRANSPORT_FAILED; - } -#endif - return USB_STOR_TRANSPORT_GOOD; - printk (KERN_DEBUG "Freecom: transfer_length = %d\n", - us_transfer_length (srb)); + US_DEBUGP("Freecom: transfer_length = %d\n", + usb_stor_transfer_length (srb)); - printk (KERN_DEBUG "Freecom: direction = %d\n", - srb->sc_data_direction); + US_DEBUGP("Freecom: direction = %d\n", srb->sc_data_direction); return USB_STOR_TRANSPORT_ERROR; } @@ -713,13 +580,14 @@ freecom_init (struct us_data *us) us->extra = kmalloc (sizeof (struct freecom_udata), GFP_KERNEL); if (us->extra == NULL) { - printk (KERN_WARNING USB_STORAGE "Out of memory\n"); + US_DEBUGP("Out of memory\n"); return USB_STOR_TRANSPORT_ERROR; } } - result = usb_stor_control_msg(us, usb_rcvctrlpipe(us->pusb_dev, 0), - 0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20); + result = usb_control_msg(us->pusb_dev, + usb_rcvctrlpipe(us->pusb_dev, 0), + 0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*HZ); buffer[32] = '\0'; US_DEBUGP("String returned from FC init is: %s\n", buffer); @@ -736,7 +604,7 @@ freecom_init (struct us_data *us) if (result != USB_STOR_TRANSPORT_GOOD) return result; if (counter-- < 0) { - printk (KERN_WARNING USB_STORAGE "Timeout in freecom"); + US_DEBUGP("Timeout in freecom"); return USB_STOR_TRANSPORT_ERROR; } } while ((value & 0x80) != 0); @@ -751,7 +619,7 @@ freecom_init (struct us_data *us) if (result != USB_STOR_TRANSPORT_GOOD) return result; if (counter-- < 0) { - printk (KERN_WARNING USB_STORAGE "Timeout in freecom"); + US_DEBUGP("Timeout in freecom"); return USB_STOR_TRANSPORT_ERROR; } } while ((value & 0x80) != 0); @@ -765,12 +633,13 @@ freecom_init (struct us_data *us) int usb_stor_freecom_reset(struct us_data *us) { - printk (KERN_DEBUG "freecom reset called\n"); + printk (KERN_CRIT "freecom reset called\n"); /* We don't really have this feature. */ - return USB_STOR_TRANSPORT_ERROR; + return FAILED; } +#ifdef CONFIG_USB_STORAGE_DEBUG static void pdump (void *ibuffer, int length) { static char line[80]; @@ -791,7 +660,7 @@ static void pdump (void *ibuffer, int length) line[offset++] = '.'; } line[offset] = 0; - printk (KERN_DEBUG "%s\n", line); + US_DEBUGP("%s\n", line); offset = 0; } offset += sprintf (line+offset, "%08x:", i); @@ -819,7 +688,8 @@ static void pdump (void *ibuffer, int length) line[offset++] = '.'; } line[offset] = 0; - printk (KERN_DEBUG "%s\n", line); + US_DEBUGP("%s\n", line); offset = 0; } +#endif diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index e5420ff6b..80ace9dac 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -1,7 +1,7 @@ /* Driver for USB Mass Storage compliant devices * SCSI layer glue code * - * $Id: scsiglue.c,v 1.13 2000/09/28 21:54:30 mdharm Exp $ + * $Id: scsiglue.c,v 1.15 2000/10/19 18:44:11 mdharm Exp $ * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) @@ -168,34 +168,30 @@ static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) * Error handling functions ***********************************************************************/ -/* Command abort - * - * Note that this is really only meaningful right now for CBI transport - * devices which have failed to give us the command completion interrupt - */ +/* Command abort */ static int command_abort( Scsi_Cmnd *srb ) { struct us_data *us = (struct us_data *)srb->host->hostdata[0]; - wait_queue_head_t *wqh = (wait_queue_head_t *)us->current_urb->context; US_DEBUGP("command_abort() called\n"); /* if we're stuck waiting for an IRQ, simulate it */ - if (us->ip_wanted) { + if (atomic_read(us->ip_wanted)) { US_DEBUGP("-- simulating missing IRQ\n"); up(&(us->ip_waitq)); + } + + /* if the device has been removed, this worked */ + if (!us->pusb_dev) { + US_DEBUGP("-- device removed already\n"); return SUCCESS; } /* if we have an urb pending, let's wake the control thread up */ if (us->current_urb->status == -EINPROGRESS) { - /* cancel the URB */ + /* cancel the URB -- this will automatically wake the thread */ usb_unlink_urb(us->current_urb); - /* wake the control thread up */ - if (waitqueue_active(wqh)) - wake_up(wqh); - /* wait for us to be done */ down(&(us->notify)); return SUCCESS; @@ -226,6 +222,12 @@ static int bus_reset( Scsi_Cmnd *srb ) /* we use the usb_reset_device() function to handle this for us */ US_DEBUGP("bus_reset() called\n"); + /* if the device has been removed, this worked */ + if (!us->pusb_dev) { + US_DEBUGP("-- device removed already\n"); + return SUCCESS; + } + /* attempt to reset the port */ if (usb_reset_device(us->pusb_dev) < 0) return FAILED; diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 5641a751a..cbf3db2ca 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1,6 +1,6 @@ /* Driver for SanDisk SDDR-09 SmartMedia reader * - * $Id: sddr09.c,v 1.10 2000/08/25 00:13:51 mdharm Exp $ + * $Id: sddr09.c,v 1.12 2000/10/03 01:06:07 mdharm Exp $ * * SDDR09 driver v0.1: * @@ -40,12 +40,6 @@ #include <linux/errno.h> #include <linux/malloc.h> -extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe, - u8 request, u8 requesttype, u16 value, u16 index, - void *data, u16 size); -extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe, - unsigned int len, unsigned int *act_len); - #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) #define LSB_of(s) ((s)&0xFF) #define MSB_of(s) ((s)>>8) @@ -418,7 +412,7 @@ int sddr09_read_control(struct us_data *us, MSB_of(blocks), LSB_of(blocks) }; - US_DEBUGP("Read control address %08X blocks %04X\n", + US_DEBUGP("Read control address %08lX blocks %04X\n", address, blocks); result = sddr09_send_control(us, @@ -814,8 +808,8 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us) unsigned char inquiry_response[36] = { 0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00 }; - unsigned char mode_page_01[12] = { - 0x01, 0x0a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + unsigned char mode_page_01[4] = { // write-protected for now + 0x03, 0x00, 0x80, 0x00 }; unsigned char *ptr; unsigned long capacity; @@ -887,14 +881,14 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us) } if (srb->cmnd[0] == MODE_SENSE) { - + // Read-write error recovery page: there needs to // be a check for write-protect here if ( (srb->cmnd[2] & 0x3F) == 0x01 ) { - if (ptr==NULL || srb->request_bufflen<12) + if (ptr==NULL || srb->request_bufflen<4) return USB_STOR_TRANSPORT_ERROR; - memcpy(ptr, mode_page_01, 12); + memcpy(ptr, mode_page_01, sizeof(mode_page_01)); return USB_STOR_TRANSPORT_GOOD; } diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index ebfda2b0d..6551d259c 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1,6 +1,6 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: transport.c,v 1.27 2000/09/28 21:54:30 mdharm Exp $ + * $Id: transport.c,v 1.30 2000/10/24 02:01:18 mdharm Exp $ * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) @@ -61,7 +61,7 @@ /* Calculate the length of the data transfer (not the command) for any * given SCSI command */ -static unsigned int us_transfer_length(Scsi_Cmnd *srb) +unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) { int i; int doDefault = 0; @@ -412,6 +412,9 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, FILL_CONTROL_URB(us->current_urb, us->pusb_dev, pipe, (unsigned char*) dr, data, size, usb_stor_blocking_completion, &wqh); + us->current_urb->actual_length = 0; + us->current_urb->error_count = 0; + us->current_urb->transfer_flags = USB_ASYNC_UNLINK; /* submit the URB */ set_current_state(TASK_UNINTERRUPTIBLE); @@ -426,7 +429,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, /* wait for the completion of the URB */ up(&(us->current_urb_sem)); - if (us->current_urb->status == -EINPROGRESS) + while (us->current_urb->status == -EINPROGRESS) schedule(); down(&(us->current_urb_sem)); @@ -466,6 +469,9 @@ int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe, /* fill the URB */ FILL_BULK_URB(us->current_urb, us->pusb_dev, pipe, data, len, usb_stor_blocking_completion, &wqh); + us->current_urb->actual_length = 0; + us->current_urb->error_count = 0; + us->current_urb->transfer_flags = USB_ASYNC_UNLINK; /* submit the URB */ set_current_state(TASK_UNINTERRUPTIBLE); @@ -479,7 +485,7 @@ int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe, /* wait for the completion of the URB */ up(&(us->current_urb_sem)); - if (us->current_urb->status == -EINPROGRESS) + while (us->current_urb->status == -EINPROGRESS) schedule(); down(&(us->current_urb_sem)); @@ -506,7 +512,7 @@ int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe, * timeout limit. Thus we don't have to worry about it for individual * packets. */ -static int us_transfer_partial(struct us_data *us, char *buf, int length) +int usb_stor_transfer_partial(struct us_data *us, char *buf, int length) { int result; int partial; @@ -519,7 +525,7 @@ static int us_transfer_partial(struct us_data *us, char *buf, int length) pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out); /* transfer the data */ - US_DEBUGP("us_transfer_partial(): xfer %d bytes\n", length); + US_DEBUGP("usb_stor_transfer_partial(): xfer %d bytes\n", length); result = usb_stor_bulk_msg(us, buf, pipe, length, &partial); US_DEBUGP("usb_stor_bulk_msg() returned %d xferred %d/%d\n", result, partial, length); @@ -532,7 +538,7 @@ static int us_transfer_partial(struct us_data *us, char *buf, int length) /* did we send all the data? */ if (partial == length) { - US_DEBUGP("us_transfer_partial(): transfer complete\n"); + US_DEBUGP("usb_stor_transfer_partial(): transfer complete\n"); return US_BULK_TRANSFER_GOOD; } @@ -540,18 +546,18 @@ static int us_transfer_partial(struct us_data *us, char *buf, int length) if (result) { /* NAK - that means we've retried a few times allready */ if (result == -ETIMEDOUT) { - US_DEBUGP("us_transfer_partial(): device NAKed\n"); + US_DEBUGP("usb_stor_transfer_partial(): device NAKed\n"); return US_BULK_TRANSFER_FAILED; } /* -ENOENT -- we canceled this transfer */ if (result == -ENOENT) { - US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + US_DEBUGP("usb_stor_transfer_partial(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } /* the catch-all case */ - US_DEBUGP("us_transfer_partial(): unknown error\n"); + US_DEBUGP("usb_stor_transfer_partial(): unknown error\n"); return US_BULK_TRANSFER_FAILED; } @@ -564,7 +570,7 @@ static int us_transfer_partial(struct us_data *us, char *buf, int length) * Transfer an entire SCSI command's worth of data payload over the bulk * pipe. * - * Note that this uses us_transfer_partial to achieve it's goals -- this + * Note that this uses usb_stor_transfer_partial to achieve it's goals -- this * function simply determines if we're going to use scatter-gather or not, * and acts appropriately. For now, it also re-interprets the error codes. */ @@ -577,7 +583,7 @@ static void us_transfer(Scsi_Cmnd *srb, struct us_data* us) unsigned int transfer_amount; /* calculate how much we want to transfer */ - transfer_amount = us_transfer_length(srb); + transfer_amount = usb_stor_transfer_length(srb); /* was someone foolish enough to request more data than available * buffer space? */ @@ -597,11 +603,12 @@ static void us_transfer(Scsi_Cmnd *srb, struct us_data* us) * remaining data */ if (transfer_amount - total_transferred >= sg[i].length) { - result = us_transfer_partial(us, sg[i].address, - sg[i].length); + result = usb_stor_transfer_partial(us, + sg[i].address, sg[i].length); total_transferred += sg[i].length; } else - result = us_transfer_partial(us, sg[i].address, + result = usb_stor_transfer_partial(us, + sg[i].address, transfer_amount - total_transferred); /* if we get an error, end the loop here */ @@ -611,7 +618,7 @@ static void us_transfer(Scsi_Cmnd *srb, struct us_data* us) } else /* no scatter-gather, just make the request */ - result = us_transfer_partial(us, srb->request_buffer, + result = usb_stor_transfer_partial(us, srb->request_buffer, transfer_amount); /* return the result in the data structure itself */ @@ -824,8 +831,9 @@ void usb_stor_CBI_irq(struct urb *urb) /* was this a wanted interrupt? */ - if (us->ip_wanted) { - us->ip_wanted = 0; + if (atomic_read(us->ip_wanted)) { + atomic_set(us->ip_wanted, 0); + US_DEBUGP("-- Current value of ip_waitq is: %d\n", atomic_read(&us->ip_waitq.count)); up(&(us->ip_waitq)); } else US_DEBUGP("ERROR: Unwanted interrupt received!\n"); @@ -838,7 +846,11 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) int result; /* Set up for status notification */ - us->ip_wanted = 1; + atomic_set(us->ip_wanted, 1); + + /* re-initialize the mutex so that we avoid any races with + * early/late IRQs from previous commands */ + init_MUTEX_LOCKED(&(us->ip_waitq)); /* COMMAND STAGE */ /* let's send the command via the control pipe */ @@ -851,7 +863,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) US_DEBUGP("Call to usb_stor_control_msg() returned %d\n", result); if (result < 0) { /* Reset flag for status notification */ - us->ip_wanted = 0; + atomic_set(us->ip_wanted, 0); /* if the command was aborted, indicate that */ if (result == -ENOENT) @@ -873,15 +885,12 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) /* DATA STAGE */ /* transfer the data payload for this command, if one exists*/ - if (us_transfer_length(srb)) { + if (usb_stor_transfer_length(srb)) { us_transfer(srb, us); US_DEBUGP("CBI data stage result is 0x%x\n", srb->result); /* if it was aborted, we need to indicate that */ if (srb->result == USB_STOR_TRANSPORT_ABORTED) { - /* we need to reset the state of this semaphore */ - down(&(us->ip_waitq)); - return USB_STOR_TRANSPORT_ABORTED; } } @@ -889,12 +898,13 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) /* STATUS STAGE */ /* go to sleep until we get this interrupt */ + US_DEBUGP("Current value of ip_waitq is: %d\n", atomic_read(&us->ip_waitq.count)); down(&(us->ip_waitq)); /* if we were woken up by an abort instead of the actual interrupt */ - if (us->ip_wanted) { + if (atomic_read(us->ip_wanted)) { US_DEBUGP("Did not get interrupt on CBI\n"); - us->ip_wanted = 0; + atomic_set(us->ip_wanted, 0); return USB_STOR_TRANSPORT_ABORTED; } @@ -978,7 +988,7 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us) /* DATA STAGE */ /* transfer the data payload for this command, if one exists*/ - if (us_transfer_length(srb)) { + if (usb_stor_transfer_length(srb)) { us_transfer(srb, us); US_DEBUGP("CB data stage result is 0x%x\n", srb->result); @@ -1039,10 +1049,14 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) int result; int pipe; int partial; + + /* if the device was removed, then we're already reset */ + if (!us->pusb_dev) + return SUCCESS; /* set up the command wrapper */ bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb.DataTransferLength = cpu_to_le32(us_transfer_length(srb)); + bcb.DataTransferLength = cpu_to_le32(usb_stor_transfer_length(srb)); bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0; bcb.Tag = srb->serial_number; bcb.Lun = srb->cmnd[1] >> 5; @@ -1182,6 +1196,10 @@ int usb_stor_CB_reset(struct us_data *us) US_DEBUGP("CB_reset() called\n"); + /* if the device was removed, then we're already reset */ + if (!us->pusb_dev) + return SUCCESS; + memset(cmd, 0xFF, sizeof(cmd)); cmd[0] = SEND_DIAGNOSTIC; cmd[1] = 4; @@ -1220,6 +1238,10 @@ int usb_stor_Bulk_reset(struct us_data *us) US_DEBUGP("Bulk reset requested\n"); + /* if the device was removed, then we're already reset */ + if (!us->pusb_dev) + return SUCCESS; + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_BULK_RESET_REQUEST, diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 7590f17c9..df6719cdf 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -1,7 +1,7 @@ /* Driver for USB Mass Storage compliant devices * Transport Functions Header File * - * $Id: transport.h,v 1.12 2000/09/08 21:20:06 mdharm Exp $ + * $Id: transport.h,v 1.13 2000/10/03 01:06:07 mdharm Exp $ * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) @@ -136,8 +136,11 @@ extern int usb_stor_Bulk_transport(Scsi_Cmnd*, struct us_data*); extern int usb_stor_Bulk_max_lun(struct us_data*); extern int usb_stor_Bulk_reset(struct us_data*); -void usb_stor_invoke_transport(Scsi_Cmnd *, struct us_data *); - -extern int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us); - +extern unsigned int usb_stor_transfer_length(Scsi_Cmnd*); +extern void usb_stor_invoke_transport(Scsi_Cmnd*, struct us_data*); +extern int usb_stor_transfer_partial(struct us_data*, char*, int); +extern int usb_stor_bulk_msg(struct us_data*, void*, int, unsigned int, + unsigned int*); +extern int usb_stor_control_msg(struct us_data*, unsigned int, u8, u8, + u16, u16, void*, u16); #endif diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 2af32768f..8d41b1c0c 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -1,6 +1,6 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: usb.c,v 1.46 2000/09/25 23:25:12 mdharm Exp $ + * $Id: usb.c,v 1.51 2000/10/19 18:49:51 mdharm Exp $ * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) @@ -473,21 +473,27 @@ static struct us_unusual_dev us_unusual_dev_list[] = { { 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk", - "ImageMate SDDR05a", + "ImageMate SDDR-05a", US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN | US_FL_START_STOP}, + { 0x0781, 0x0100, 0x0100, 0x0100, + "Sandisk", + "ImageMate SDDR-12", + US_SC_SCSI, US_PR_CB, NULL, + US_FL_SINGLE_LUN }, + #ifdef CONFIG_USB_STORAGE_SDDR09 { 0x0781, 0x0200, 0x0100, 0x0100, "Sandisk", - "ImageMate SDDR09", + "ImageMate SDDR-09", US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, US_FL_SINGLE_LUN | US_FL_START_STOP }, #endif { 0x0781, 0x0002, 0x0009, 0x0009, "Sandisk", - "ImageMate SDDR31", + "ImageMate SDDR-31", US_SC_SCSI, US_PR_BULK, NULL, US_FL_IGNORE_SER}, @@ -696,19 +702,20 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) US_DEBUGP("Endpoints: In: 0x%p Out: 0x%p Int: 0x%p (Period %d)\n", ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0); - /* set the interface -- STALL is an acceptable response here */ #ifdef CONFIG_USB_STORAGE_SDDR09 - if (protocol == US_PR_EUSB_SDDR09) + if (protocol == US_PR_EUSB_SDDR09 || protocol == US_PR_DPCM_USB) { + /* set the configuration -- STALL is an acceptable response here */ result = usb_set_configuration(dev, 1); - US_DEBUGP("Result from usb_set_configuration is %d\n", result); - if (result == -EPIPE) { - US_DEBUGP("-- clearing stall on control interface\n"); - usb_clear_halt(dev, usb_sndctrlpipe(dev, 0)); - } else if (result != 0) { - /* it's not a stall, but another error -- time to bail */ - US_DEBUGP("-- Unknown error. Rejecting device\n"); - return NULL; + US_DEBUGP("Result from usb_set_configuration is %d\n", result); + if (result == -EPIPE) { + US_DEBUGP("-- clearing stall on control interface\n"); + usb_clear_halt(dev, usb_sndctrlpipe(dev, 0)); + } else if (result != 0) { + /* it's not a stall, but another error -- time to bail */ + US_DEBUGP("-- Unknown error. Rejecting device\n"); + return NULL; + } } #endif @@ -759,6 +766,9 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) US_DEBUGP("Found existing GUID " GUID_FORMAT "\n", GUID_ARGS(guid)); + /* lock the device pointers */ + down(&(ss->dev_semaphore)); + /* establish the connection to the new device upon reconnect */ ss->ifnum = ifnum; ss->pusb_dev = dev; @@ -773,13 +783,15 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) ss->ep_int = ep_int; /* allocate an IRQ callback if one is needed */ - if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) + if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) { + usb_dec_dev_use(dev); return NULL; + } /* allocate the URB we're going to use */ ss->current_urb = usb_alloc_urb(0); if (!ss->current_urb) { - kfree(ss); + usb_dec_dev_use(dev); return NULL; } @@ -787,6 +799,9 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) if (unusual_dev && unusual_dev->initFunction) (unusual_dev->initFunction)(ss); + /* unlock the device pointers */ + up(&(ss->dev_semaphore)); + } else { /* New device -- allocate memory and initialize */ US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid)); @@ -794,6 +809,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), GFP_KERNEL)) == NULL) { printk(KERN_WARNING USB_STORAGE "Out of memory\n"); + usb_dec_dev_use(dev); return NULL; } memset(ss, 0, sizeof(struct us_data)); @@ -802,6 +818,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) ss->current_urb = usb_alloc_urb(0); if (!ss->current_urb) { kfree(ss); + usb_dec_dev_use(dev); return NULL; } @@ -924,6 +941,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) ss->transport_name = "Unknown"; kfree(ss->current_urb); kfree(ss); + usb_dec_dev_use(dev); return NULL; break; } @@ -977,8 +995,10 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) US_DEBUGP("Protocol: %s\n", ss->protocol_name); /* allocate an IRQ callback if one is needed */ - if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) + if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) { + usb_dec_dev_use(dev); return NULL; + } /* * Since this is a new device, we need to generate a scsi @@ -1011,6 +1031,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) "Unable to start control thread\n"); kfree(ss->current_urb); kfree(ss); + usb_dec_dev_use(dev); return NULL; } diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 2abb34396..342e94a4e 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -1,7 +1,7 @@ /* Driver for USB Mass Storage compliant devices * Main Header File * - * $Id: usb.h,v 1.9 2000/09/25 23:25:12 mdharm Exp $ + * $Id: usb.h,v 1.10 2000/10/19 18:44:11 mdharm Exp $ * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) @@ -160,7 +160,7 @@ struct us_data { /* interrupt info for CBI devices -- only good if attached */ struct semaphore ip_waitq; /* for CBI interrupts */ - int ip_wanted; /* is an IRQ expected? */ + atomic_t ip_wanted[1]; /* is an IRQ expected? */ /* interrupt communications data */ struct semaphore irq_urb_sem; /* to protect irq_urb */ diff --git a/drivers/usb/usb-core.c b/drivers/usb/usb-core.c deleted file mode 100644 index 8e2dd4da5..000000000 --- a/drivers/usb/usb-core.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * driver/usb/usb-core.c - * - * (C) Copyright David Waite 1999 - * based on code from usb.c, by Linus Torvalds - * - * The purpose of this file is to pull any and all generic modular code from - * usb.c and put it in a separate file. This way usb.c is kept as a generic - * library, while this file handles starting drivers, etc. - * - */ - -#include <linux/version.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/usb.h> - -/* - * USB core - */ - -int usb_hub_init(void); -void usb_hub_cleanup(void); -int usb_major_init(void); -void usb_major_cleanup(void); - - -/* - * Cleanup - */ - -static void __exit usb_exit(void) -{ - usb_major_cleanup(); - usbdevfs_cleanup(); - usb_hub_cleanup(); -} - -/* - * Init - */ - -static int __init usb_init(void) -{ - usb_major_init(); - usbdevfs_init(); - usb_hub_init(); - - return 0; -} - -module_init(usb_init); -module_exit(usb_exit); diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c index 4fb391a8b..2105cb595 100644 --- a/drivers/usb/usb-ohci.c +++ b/drivers/usb/usb-ohci.c @@ -64,6 +64,8 @@ #define OHCI_USE_NPS // force NoPowerSwitching mode // #define OHCI_VERBOSE_DEBUG /* not always helpful */ +// #define OHCI_MEM_SLAB +// #define OHCI_MEM_FLAGS SLAB_POISON /* no redzones; see mm/slab.c */ #include "usb-ohci.h" @@ -95,13 +97,13 @@ static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED; /* free HCD-private data associated with this URB */ -static void urb_free_priv (urb_priv_t * urb_priv) +static void urb_free_priv (struct ohci *hc, urb_priv_t * urb_priv) { int i; for (i = 0; i < urb_priv->length; i++) { if (urb_priv->td [i]) { - OHCI_FREE (urb_priv->td [i]); + td_free (hc, urb_priv->td [i]); } } @@ -129,7 +131,7 @@ static void urb_rm_priv_locked (urb_t * urb) } } - urb_free_priv (urb_priv); + urb_free_priv ((struct ohci *)urb->dev->bus, urb_priv); usb_dec_dev_use (urb->dev); urb->dev = NULL; } @@ -531,16 +533,16 @@ static int sohci_submit_urb (urb_t * urb) /* allocate the TDs */ for (i = 0; i < size; i++) { - OHCI_ALLOC (urb_priv->td[i], sizeof (td_t)); + urb_priv->td[i] = td_alloc (ohci); if (!urb_priv->td[i]) { - urb_free_priv (urb_priv); + urb_free_priv (ohci, urb_priv); usb_dec_dev_use (urb->dev); return -ENOMEM; } } if (ed->state == ED_NEW || (ed->state & ED_DEL)) { - urb_free_priv (urb_priv); + urb_free_priv (ohci, urb_priv); usb_dec_dev_use (urb->dev); return -EINVAL; } @@ -561,7 +563,7 @@ static int sohci_submit_urb (urb_t * urb) bustime = usb_check_bandwidth (urb->dev, urb); } if (bustime < 0) { - urb_free_priv (urb_priv); + urb_free_priv (ohci, urb_priv); usb_dec_dev_use (urb->dev); return bustime; } @@ -683,7 +685,11 @@ static int sohci_alloc_dev (struct usb_device *usb_dev) { struct ohci_device * dev; - dev = kmalloc (sizeof (*dev), GFP_KERNEL); + /* FIXME: ED allocation with pci_consistent memory + * must know the controller ... either pass it in here, + * or decouple ED allocation from dev allocation. + */ + dev = dev_alloc (NULL); if (!dev) return -ENOMEM; @@ -772,7 +778,9 @@ static int sohci_free_dev (struct usb_device * usb_dev) } } } - kfree (dev); + + /* free device, and associated EDs */ + dev_free (dev); return 0; } @@ -1077,7 +1085,8 @@ static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int int if (ed->state == ED_NEW) { ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ - OHCI_ALLOC (td, sizeof (*td)); /* dummy td; end of td list for ed */ + /* dummy td; end of td list for ed */ + td = td_alloc (ohci); if (!td) { /* out of memory */ spin_unlock_irqrestore (&usb_ed_lock, flags); @@ -1425,7 +1434,7 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame) if (ed->state & ED_DEL) { /* set by sohci_free_dev */ struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO & 0x7F]); - OHCI_FREE (tdTailP); /* free dummy td */ + td_free (ohci, tdTailP); /* free dummy td */ ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); ed->state = ED_NEW; /* if all eds are removed wake up sohci_free_dev */ @@ -1443,7 +1452,7 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame) if (tdHeadP == tdTailP) { if (ed->state == ED_OPER) ep_unlink(ohci, ed); - OHCI_FREE (tdTailP); + td_free (ohci, tdTailP); ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); ed->state = ED_NEW; --(usb_to_ohci (ohci->dev[edINFO & 0x7F]))->ed_cnt; @@ -2536,15 +2545,23 @@ static struct pmu_sleep_notifier ohci_sleep_notifier = { }; #endif /* CONFIG_PMAC_PBOOK */ + /*-------------------------------------------------------------------------*/ static int __init ohci_hcd_init (void) { - int ret = pci_module_init (&ohci_pci_driver); + int ret; + + if ((ret = ohci_mem_init ()) < 0) + return ret; + + if ((ret = pci_module_init (&ohci_pci_driver)) < 0) { + ohci_mem_cleanup (); + return ret; + } #ifdef CONFIG_PMAC_PBOOK - if (ret >= 0) - pmu_register_sleep_notifier (&ohci_sleep_notifier); + pmu_register_sleep_notifier (&ohci_sleep_notifier); #endif return ret; } @@ -2557,6 +2574,7 @@ static void __exit ohci_hcd_cleanup (void) pmu_unregister_sleep_notifier (&ohci_sleep_notifier); #endif pci_unregister_driver (&ohci_pci_driver); + ohci_mem_cleanup (); } module_init (ohci_hcd_init); diff --git a/drivers/usb/usb-ohci.h b/drivers/usb/usb-ohci.h index 086db1a12..349e4cda4 100644 --- a/drivers/usb/usb-ohci.h +++ b/drivers/usb/usb-ohci.h @@ -30,10 +30,6 @@ static int cc_to_error[16] = { }; -struct ed; -struct td; -/* for ED and TD structures */ - /* ED States */ #define ED_NEW 0x00 @@ -406,12 +402,100 @@ static int rh_submit_urb(urb_t * urb); static int rh_unlink_urb(urb_t * urb); static int rh_init_int_timer(urb_t * urb); -#ifdef OHCI_VERBOSE_DEBUG -#define OHCI_FREE(x) kfree(x); printk("OHCI FREE: %d: %4x\n", -- __ohci_free_cnt, (unsigned int) x) -#define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); printk("OHCI ALLO: %d: %4x\n", ++ __ohci_free_cnt,(unsigned int) x) -static int __ohci_free_cnt = 0; +/*-------------------------------------------------------------------------*/ + +#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL) + +#ifdef OHCI_MEM_SLAB +#define __alloc(t,c) kmem_cache_alloc(c,ALLOC_FLAGS) +#define __free(c,x) kmem_cache_free(c,x) +static kmem_cache_t *td_cache, *ed_cache; + +/* + * WARNING: do NOT use this with "forced slab debug"; it won't respect + * our hardware alignment requirement. + */ +#ifndef OHCI_MEM_FLAGS +#define OHCI_MEM_FLAGS 0 +#endif + +static int ohci_mem_init (void) +{ + /* redzoning (or forced debug!) breaks alignment */ + int flags = (OHCI_MEM_FLAGS) & ~SLAB_RED_ZONE; + + /* TDs accessed by controllers and host */ + td_cache = kmem_cache_create ("ohci_td", sizeof (struct td), 0, + flags | SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!td_cache) { + dbg ("no TD cache?"); + return -ENOMEM; + } + + /* EDs are accessed by controllers and host; dev part is host-only */ + ed_cache = kmem_cache_create ("ohci_ed", sizeof (struct ohci_device), 0, + flags | SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!ed_cache) { + dbg ("no ED cache?"); + kmem_cache_destroy (td_cache); + td_cache = 0; + return -ENOMEM; + } + dbg ("slab flags 0x%x", flags); + return 0; +} + +static void ohci_mem_cleanup (void) +{ + if (ed_cache && kmem_cache_destroy (ed_cache)) + err ("ed_cache remained"); + ed_cache = 0; + + if (td_cache && kmem_cache_destroy (td_cache)) + err ("td_cache remained"); + td_cache = 0; +} + #else -#define OHCI_FREE(x) kfree(x) -#define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) +#define __alloc(t,c) kmalloc(sizeof(t),ALLOC_FLAGS) +#define __free(dev,x) kfree(x) +#define td_cache 0 +#define ed_cache 0 + +static inline int ohci_mem_init (void) { return 0; } +static inline void ohci_mem_cleanup (void) { return; } + +/* FIXME: pci_consistent version */ + #endif - + + +/* TDs ... */ +static inline struct td * +td_alloc (struct ohci *hc) +{ + struct td *td = (struct td *) __alloc (struct td, td_cache); + return td; +} + +static inline void +td_free (struct ohci *hc, struct td *td) +{ + __free (td_cache, td); +} + + +/* DEV + EDs ... only the EDs need to be consistent */ +static inline struct ohci_device * +dev_alloc (struct ohci *hc) +{ + struct ohci_device *dev = (struct ohci_device *) + __alloc (struct ohci_device, ed_cache); + return dev; +} + +static inline void +dev_free (struct ohci_device *dev) +{ + __free (ed_cache, dev); +} diff --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c index fbed8c158..4834f25cf 100644 --- a/drivers/usb/usb-uhci.c +++ b/drivers/usb/usb-uhci.c @@ -12,7 +12,7 @@ * (C) Copyright 1999 Johannes Erdfelt * (C) Copyright 1999 Randy Dunlap * - * $Id: usb-uhci.c,v 1.239 2000/09/19 20:15:12 acher Exp $ + * $Id: usb-uhci.c,v 1.242 2000/10/05 21:19:49 acher Exp $ */ #include <linux/config.h> @@ -48,7 +48,7 @@ /* This enables an extra UHCI slab for memory debugging */ #define DEBUG_SLAB -#define VERSTR "$Revision: 1.239 $ time " __TIME__ " " __DATE__ +#define VERSTR "$Revision: 1.242 $ time " __TIME__ " " __DATE__ #include <linux/usb.h> #include "usb-uhci.h" @@ -2563,6 +2563,8 @@ _static int process_urb (uhci_t *s, struct list_head *p) uhci_submit_urb (urb); } } + else if (!urb->complete) + urb->dev = NULL; if (proceed && urb->next) { // if there are linked urbs - handle submitting of them right now. @@ -2577,12 +2579,15 @@ _static int process_urb (uhci_t *s, struct list_head *p) if (urb->complete) { dbg("process_transfer: calling completion"); - urb->dev=NULL; + if (urb->status!=-EINPROGRESS) + urb->dev=NULL; urb->complete ((struct urb *) urb); } + else + if (urb->status!=-EINPROGRESS) + urb->dev=NULL; } - urb->dev=NULL; // Just in case no completion was called usb_dec_dev_use (usb_dev); spin_unlock(&urb->lock); spin_lock(&s->urb_list_lock); diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index df469e7d8..7e59346aa 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -26,6 +26,7 @@ #include <linux/malloc.h> #include <linux/interrupt.h> /* for in_interrupt() */ #include <linux/kmod.h> +#include <linux/init.h> #ifdef CONFIG_USB_DEBUG @@ -47,6 +48,9 @@ static const int usb_bandwidth_option = 0; #endif +extern int usb_hub_init(void); +extern void usb_hub_cleanup(void); + /* * Prototypes for the device driver probing/loading functions */ @@ -462,6 +466,10 @@ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interfac * We now walk the list of registered USB drivers, * looking for one that will accept this interface. * + * "New Style" drivers use a table describing the devices and interfaces + * they handle. Those tables are available to user mode tools deciding + * whether to load driver modules for a new device. + * * The probe return value is changed to be a private pointer. This way * the drivers don't have to dig around in our structures to set the * private pointer if they only need one interface. @@ -490,7 +498,70 @@ static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) tmp = tmp->next; down(&driver->serialize); - private = driver->probe(dev, ifnum); + + /* new style driver? */ + if (driver->bind) { + const struct usb_device_id *id = driver->id_table; + + if (id) { + /* scan device ids for a match */ + for (;; id++) { + struct usb_interface_descriptor *intf = 0; + + /* done? */ + if (!id->idVendor && !id->bDeviceClass && !id->bInterfaceClass) { + id = 0; + break; + } + + /* Vendor match, possibly product-specific? */ + if (id->idVendor && id->idVendor == dev->descriptor.idVendor) { + if (id->idProduct && id->idProduct != dev->descriptor.idProduct) + continue; + break; + } + + /* Device class match? */ + if (id->bDeviceClass + && id->bDeviceClass == dev->descriptor.bDeviceClass) { + if (id->bDeviceSubClass && id->bDeviceSubClass + != dev->descriptor.bDeviceClass) + continue; + if (id->bDeviceProtocol && id->bDeviceProtocol + != dev->descriptor.bDeviceProtocol) + continue; + break; + } + + /* Interface class match? */ + if (!interface->altsetting || interface->num_altsetting < 1) + continue; + intf = &interface->altsetting [0]; + if (id->bInterfaceClass + && id->bInterfaceClass == intf->bInterfaceClass) { + if (id->bInterfaceSubClass && id->bInterfaceSubClass + != intf->bInterfaceClass) + continue; + if (id->bInterfaceProtocol && id->bInterfaceProtocol + != intf->bInterfaceProtocol) + continue; + break; + } + } + + /* is this driver interested in this interface? */ + if (id) + private = driver->bind(dev, ifnum, id); + else + private = 0; + } else { + /* "old style" driver, but using new interface */ + private = driver->bind(dev, ifnum, 0); + } + + /* "old style" driver */ + } else + private = driver->probe(dev, ifnum); up(&driver->serialize); if (!private) continue; @@ -758,6 +829,7 @@ void usb_inc_dev_use(struct usb_device *dev) { atomic_inc(&dev->refcnt); } + /* ------------------------------------------------------------------------------------- * New USB Core Functions * -------------------------------------------------------------------------------------*/ @@ -836,7 +908,6 @@ static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length) int status; awd.wakeup = &wqh; - awd.handler = 0; init_waitqueue_head(&wqh); current->state = TASK_INTERRUPTIBLE; add_wait_queue(&wqh, &wait); @@ -1518,9 +1589,9 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char while (i--) { if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) >= 0 || + (type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) > 0 || result == -EPIPE) - break; + break; /* retry if the returned length was 0; flaky device */ } return result; } @@ -2029,6 +2100,32 @@ struct list_head *usb_bus_get_list(void) } #endif + +/* + * Init + */ +static int __init usb_init(void) +{ + usb_major_init(); + usbdevfs_init(); + usb_hub_init(); + + return 0; +} + +/* + * Cleanup + */ +static void __exit usb_exit(void) +{ + usb_major_cleanup(); + usbdevfs_cleanup(); + usb_hub_cleanup(); +} + +module_init(usb_init); +module_exit(usb_exit); + /* * USB may be built into the kernel or be built as modules. * If the USB core [and maybe a host controller driver] is built diff --git a/drivers/usb/usbmouse.c b/drivers/usb/usbmouse.c index 39df8e5e0..1e873b285 100644 --- a/drivers/usb/usbmouse.c +++ b/drivers/usb/usbmouse.c @@ -43,6 +43,7 @@ struct usb_mouse { char name[128]; struct input_dev dev; struct urb irq; + struct usb_device *my_usb_device; // for resubmitting my urb int open; }; @@ -72,6 +73,7 @@ static int usb_mouse_open(struct input_dev *dev) if (mouse->open++) return 0; + mouse->irq.dev = mouse->my_usb_device; if (usb_submit_urb(&mouse->irq)) return -EIO; @@ -148,6 +150,7 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum) kfree(buf); + mouse->my_usb_device = dev; FILL_INT_URB(&mouse->irq, dev, pipe, mouse->data, maxp > 8 ? 8 : maxp, usb_mouse_irq, mouse, endpoint->bInterval); diff --git a/drivers/usb/wacom.c b/drivers/usb/wacom.c index b74a003e8..4dcc86436 100644 --- a/drivers/usb/wacom.c +++ b/drivers/usb/wacom.c @@ -117,6 +117,7 @@ struct wacom_features { struct wacom { signed char data[10]; struct input_dev dev; + struct usb_device *usbdev; struct urb irq; struct wacom_features *features; int tool; @@ -239,6 +240,7 @@ static int wacom_open(struct input_dev *dev) if (wacom->open++) return 0; + wacom->irq.dev = wacom->usbdev; if (usb_submit_urb(&wacom->irq)) return -EIO; @@ -293,6 +295,7 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum) wacom->dev.idvendor = dev->descriptor.idVendor; wacom->dev.idproduct = dev->descriptor.idProduct; wacom->dev.idversion = dev->descriptor.bcdDevice; + wacom->usbdev = dev; FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), wacom->data, wacom->features->pktlen, wacom->features->irq, wacom, endpoint->bInterval); diff --git a/drivers/video/clgenfb.c b/drivers/video/clgenfb.c index e38198485..57626f05c 100644 --- a/drivers/video/clgenfb.c +++ b/drivers/video/clgenfb.c @@ -997,10 +997,10 @@ static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par, vsync *= 2; vback *= 2; } else if (_par->var.vmode & FB_VMODE_INTERLACED) { - yres = ++yres / 2; - vfront = ++vfront / 2; - vsync = ++vsync / 2; - vback = ++vback / 2; + yres = (yres + 1) / 2; + vfront = (vfront + 1) / 2; + vsync = (vsync + 1) / 2; + vback = (vback + 1) / 2; } _par->HorizRes = xres; _par->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5; diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index 1e06548b3..fe64ab9a1 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c @@ -1190,7 +1190,7 @@ static void control_set_dispsw(struct display *disp, int cmode, struct fb_info_c } } -static void control_init_info(struct fb_info *info, struct fb_info_control *p) +static void __init control_init_info(struct fb_info *info, struct fb_info_control *p) { strcpy(info->modename, "control"); info->node = -1; /* ??? danj */ diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c index bd7618def..5c4af6bf0 100644 --- a/drivers/video/cyberfb.c +++ b/drivers/video/cyberfb.c @@ -1070,7 +1070,6 @@ int __init cyberfb_init(void) release_mem_region(CyberRegs_phys, 0x10000); continue; } - strcpy(z->name, "CyberVision64 Graphics Board"); DPRINTK("board_addr=%08lx\n", board_addr); DPRINTK("board_size=%08lx\n", board_size); diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c index 2deaeca27..f7a5ffba3 100644 --- a/drivers/video/dnfb.c +++ b/drivers/video/dnfb.c @@ -296,7 +296,7 @@ static void dn_fb_set_disp(int con, struct fb_info *info) { } -unsigned long dnfb_init(unsigned long mem_start) { +unsigned long __init dnfb_init(unsigned long mem_start) { int err; diff --git a/drivers/video/dummycon.c b/drivers/video/dummycon.c index ee14ed409..3e08ebcb2 100644 --- a/drivers/video/dummycon.c +++ b/drivers/video/dummycon.c @@ -53,7 +53,7 @@ static int dummycon_dummy(void) * Most of the operations are dummies. */ -struct consw dummy_con = { +const struct consw dummy_con = { con_startup: dummycon_startup, con_init: dummycon_init, con_deinit: DUMMY, diff --git a/drivers/video/fbcon.c b/drivers/video/fbcon.c index c559afcca..32935dfc3 100644 --- a/drivers/video/fbcon.c +++ b/drivers/video/fbcon.c @@ -1907,12 +1907,13 @@ static unsigned long fbcon_getxy(struct vc_data *conp, unsigned long pos, int *p y += softback_lines; ret = pos + (conp->vc_cols - x) * 2; } else if (conp->vc_num == fg_console && softback_lines) { - unsigned long offset = (pos - softback_curr) / 2; + unsigned long offset = pos - softback_curr; + if (pos < softback_curr) + offset += softback_end - softback_buf; + offset /= 2; x = offset % conp->vc_cols; y = offset / conp->vc_cols; - if (pos < softback_curr) - y += (softback_end - softback_buf) / conp->vc_size_row; ret = pos + (conp->vc_cols - x) * 2; if (ret == softback_end) ret = softback_buf; @@ -2384,7 +2385,7 @@ static int __init fbcon_show_logo( void ) * The console `switch' structure for the frame buffer based console */ -struct consw fb_con = { +const struct consw fb_con = { con_startup: fbcon_startup, con_init: fbcon_init, con_deinit: fbcon_deinit, diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 015b8b946..7b3d49822 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -618,7 +618,7 @@ int GET_FB_IDX(kdev_t rdev) int fbidx = MINOR(rdev); if (fbidx >= 32) { int newfbidx = fbidx >> 5; - static int warned = 0; + static int warned; if (!(warned & (1<<newfbidx))) { warned |= 1<<newfbidx; printk("Warning: Remapping obsolete /dev/fb* minor %d to %d\n", @@ -679,7 +679,7 @@ static struct file_operations fb_fops = { release: fb_release, }; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; int register_framebuffer(struct fb_info *fb_info) diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c index a5c173aa2..78538935a 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/macfb.c @@ -839,7 +839,7 @@ static struct fb_ops macfb_ops = { fb_set_cmap: macfb_set_cmap, }; -void macfb_setup(char *options, int *ints) +void __init macfb_setup(char *options, int *ints) { char *this_opt; diff --git a/drivers/video/mdacon.c b/drivers/video/mdacon.c index aac8c4ab9..d988d9e39 100644 --- a/drivers/video/mdacon.c +++ b/drivers/video/mdacon.c @@ -37,6 +37,7 @@ #include <linux/vt_kern.h> #include <linux/vt_buffer.h> #include <linux/selection.h> +#include <linux/spinlock.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/init.h> @@ -44,6 +45,7 @@ #include <asm/io.h> #include <asm/vga.h> +static spinlock_t mda_lock = SPIN_LOCK_UNLOCKED; /* description of the hardware layout */ @@ -80,7 +82,6 @@ MODULE_PARM(mda_first_vc, "1-255i"); MODULE_PARM(mda_last_vc, "1-255i"); #endif - /* MDA register values */ @@ -110,39 +111,38 @@ static void write_mda_b(unsigned int val, unsigned char reg) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&mda_lock, flags); outb_p(reg, mda_index_port); outb_p(val, mda_value_port); - restore_flags(flags); + spin_unlock_irqrestore(&mda_lock, flags); } static void write_mda_w(unsigned int val, unsigned char reg) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&mda_lock, flags); outb_p(reg, mda_index_port); outb_p(val >> 8, mda_value_port); outb_p(reg+1, mda_index_port); outb_p(val & 0xff, mda_value_port); - restore_flags(flags); + spin_unlock_irqrestore(&mda_lock, flags); } static int test_mda_b(unsigned char val, unsigned char reg) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&mda_lock, flags); outb_p(reg, mda_index_port); outb (val, mda_value_port); udelay(20); val = (inb_p(mda_value_port) == val); - restore_flags(flags); - + spin_unlock_irqrestore(&mda_lock, flags); return val; } @@ -422,7 +422,8 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, static void mdacon_invert_region(struct vc_data *c, u16 *p, int count) { for (; count > 0; count--) { - scr_writew(scr_readw(p) ^ 0x0800, p++); + scr_writew(scr_readw(p) ^ 0x0800, p); + p++; } } @@ -585,7 +586,7 @@ static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines) * The console `switch' structure for the MDA based console */ -struct consw mda_con = { +const struct consw mda_con = { con_startup: mdacon_startup, con_init: mdacon_init, con_deinit: mdacon_deinit, diff --git a/drivers/video/newport_con.c b/drivers/video/newport_con.c index da99d78a1..4e056d2ea 100644 --- a/drivers/video/newport_con.c +++ b/drivers/video/newport_con.c @@ -574,7 +574,7 @@ static int newport_dummy(struct vc_data *c) #define DUMMY (void *) newport_dummy -struct consw newport_con = { +const struct consw newport_con = { con_startup: newport_startup, con_init: newport_init, con_deinit: DUMMY, diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 81b08345e..1a1b7a3db 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -369,7 +369,7 @@ static void __init offb_init_nodriver(struct device_node *dp) } -static void offb_init_fb(const char *name, const char *full_name, +static void __init offb_init_fb(const char *name, const char *full_name, int width, int height, int depth, int pitch, unsigned long address, struct device_node *dp) diff --git a/drivers/video/promcon.c b/drivers/video/promcon.c index 9715ae881..9c7277b70 100644 --- a/drivers/video/promcon.c +++ b/drivers/video/promcon.c @@ -566,7 +566,7 @@ static int promcon_dummy(void) #define DUMMY (void *) promcon_dummy -struct consw prom_con = { +const struct consw prom_con = { con_startup: promcon_startup, con_init: promcon_init, con_deinit: promcon_deinit, diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c index 2b798e05d..a5c68f070 100644 --- a/drivers/video/q40fb.c +++ b/drivers/video/q40fb.c @@ -313,7 +313,7 @@ static void q40fb_set_disp(int con, struct fb_info *info) #endif } -int q40fb_init(void) +int __init q40fb_init(void) { if ( !MACH_IS_Q40) diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c index ef39926ab..13e843c3d 100644 --- a/drivers/video/retz3fb.c +++ b/drivers/video/retz3fb.c @@ -1391,7 +1391,6 @@ int __init retz3fb_init(void) release_mem_region(board_addr, 0x00c00000); continue; } - strcpy(z->name, "Retina Z3 Graphics "); if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info), GFP_KERNEL))) return -ENOMEM; diff --git a/drivers/video/sisfb.c b/drivers/video/sisfb.c index 85c8f1730..c2d460b99 100644 --- a/drivers/video/sisfb.c +++ b/drivers/video/sisfb.c @@ -3313,7 +3313,7 @@ static struct fb_ops sisfb_ops = { fb_mmap: sisfb_mmap, }; -int sisfb_setup(char *options) +int __init sisfb_setup(char *options) { char *this_opt; diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c index 3723325be..87936fc0a 100644 --- a/drivers/video/sun3fb.c +++ b/drivers/video/sun3fb.c @@ -334,7 +334,7 @@ static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, * Setup: parse used options */ -__initfunc(void sun3fb_setup(char *options)) +void __init sun3fb_setup(char *options) { char *p; @@ -521,7 +521,7 @@ void sun3fb_palette(int enter) /* * Initialisation */ -__initfunc(static void sun3fb_init_fb(int fbtype, unsigned long addr)) +static void __init sun3fb_init_fb(int fbtype, unsigned long addr) { static struct linux_sbus_device sdb; struct fb_fix_screeninfo *fix; @@ -648,7 +648,7 @@ sizechange: } -__initfunc(int sun3fb_init(void)) +int __init sun3fb_init(void) { extern int con_is_present(void); unsigned long addr; diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index fa19c744d..11e803273 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -448,7 +448,7 @@ static struct fb_ops vesafb_ops = { fb_pan_display: vesafb_pan_display, }; -int vesafb_setup(char *options) +int __init vesafb_setup(char *options) { char *this_opt; diff --git a/drivers/video/vgacon.c b/drivers/video/vgacon.c index 5ebfec7b0..8a7e0a0ff 100644 --- a/drivers/video/vgacon.c +++ b/drivers/video/vgacon.c @@ -1037,7 +1037,7 @@ static int vgacon_dummy(struct vc_data *c) #define DUMMY (void *) vgacon_dummy -struct consw vga_con = { +const struct consw vga_con = { con_startup: vgacon_startup, con_init: vgacon_init, con_deinit: vgacon_deinit, diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c index 6be952607..ed7bad2b1 100644 --- a/drivers/video/virgefb.c +++ b/drivers/video/virgefb.c @@ -1139,7 +1139,6 @@ int __init virgefb_init(void) release_mem_region(CyberRegs_phys, 0x10000); continue; } - strcpy(z->name, "CyberVision64-3D Graphics Board"); if (board_addr < 0x01000000) { /* diff --git a/drivers/zorro/Config.in b/drivers/zorro/Config.in new file mode 100644 index 000000000..dc91f84b4 --- /dev/null +++ b/drivers/zorro/Config.in @@ -0,0 +1,7 @@ +# +# Zorro configuration +# + +if [ "$CONFIG_ZORRO" = "y" ]; then + bool 'Zorro device name database' CONFIG_ZORRO_NAMES +fi diff --git a/drivers/zorro/Makefile b/drivers/zorro/Makefile index 8e14649b2..363e699ea 100644 --- a/drivers/zorro/Makefile +++ b/drivers/zorro/Makefile @@ -23,3 +23,11 @@ endif L_OBJS += names.o include $(TOPDIR)/Rules.make + +names.o: names.c devlist.h + +devlist.h: zorro.ids gen-devlist + ./gen-devlist <zorro.ids + +gen-devlist: gen-devlist.c + $(HOSTCC) $(HOSTCFLAGS) -o gen-devlist gen-devlist.c diff --git a/drivers/zorro/gen-devlist.c b/drivers/zorro/gen-devlist.c new file mode 100644 index 000000000..b0a355945 --- /dev/null +++ b/drivers/zorro/gen-devlist.c @@ -0,0 +1,107 @@ +/* + * Generate devlist.h from the Zorro ID file. + * + * (c) 2000 Geert Uytterhoeven <geert@linux-m68k.org> + * + * Based on the PCI version: + * + * (c) 1999--2000 Martin Mares <mj@suse.cz> + */ + +#include <stdio.h> +#include <string.h> + +#define MAX_NAME_SIZE 63 + +static void +pq(FILE *f, const char *c) +{ + while (*c) { + if (*c == '"') + fprintf(f, "\\\""); + else + fputc(*c, f); + c++; + } +} + +int +main(void) +{ + char line[1024], *c, *bra, manuf[8]; + int manufs = 0; + int mode = 0; + int lino = 0; + int manuf_len = 0; + FILE *devf; + + devf = fopen("devlist.h", "w"); + if (!devf) { + fprintf(stderr, "Cannot create output file!\n"); + return 1; + } + + while (fgets(line, sizeof(line)-1, stdin)) { + lino++; + if ((c = strchr(line, '\n'))) + *c = 0; + if (!line[0] || line[0] == '#') + continue; + if (line[0] == '\t') { + switch (mode) { + case 1: + if (strlen(line) > 5 && line[5] == ' ') { + c = line + 5; + while (*c == ' ') + *c++ = 0; + if (manuf_len + strlen(c) + 1 > MAX_NAME_SIZE) { + /* Too long, try cutting off long description */ + bra = strchr(c, '['); + if (bra && bra > c && bra[-1] == ' ') + bra[-1] = 0; + if (manuf_len + strlen(c) + 1 > MAX_NAME_SIZE) { + fprintf(stderr, "Line %d: Product name too long\n", lino); + return 1; + } + } + fprintf(devf, "\tPRODUCT(%s,%s,\"", manuf, line+1); + pq(devf, c); + fputs("\")\n", devf); + } else goto err; + break; + default: + goto err; + } + } else if (strlen(line) > 4 && line[4] == ' ') { + c = line + 4; + while (*c == ' ') + *c++ = 0; + if (manufs) + fputs("ENDMANUF()\n\n", devf); + manufs++; + strcpy(manuf, line); + manuf_len = strlen(c); + if (manuf_len + 24 > MAX_NAME_SIZE) { + fprintf(stderr, "Line %d: manufacturer name too long\n", lino); + return 1; + } + fprintf(devf, "MANUF(%s,\"", manuf); + pq(devf, c); + fputs("\")\n", devf); + mode = 1; + } else { + err: + fprintf(stderr, "Line %d: Syntax error in mode %d: %s\n", lino, mode, line); + return 1; + } + } + fputs("ENDMANUF()\n\ +\n\ +#undef MANUF\n\ +#undef PRODUCT\n\ +#undef ENDMANUF\n", devf); + + fclose(devf); + + return 0; +} diff --git a/drivers/zorro/names.c b/drivers/zorro/names.c index 2277bcc2b..c7299c891 100644 --- a/drivers/zorro/names.c +++ b/drivers/zorro/names.c @@ -1,83 +1,109 @@ /* - * $Id: zorro.c,v 1.1.2.1 1998/06/07 23:21:02 geert Exp $ + * Zorro Device Name Tables * - * Zorro Expansion Device Names + * Copyright (C) 1999--2000 Geert Uytterhoeven * - * Copyright (C) 1999-2000 Geert Uytterhoeven + * Based on the PCI version: * - * This file is subject to 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 1992--1999 Drew Eckhardt, Frederic Potter, + * David Mosberger-Tang, Martin Mares */ +#include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/zorro.h> - /* - * Just for reference, these are the boards we have a driver for in the - * kernel: - * - * ZORRO_PROD_AMERISTAR_A2065 - * ZORRO_PROD_BSC_FRAMEMASTER_II - * ZORRO_PROD_BSC_MULTIFACE_III - * ZORRO_PROD_BSC_OKTAGON_2008 - * ZORRO_PROD_CBM_A2065_1 - * ZORRO_PROD_CBM_A2065_2 - * ZORRO_PROD_CBM_A4091_1 - * ZORRO_PROD_CBM_A4091_2 - * ZORRO_PROD_CBM_A590_A2091_1 - * ZORRO_PROD_CBM_A590_A2091_2 - * ZORRO_PROD_GVP_A1291 - * ZORRO_PROD_GVP_A530_SCSI - * ZORRO_PROD_GVP_COMBO_030_R3_SCSI - * ZORRO_PROD_GVP_COMBO_030_R4_SCSI - * ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM - * ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG - * ZORRO_PROD_GVP_GFORCE_030_SCSI - * ZORRO_PROD_GVP_GFORCE_040_060 - * ZORRO_PROD_GVP_GFORCE_040_1 - * ZORRO_PROD_GVP_GFORCE_040_SCSI_1 - * ZORRO_PROD_GVP_IO_EXTENDER - * ZORRO_PROD_GVP_SERIES_II - * ZORRO_PROD_HELFRICH_PICCOLO_RAM - * ZORRO_PROD_HELFRICH_PICCOLO_REG - * ZORRO_PROD_HELFRICH_RAINBOW_II - * ZORRO_PROD_HELFRICH_SD64_RAM - * ZORRO_PROD_HELFRICH_SD64_REG - * ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET - * ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA - * ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL - * ZORRO_PROD_MACROSYSTEMS_RETINA_Z3 - * ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx - * ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM - * ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060 - * ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260 - * ZORRO_PROD_PHASE5_BLIZZARD_2060 - * ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS - * ZORRO_PROD_PHASE5_CYBERSTORM_MK_II - * ZORRO_PROD_PHASE5_CYBERVISION64 - * ZORRO_PROD_PHASE5_CYBERVISION64_3D - * ZORRO_PROD_VILLAGE_TRONIC_ARIADNE - * ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2 - * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM - * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG - * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 - * - * And I guess these are automagically supported as well :-) - * - * ZORRO_PROD_CBM_A560_RAM - * ZORRO_PROD_CBM_A590_A2052_A2058_A2091 - */ - -void __init zorro_namedevice(struct zorro_dev *dev) +#ifdef CONFIG_ZORRO_NAMES + +struct zorro_prod_info { + __u16 prod; + unsigned short seen; + const char *name; +}; + +struct zorro_manuf_info { + __u16 manuf; + unsigned short nr; + const char *name; + struct zorro_prod_info *prods; +}; + +/* + * This is ridiculous, but we want the strings in + * the .init section so that they don't take up + * real memory.. Parse the same file multiple times + * to get all the info. + */ +#define MANUF( manuf, name ) static const char __manufstr_##manuf[] __initdata = name; +#define ENDMANUF() +#define PRODUCT( manuf, prod, name ) static const char __prodstr_##manuf##prod[] __initdata = name; +#include "devlist.h" + + +#define MANUF( manuf, name ) static struct zorro_prod_info __prods_##manuf[] __initdata = { +#define ENDMANUF() }; +#define PRODUCT( manuf, prod, name ) { 0x##prod, 0, __prodstr_##manuf##prod }, +#include "devlist.h" + +static const struct zorro_manuf_info __initdata zorro_manuf_list[] = { +#define MANUF( manuf, name ) { 0x##manuf, sizeof(__prods_##manuf) / sizeof(struct zorro_prod_info), __manufstr_##manuf, __prods_##manuf }, +#define ENDMANUF() +#define PRODUCT( manuf, prod, name ) +#include "devlist.h" +}; + +#define MANUFS (sizeof(zorro_manuf_list)/sizeof(struct zorro_manuf_info)) + +void __init zorro_name_device(struct zorro_dev *dev) +{ + const struct zorro_manuf_info *manuf_p = zorro_manuf_list; + int i = MANUFS; + char *name = dev->name; + + do { + if (manuf_p->manuf == ZORRO_MANUF(dev->id)) + goto match_manuf; + manuf_p++; + } while (--i); + + /* Couldn't find either the manufacturer nor the product */ + sprintf(name, "Zorro device %08x", dev->id); + return; + + match_manuf: { + struct zorro_prod_info *prod_p = manuf_p->prods; + int i = manuf_p->nr; + + while (i > 0) { + if (prod_p->prod == + ((ZORRO_PROD(dev->id)<<8) | ZORRO_EPC(dev->id))) + goto match_prod; + prod_p++; + i--; + } + + /* Ok, found the manufacturer, but unknown product */ + sprintf(name, "Zorro device %08x (%s)", dev->id, manuf_p->name); + return; + + /* Full match */ + match_prod: { + char *n = name + sprintf(name, "%s %s", manuf_p->name, prod_p->name); + int nr = prod_p->seen + 1; + prod_p->seen = nr; + if (nr > 1) + sprintf(n, " (#%d)", nr); + } + } +} + +#else + +void __init zorro_name_device(struct zorro_dev *dev) { - /* - * Nah, we're not that stupid to put name databases in the kernel ;-) - * That's why we have zorroutils... - */ - sprintf(dev->name, "Zorro device %08x", dev->id); } +#endif diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index 10ac2eec3..114a27ebb 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c @@ -20,8 +20,6 @@ #include <asm/amigahw.h> -extern void zorro_namedevice(struct zorro_dev *dev); - /* * Zorro Expansion Devices */ @@ -36,13 +34,15 @@ struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO]; */ static struct resource zorro_res[4] = { + /* Zorro II regions (on Zorro II/III) */ { "Zorro II exp", 0x00e80000, 0x00efffff }, { "Zorro II mem", 0x00200000, 0x009fffff }, + /* Zorro III regions (on Zorro III only) */ { "Zorro III exp", 0xff000000, 0xffffffff }, { "Zorro III cfg", 0x40000000, 0x7fffffff } }; -static u_int __init zorro_num_res = 0; +static u_int zorro_num_res __initdata = 0; /* @@ -56,8 +56,9 @@ struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from) if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) return NULL; - dev = from ? from+1 : &zorro_autocon[0]; - for (; dev < zorro_autocon+zorro_num_autocon; dev++) + for (dev = from ? from+1 : &zorro_autocon[0]; + dev < zorro_autocon+zorro_num_autocon; + dev++) if (id == ZORRO_WILDCARD || id == dev->id) return dev; return NULL; @@ -146,10 +147,13 @@ void __init zorro_init(void) unsigned long magic = dev->resource.start+0x8000; dev->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK; } + sprintf(dev->name, "Zorro device %08x", dev->id); + zorro_name_device(dev); dev->resource.name = dev->name; - zorro_namedevice(dev); if (request_resource(zorro_find_parent_resource(dev), &dev->resource)) - printk("zorro_init: cannot request resource for board %d\n", i); + printk(KERN_ERR "Zorro: Address space collision on device %s " + "[%lx:%lx]\n", + dev->name, dev->resource.start, dev->resource.end); } /* Mark all available Zorro II memory */ diff --git a/drivers/zorro/zorro.ids b/drivers/zorro/zorro.ids new file mode 100644 index 000000000..aec74bbba --- /dev/null +++ b/drivers/zorro/zorro.ids @@ -0,0 +1,469 @@ +# +# List of Zorro IDs +# +# Maintained by Geert Uytterhoeven <zorro@linux-m68k.org> +# If you have any new entries, please send them to the maintainer. +# +# $Id: zorro.ids,v 1.16 2000/09/28 18:45:47 geert Exp $ +# + +# Manufacturers and Products. Please keep sorted. + +# Syntax: +# manufacturer manufacturer_name +# product product_name <-- single tab + +00d3 Pacific Peripherals + 0000 SE 2000 A500 [HD Controller] + 0a00 [SCSI Host Adapter] +00dd Kupke + 0000 Golem RAM Box 2MB [RAM Expansion] +0100 MacroSystems USA +# The Stormbringer is actually made by Memphis + 0000 Stormbringer [Accelerator] + 1300 Warp Engine [Accelerator, SCSI Host Adapter and RAM Expansion] +0200 3-State + 0200 Megamix 2000 [RAM Expansion] +0201 Commodore Braunschweig + 0100 A2088 XT/A2286 AT [ISA Bus Bridge] + 0200 A2286 AT [ISA Bus Bridge] + 5400 A4091 [SCSI Host Adapter] + 6700 A2386-SX [ISA Bus Bridge] +0202 Commodore West Chester + 0100 A2090/A2090A [SCSI Host Adapter] + 0200 A590/A2091 [SCSI Host Adapter] + 0300 A590/A2091 [SCSI Host Adapter] + 0400 A2090B 2090 Autoboot [SCSI Host Adapter] + 0900 A2060 [ArcNet Card] + 0a00 A590/A2052/A2058/A2091 [RAM Expansion] + 2000 A560 [RAM Expansion] + 4500 A2232 Prototype [Multi I/O] + 4600 A2232 [Multi I/O] + 5000 A2620 68020 [Accelerator and RAM Expansion] + 5100 A2630 68030 [Accelerator and RAM Expansion] + 5400 A4091 [SCSI Host Adapter] + 5a00 A2065 [Ethernet Card]] + 6000 Romulator Card + 6100 A3000 Test Fixture [Miscellaneous Expansion Card] + 6700 A2386-SX [ISA Bus Bridge] + 7000 A2065 [Ethernet Card] +0203 Commodore West Chester + 0300 A2090/A2090A Combitec/MacroSystem [SCSI Host Adapter] +02f4 Progressive Peripherals & Systems + 0200 EXP8000 [RAM Expansion] + 6900 A2000 68040 [Accelerator] + 9600 68040 [Accelerator] +02ff Kolff Computer Supplies + 0000 KCS Power PC [ISA Bus Bridge] +03ec Cardco Ltd. + 0400 Kronos 2000 [SCSI Host Adapter]] + 0c00 A1000 [SCSI Host Adapter] + 0e00 Escort [SCSI Host Adapter] + f500 A2410 HiRes [Graphics Card] +03ed A-Squared + 0100 Live! 2000 [Video Card] +03ee Comspec Communications + 0100 AX2000 [RAM Expansion] +03f1 Anakin Research + 0100 Easyl Drawing Tablet Interface +03f2 Microbotics + 0000 StarBoard II [RAM Expansion] + 0200 StarDrive [SCSI Host Adapter] + 0300 8-Up (Rev A) [RAM Expansion] + 0400 8-Up (Rev Z) [RAM Expansion] + 2000 Delta [RAM Expansion] + 4000 8-Star [RAM Expansion] + 4100 8-Star [Miscellaneous Expansion Card] + 4400 VXL RAM*32 [RAM Expansion] + 4500 VXL-30 [Accelerator] + 6000 Delta [Miscellaneous Expansion Card] + 8100 MBX 1200/1200z [RAM Expansion] + 9600 Hardframe 2000 [SCSI Host Adapter] + 9e00 Hardframe 2000 [SCSI Host Adapter] + c100 MBX 1200/1200z [Miscellaneous Expansion Card] +03f4 Access Associates Alegra +03f6 Expansion Technologies/Pacific Cypress +03ff ASDG + 0100 [RAM Expansion] + 0200 [RAM Expansion] + fe00 EB-920 Lan Rover [Ethernet Card] + ff00 GPIB/Dual IEEE-488/Twin-X [Multi I/O] +0404 Ronin/Imtronics + 3900 Hurricane 2800 [Accelerator and RAM Expansion] + 5700 Hurricane 2800 [Accelerator and RAM Expansion] +0406 Commodore/University of Lowell + 0000 A2410 HiRes [Graphics Card] +041d Ameristar + 0100 A2065 [Ethernet Card] + 0900 A560 [ArcNet Card] + 0a00 A4066 [Ethernet Card] + 2000 1600-GX [Graphics Card] +0420 Supra + 0100 SupraDrive 4x4 [SCSI Host Adapter] + 0200 1000 [RAM Expansion] + 0300 2000 DMA [SCSI Host Adapter] + 0500 500 [SCSI Host Adapter and RAM Expansion] + 0800 500 [SCSI Host Adapter] + 0900 500XP/2000 [RAM Expansion] + 0a00 500RX/2000 [RAM Expansion] + 0b00 2400zi [Modem] + 0c00 500XP/SupraDrive WordSync [SCSI Host Adapter] + 0d00 SupraDrive WordSync II [SCSI Host Adapter] + 1000 2400zi+ [Modem] +0422 Computer Systems Assosiates + 1100 Magnum 40 [Accelerator and SCSI Host Adapter] + 1500 12 Gauge [SCSI Host Adapter] +0439 Marc Michael Groth +0502 M-Tech + 0300 AT500 [RAM Expansion] +06e1 Great Valley Products + 0800 Impact Series I [SCSI Host Adapter and RAM Expansion] + 2000 Impact Vision 24 [Graphics Card] +07da ByteBox + 0000 A500 +07db Hacker Test Board +07dc DKB/Power Computing + 0900 SecureKey + 0e00 DKM 3128 [RAM Expansion] + 0f00 Rapid Fire [SCSI Host Adapter] + 1000 DKM 1202 [FPU and RAM Expansion] + 1200 Cobra/Viper II 68EC030 [Accelerator] + 1700 WildFire 060 [Accelerator] + ff00 WildFire 060 [Accelerator] +07e1 Great Valley Products + 0100 Impact Series I (4K) [SCSI Host Adapter] + 0200 Impact Series I (16K/2) [SCSI Host Adapter] + 0300 Impact Series I (16K/2) [SCSI Host Adapter] + 0800 Impact 3001 [IDE Interface] + 0900 Impact 3001 [RAM Expansion] + 0a00 Impact Series II [RAM Expansion] + 0b20 GForce 040 [Accelerator] + 0b30 GForce 040 [Accelerator and SCSI Host Adapter] + 0b40 A1291 [SCSI Host Adapter] + 0b60 Combo 030 R4 [Accelerator] + 0b70 Combo 030 R4 [Accelerator and SCSI Host Adapter] + 0b78 Phone Pak + 0b98 IO-Extender [Multi I/O] + 0ba0 GForce 030 [Accelerator] + 0bb0 GForce 030 [Accelerator and SCSI Host Adapter] + 0bc0 A530 [Accelerator] + 0bd0 A530 [Accelerator and SCSI Host Adapter] + 0be0 Combo 030 R3 [Accelerator] + 0bf0 Combo 030 R3 [Accelerator and SCSI Host Adapter] + 0bf8 Series-II [SCSI Host Adapter] + 0d00 Impact 3001 [IDE Interface] + 1600 GForce 040/060 [Accelerator and SCSI Host Adapter] + 2000 Impact Vision 24 [Graphics Card] + 4400 Rembrandt [Graphics Card] + ff00 GForce 040 [Accelerator] +07e5 California Access/Synergy + 0100 Malibu [SCSI Host Adapter] +07e6 Xetec + 0100 FastCard [SCSI Host Adapter] + 0200 FastCard [RAM Expansion] + 0300 FastCard Plus [SCSI Host Adapter] +07ea Progressive Peripherals & Systems + 0000 Mercury [Accelerator] + 0100 A3000 68040 [Accelerator] + 6900 A2000 68040 [Accelerator] + 9600 Zeus [Accelerator, SCSI Host Adapter and RAM Expansion] + bb00 A500 68040 [Accelerator] +# The AteoBus and Pixel64 are actually made by Ateo Concepts + fc00 AteoBus [Expansion Bus Bridge] + fe00 Pixel64 [Graphics Card] + ff00 Pixel64 RAM [Graphics Card] +07ec Xebec +07f2 Spirit Technology + 0100 Insider IN1000 [RAM Expansion] + 0200 Insider IN500 [RAM Expansion] + 0300 SIN500 [RAM Expansion] + 0400 HDA 506 [HD Controller] + 0500 AX-S [Miscellaneous Expansion Card] + 0600 OctaByte [RAM Expansion] + 0800 Inmate [SCSI Host Adapter and RAM Expansion] +07f3 Spirit Technology +07fe BSC/Alfadata + 0300 ALF 3 [SCSI Host Adapter] +0801 BSC/Alfadata + 0100 ALF 2 [SCSI Host Adapter] + 0200 ALF 2 [SCSI Host Adapter] + 0300 ALF 3 [SCSI Host Adapter] + 0400 Oktagon 500 [SCSI Host Adapter] + 0600 Tandem AT-2008/508 [IDE Interface] + 0800 Oktagon 2008 [RAM Expansion] + 1000 MultiFace I [Multi I/O] + 2000 FrameMaster II [Graphics Card] + 4000 ISDN MasterCard [ISDN Interface] +0802 Cardco Ltd. + 0400 Kronos 2000 [SCSI Host Adapter] + 0c00 A1000 [SCSI Host Adapter] +0804 Jochheim + 0100 [RAM Expansion] + 2000 [RAM Expansion] +0807 Checkpoint Technologies + 0000 Serial Solution [Multi Serial] +0810 Edotronik + 0100 IEEE-488 Interface Card + 0200 CBM-8032 Card + 0300 [Multi Serial] + 0400 24Bit Realtime Video Digitizer + 0500 32Bit Parallel I/O Interface + 0600 PIC Prototyping Card + 0700 16 Channel ADC Interface + 0800 VME-Bus Controller + 0900 DSP96000 Realtime Data Acquisition DSP Card +0813 NES Inc. + 0000 [RAM Expansion] +0817 ICD + 0100 Advantage 2000 [SCSI Host Adapter] + 0300 Advantage [IDE Interface] + 0400 Advantage 2080 [RAM Expansion] +0819 Kupke + 0100 Omti [HD Controller] + 0200 Golem SCSI-II [SCSI Host Adapter] + 0300 Golem Box + 0400 030/882 [Accelerator] + 0500 Golem [SCSI Host Adapter] +081d Great Valley Products + 0900 A2000-RAM8/2 [Miscellaneous Expansion Card] + 0a00 Impact Series II [RAM Expansion] +081e Interworks Network +0820 Hardital Synthesis + 1400 TQM 68030+68882 [Accelerator] +0828 Applied Engineering + 1000 DL2000 [Modem] + e000 RAM Works [RAM Expansion] +082c BSC/Alfadata + 0400 Oktagon 500 [SCSI Host Adapter] + 0500 Oktagon 2008 [SCSI Host Adapter] + 0600 Tandem AT-2008/508 [IDE Interface] + 0700 Alpha 1200 [RAM Expansion] + 0800 Oktagon 2008 [RAM Expansion] + 1000 MultiFace I [Multi I/O] + 1100 MultiFace II [Multi I/O] + 1200 MultiFace III [Multi I/O] + 2000 FrameMaster II [Graphics Card] + 2100 Graffiti RAM [Graphics Card] + 2200 Graffiti [Graphics Card] + 4000 ISDN MasterCard [ISDN Interface] + 4100 ISDN MasterCard II [ISDN Interface] +0835 Phoenix + 2100 ST506 [HD Controller] + 2200 [SCSI Host Adapter] + be00 [RAM Expansion] +0836 Advanced Storage Systems + 0100 Nexus [SCSI Host Adapter] + 0800 Nexus [RAM Expansion] +0838 Impulse + 0000 FireCracker 24 (NTSC) [Graphics Card] + 0100 FireCracker 24 (PAL) [Graphics Card] +0840 IVS + 0200 GrandSlam PIC 2 [RAM Expansion] + 0400 GrandSlam PIC 1 [RAM Expansion] + 1000 OverDrive [HD Controller] + 3000 TrumpCard Classic [SCSI Host Adapter] + 3400 TrumpCard Pro/GrandSlam [SCSI Host Adapter] + 4000 Meta-4 [RAM Expansion] + bf00 Wavetools [Audio Card] + f300 Vector [SCSI Host Adapter] + f400 Vector [SCSI Host Adapter] +0841 Vector + e300 Connection [Multi I/O] +0845 XPert ProDev + 0100 Visiona RAM [Graphics Card] + 0200 Visiona [Graphics Card] + 0300 Merlin RAM [Graphics Card] + 0400 Merlin [Graphics Card] + c900 Merlin [Graphics Card] +0849 Hydra Systems + 0100 Amiganet [Ethernet Card] +084f Sunrize Industries + 0100 AD1012 [Audio Card] + 0200 AD516 [Audio Card] + 0300 DD512 [Audio Card] +0850 Triceratops + 0100 [Multi I/O] +0851 Applied Magic Inc. + 0100 DMI Resolver [Graphics Card] + 0200 Vivid 24 [Graphics Card] + 0600 Digital Broadcaster [Video Card] +085e GFX-Base + 0000 GDA-1 VRAM [Graphics Card] + 0100 GDA-1 [Graphics Card] +0860 RocTec + 0100 RH 800C [HD Controller] + 0200 RH 800C [RAM Expansion] +0861 Kato +# The Rainbow II and III are actually made by Ingenieurbüro Helfrich + 2000 Rainbow II [Graphics Card] + 2100 Rainbow III [Graphics Card] + 8000 Melody MPEG [Audio Card] +0862 Atlantis +0864 Protar +0865 ACS +0866 Software Results Enterprises + 0100 Golden Gate 2 Bus+ [ISA Bus Bridge] +086a Unknown + 0100 Horizon [Graphics Card] + 0200 Blackbox [Graphics Card] + 0300 Voyager [Graphics Card] +086d Masoboshi + 0300 MasterCard SC201 [RAM Expansion] + 0400 MasterCard MC702 [SCSI Host Adapter and IDE Interface] + 0700 MVD 819 +086f Mainhattan-Data/A-Team + 0100 [IDE Interface] +0877 Village Tronic + 0100 Domino RAM [Graphics Card] + 0200 Domino [Graphics Card] + 0300 Domino 16M Prototype [Graphics Card] + 0b00 Picasso II/II+ RAM [Graphics Card] + 0c00 Picasso II/II+ [Graphics Card] + 0d00 Picasso II/II+ (Segmented Mode) [Graphics Card] + 1500 Picasso IV Z2 RAM [Graphics Card] + 1600 Picasso IV Z2 RAM [Graphics Card] + 1700 Picasso IV Z2 [Graphics Card] + 1800 Picasso IV Z3 [Graphics Card] + c900 Ariadne [Ethernet Card and Parallel Ports] + ca00 Ariadne II [Ethernet Card] +087b Utilities Unlimited + 1500 Emplant Deluxe [Macintosh Emulator] + 2000 Emplant Deluxe [Macintosh Emulator] +0880 Amitrix + 0100 [Multi I/O] + 0200 CD-RAM [RAM Expansion] +0885 ArMax + 0000 OmniBus [Graphics Card] +088d ZEUS Electronic Development + 0300 [ISDN Interface] + 0400 Spider [Video Card] +088f NewTek + 0000 VideoToaster [Video Card] +0890 M-Tech Germany + 0100 AT500 [IDE Interface] + 0300 68030 [Accelerator] + 0600 68020i [Accelerator] + 2000 A1200 T68030 RTC [Accelerator] + 2100 Viper Mk V/E-Matrix 530 [Accelerator and RAM Expansion] + 2200 8MB [RAM Expansion] + 2400 Viper Mk V/E-Matrix 530 [SCSI Host Adapter and IDE Interface] +0891 Great Valley Products + 0100 EGS 28/24 Spectrum RAM [Graphics Card] + 0200 EGS 28/24 Spectrum [Graphics Card] +0892 Apollo + 0100 A1200 [FPU and RAM Expansion] +0893 Ingenieurbüro Helfrich + 0500 Piccolo RAM [Graphics Card] + 0600 Piccolo [Graphics Card] + 0700 PeggyPlus MPEG [Video Card] + 0800 VideoCruncher [Video Card] + 0a00 Piccolo SD64 RAM [Graphics Card] + 0b00 Piccolo SD64 [Graphics Card] +089b MacroSystems USA + 1300 Warp Engine 40xx [Accelerator, SCSI Host Adapter and RAM Expansion] +089e ElBox Computer + 0600 1200/4 [RAM Expansion] + 1900 PowerFlyer [IDE Interface] +0a00 Harms Professional + 1000 030 Plus [Accelerator] + d000 3500 Professional [Accelerator and RAM Expansion] +0a50 Micronik + 0a00 RCA 120 [RAM Expansion] +0f0f Micronik + 0100 Z3i A1200 [Zorro III Extender and SCSI Host Adapter] +1000 MegaMicro + 0300 SCRAM 500 [SCSI Host Adapter] + 0400 SCRAM 500 [RAM Expansion] +1028 Ronin/Imtronics + 3900 Hurricane 2800 [Accelerator and RAM Expansion] + 5700 Hurricane 2800 [Accelerator and RAM Expansion] +102f Ateo Concepts + fc00 AteoBus [Expansion Bus Bridge] + fe00 Pixel64 [Graphics Card] + ff00 Pixel64 RAM [Graphics Card] +1212 Individual Computers + 0000 Buddha [IDE Interface] + 1700 X-Surf [Ethernet Card] + 2a00 Catweasel [IDE Interface and Floppy Controller] +1248 Kupke + 0100 Golem HD 3000 [HD Controller] +1267 RBM-Computertechnik + 0100 IOBlix [Multi I/O] +1388 ITH + 0100 ISDN-Master II [ISDN Interface] +1389 VMC + 0100 ISDN Blaster Z2 [ISDN Interface] + 0200 HyperCom 4 [Multi I/O] + 0600 HyperCom 4+ [Multi I/O] +157c Information + 6400 ISDN Engine I [ISDN Interface] +2017 Vortex + 0700 Golden Gate 80386SX [ISA Bus Bridge] + 0800 Golden Gate [RAM Expansion] + 0900 Golden Gate 80486 [ISA Bus Bridge] +2062 Expansion Systems + 0100 DataFlyer 4000SX [SCSI Host Adapter] + 0200 DataFlyer 4000SX [RAM Expansion] +2100 ReadySoft + 0100 AMax II/IV [Macintosh Emulator] +2140 Phase 5 + 0100 Blizzard [RAM Expansion] + 0200 Blizzard [Accelerator] + 0600 Blizzard 1220-IV [Accelerator] + 0a00 FastLane Z3 [RAM Expansion] + 0b00 Blizzard 1230-II/Fastlane Z3/CyberSCSI/CyberStorm060 [Accelerator and/or SCSI Host Adapter] + 0c00 Blizzard 1220/CyberStorm [Accelerator and SCSI Host Adapter] + 0d00 Blizzard 1230 [Accelerator] + 1100 Blizzard 1230-IV/1260 [Accelerator] + 1800 Blizzard 2060 [Accelerator] + 1900 CyberStorm Mk II [Flash ROM] + 2200 CyberVision64 [Graphics Card] + 3200 CyberVision64-3D Prototype [Graphics Card] + 4300 CyberVision64-3D [Graphics Card] + 6400 CyberStorm Mk III [Accelerator and SCSI Host Adapter] + 6e00 Blizzard 603e+ [Accelerator and SCSI Host Adapter] +2169 DPS + 0100 Personal Animation Recorder [Video Card] +2200 Apollo + 0000 A620 68020 [Accelerator] + 0100 A620 68020 [Accelerator] +2222 Apollo + 2200 AT-Apollo + 2300 1230/1240/1260/2030/4040/4060 [Accelerator] +38a5 Petsoff LP + 0000 Delfina [Audio Card] + 0100 Delfina Lite [Audio Card] + 0200 Delfina Plus [Audio Card] +3ff7 Uwe Gerlach + d400 RAM/ROM [Miscellaneous Expansion Card] +4231 ACT + 0100 Prelude [Audio Card] +4754 MacroSystems Germany + 0300 Maestro [Audio Card] + 0400 VLab [Video Card] + 0500 Maestro Pro [Audio Card] + 0600 Retina [Graphics Card] + 0800 MultiEvolution [SCSI Host Adapter] + 0c00 Toccata [Audio Card] + 0d00 Toccata Pro [Audio Card] + 1000 Retina Z3 [Graphics Card] + 1200 VLab Motion [Video Card] + 1300 Altais [Graphics Card] + fd00 Falcon '040 [Accelerator] +6766 Combitec +8000 SKI Peripherals + 0800 MAST Fireball [SCSI Host Adapter] + 8000 [SCSI Host Adapter and Dual Serial Card] +a9ad Reis-Ware + 1100 Scan King [Scanner Interface] +aa01 Cameron + 1000 Personal A4 [Scanner Interface] +aa11 Reis-Ware + 1100 Handyscanner [Scanner Interface] +b5a8 Phoenix + 2100 ST506 [HD Controller] + 2200 [SCSI Host Adapter] + be00 [RAM Expansion] +c008 Combitec + 2a00 [HD Controller] + 2b00 SRAM [RAM Expansion] @@ -110,6 +110,9 @@ int notify_change(struct dentry * dentry, struct iattr * attr) time_t now = CURRENT_TIME; unsigned int ia_valid = attr->ia_valid; + if (!inode) + BUG(); + attr->ia_ctime = now; if (!(ia_valid & ATTR_ATIME_SET)) attr->ia_atime = now; @@ -117,7 +120,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr) attr->ia_mtime = now; lock_kernel(); - if (inode && inode->i_op && inode->i_op->setattr) + if (inode->i_op && inode->i_op->setattr) error = inode->i_op->setattr(dentry, attr); else { error = inode_change_ok(inode, attr); diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 9d21624bc..9dfde83e8 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -3,7 +3,7 @@ * linux/fs/autofs/expire.c * * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org> + * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> * * This file is part of the Linux kernel and is made available under * the terms of the GNU General Public License, version 2, or at your @@ -15,46 +15,139 @@ /* * Determine if a subtree of the namespace is busy. + * + * mnt is the mount tree under the autofs mountpoint */ -static int is_tree_busy(struct vfsmount *mnt) +static inline int is_vfsmnt_tree_busy(struct vfsmount *mnt) { struct vfsmount *this_parent = mnt; struct list_head *next; int count; - spin_lock(&dcache_lock); - count = atomic_read(&mnt->mnt_count) - 2; - if (!is_autofs4_dentry(mnt->mnt_mountpoint)) - count--; + count = atomic_read(&mnt->mnt_count) - 1; + repeat: next = this_parent->mnt_mounts.next; + DPRINTK(("is_vfsmnt_tree_busy: mnt=%p, this_parent=%p, next=%p\n", + mnt, this_parent, next)); resume: - while (next != &this_parent->mnt_mounts) { - struct list_head *tmp = next; - struct vfsmount *p = list_entry(tmp, struct vfsmount, + for( ; next != &this_parent->mnt_mounts; next = next->next) { + struct vfsmount *p = list_entry(next, struct vfsmount, mnt_child); - next = tmp->next; - /* Decrement count for unused children */ - count += atomic_read(&p->mnt_count) - 2; + + /* -1 for struct vfs_mount's normal count, + -1 to compensate for child's reference to parent */ + count += atomic_read(&p->mnt_count) - 1 - 1; + + DPRINTK(("is_vfsmnt_tree_busy: p=%p, count now %d\n", + p, count)); + if (!list_empty(&p->mnt_mounts)) { this_parent = p; goto repeat; } /* root is busy if any leaf is busy */ - if (atomic_read(&p->mnt_count) > 1) { - spin_unlock(&dcache_lock); + if (atomic_read(&p->mnt_count) > 1) return 1; - } } - /* - * All done at this level ... ascend and resume the search. - */ + + /* All done at this level ... ascend and resume the search. */ if (this_parent != mnt) { next = this_parent->mnt_child.next; this_parent = this_parent->mnt_parent; goto resume; } - spin_unlock(&dcache_lock); + + DPRINTK(("is_vfsmnt_tree_busy: count=%d\n", count)); + return count != 0; /* remaining users? */ +} + +/* Traverse a dentry's list of vfsmounts and return the number of + non-busy mounts */ +static int check_vfsmnt(struct vfsmount *mnt, struct dentry *dentry) +{ + int ret = 0; + struct list_head *tmp; + + list_for_each(tmp, &dentry->d_vfsmnt) { + struct vfsmount *vfs = list_entry(tmp, struct vfsmount, + mnt_clash); + DPRINTK(("check_vfsmnt: mnt=%p, dentry=%p, tmp=%p, vfs=%p\n", + mnt, dentry, tmp, vfs)); + if (vfs->mnt_parent != mnt || /* don't care about busy-ness of other namespaces */ + !is_vfsmnt_tree_busy(vfs)) + ret++; + } + + DPRINTK(("check_vfsmnt: ret=%d\n", ret)); + return ret; +} + +/* Check dentry tree for busyness. If a dentry appears to be busy + because it is a mountpoint, check to see if the mounted + filesystem is busy. */ +static int is_tree_busy(struct vfsmount *topmnt, struct dentry *top) +{ + struct dentry *this_parent; + struct list_head *next; + int count; + + count = atomic_read(&top->d_count); + + DPRINTK(("is_tree_busy: top=%p initial count=%d\n", + top, count)); + this_parent = top; + + count--; /* top is passed in after being dgot */ + + if (is_autofs4_dentry(top)) { + count--; + DPRINTK(("is_tree_busy: autofs; count=%d\n", count)); + } + + if (d_mountpoint(top)) + count -= check_vfsmnt(topmnt, top); + + repeat: + next = this_parent->d_subdirs.next; + resume: + while (next != &this_parent->d_subdirs) { + int adj = 0; + struct dentry *dentry = list_entry(next, struct dentry, + d_child); + next = next->next; + + count += atomic_read(&dentry->d_count) - 1; + + if (d_mountpoint(dentry)) + adj += check_vfsmnt(topmnt, dentry); + + if (is_autofs4_dentry(dentry)) { + adj++; + DPRINTK(("is_tree_busy: autofs; adj=%d\n", + adj)); + } + + count -= adj; + + if (!list_empty(&dentry->d_subdirs)) { + this_parent = dentry; + goto repeat; + } + + if (atomic_read(&dentry->d_count) != adj) { + DPRINTK(("is_tree_busy: busy leaf (d_count=%d adj=%d)\n", + atomic_read(&dentry->d_count), adj)); + return 1; + } + } + + /* All done at this level ... ascend and resume the search. */ + if (this_parent != top) { + next = this_parent->d_child.next; + this_parent = this_parent->d_parent; + goto resume; + } DPRINTK(("is_tree_busy: count=%d\n", count)); return count != 0; /* remaining users? */ @@ -67,11 +160,11 @@ resume: * - it has been unused for exp_timeout time */ static struct dentry *autofs4_expire(struct super_block *sb, - struct vfsmount *mnt, - struct autofs_sb_info *sbi, - int do_now) + struct vfsmount *mnt, + struct autofs_sb_info *sbi, + int do_now) { - unsigned long now = jiffies; /* snapshot of now */ + unsigned long now = jiffies; unsigned long timeout; struct dentry *root = sb->s_root; struct list_head *tmp; @@ -106,36 +199,32 @@ static struct dentry *autofs4_expire(struct super_block *sb, if (!do_now) { /* Too young to die */ - if (time_after(ino->last_used+timeout, now)) + if (time_after(ino->last_used + timeout, now)) continue; /* update last_used here :- - obviously makes sense if it is in use now - less obviously, prevents rapid-fire expire - attempts if expire fails the first time */ + attempts if expire fails the first time */ ino->last_used = now; } p = mntget(mnt); - d = dget(dentry); - spin_unlock(&dcache_lock); - while(d_mountpoint(d) && follow_down(&p, &d)) - ; + d = dget_locked(dentry); - if (!is_tree_busy(p)) { - dput(d); - mntput(p); + if (!is_tree_busy(p, d)) { DPRINTK(("autofs_expire: returning %p %.*s\n", - dentry, dentry->d_name.len, dentry->d_name.name)); + dentry, (int)dentry->d_name.len, dentry->d_name.name)); /* Start from here next time */ - spin_lock(&dcache_lock); list_del(&root->d_subdirs); list_add(&root->d_subdirs, &dentry->d_child); spin_unlock(&dcache_lock); + + dput(d); + mntput(p); return dentry; } dput(d); mntput(p); - spin_lock(&dcache_lock); } spin_unlock(&dcache_lock); diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 72b5e1b27..6bdc3d358 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -3,7 +3,7 @@ * linux/fs/autofs/root.c * * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org> + * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> * * This file is part of the Linux kernel and is made available under * the terms of the GNU General Public License, version 2, or at your @@ -115,7 +115,6 @@ static int try_to_fill_dentry(struct dentry *dentry, /* Return a negative dentry, but leave it "pending" */ return 1; } - /* status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT); */ } /* If this is an unused directory that isn't a mount point, @@ -201,30 +200,34 @@ static int autofs4_revalidate(struct dentry *dentry, int flags) static void autofs4_dentry_release(struct dentry *de) { - struct autofs_info *inf = autofs4_dentry_ino(de); + struct autofs_info *inf; + + lock_kernel(); DPRINTK(("autofs4_dentry_release: releasing %p\n", de)); - lock_kernel(); + inf = autofs4_dentry_ino(de); de->d_fsdata = NULL; + if (inf) { inf->dentry = NULL; inf->inode = NULL; autofs4_free_ino(inf); } + unlock_kernel(); } /* For dentries of directories in the root dir */ static struct dentry_operations autofs4_root_dentry_operations = { - d_revalidate: autofs4_root_revalidate, /* d_revalidate */ + d_revalidate: autofs4_root_revalidate, d_release: autofs4_dentry_release, }; /* For other dentries */ static struct dentry_operations autofs4_dentry_operations = { - d_revalidate: autofs4_revalidate, /* d_revalidate */ + d_revalidate: autofs4_revalidate, d_release: autofs4_dentry_release, }; @@ -521,11 +524,11 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp, /* return a single thing to expire */ case AUTOFS_IOC_EXPIRE: return autofs4_expire_run(inode->i_sb,filp->f_vfsmnt,sbi, - (struct autofs_packet_expire *)arg); + (struct autofs_packet_expire *)arg); /* same as above, but can send multiple expires through pipe */ case AUTOFS_IOC_EXPIRE_MULTI: return autofs4_expire_multi(inode->i_sb,filp->f_vfsmnt,sbi, - (int *)arg); + (int *)arg); default: return -ENOSYS; diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 9ebea1ca7..1a0532420 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -1,7 +1,7 @@ /* * fs/bfs/dir.c * BFS directory operations. - * Copyright (C) 1999 Tigran Aivazian <tigran@ocston.org> + * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> */ #include <linux/sched.h> diff --git a/fs/bfs/file.c b/fs/bfs/file.c index 1da12e6ae..f0ee10a15 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c @@ -1,7 +1,7 @@ /* * fs/bfs/file.c * BFS file operations. - * Copyright (C) 1999 Tigran Aivazian <tigran@ocston.org> + * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> */ #include <linux/fs.h> @@ -26,7 +26,7 @@ struct file_operations bfs_file_operations = { static int bfs_move_block(unsigned long from, unsigned long to, kdev_t dev) { - struct buffer_head *bh, *new = NULL; + struct buffer_head *bh, *new; bh = bread(dev, from, BFS_BSIZE); if (!bh) @@ -56,11 +56,12 @@ static int bfs_move_blocks(kdev_t dev, unsigned long start, unsigned long end, static int bfs_get_block(struct inode * inode, long block, struct buffer_head * bh_result, int create) { - long phys, next_free_block; + long phys; int err; - struct super_block *s = inode->i_sb; + struct super_block *sb = inode->i_sb; + struct buffer_head *sbh = sb->su_sbh; - if (block < 0 || block > s->su_blocks) + if (block < 0 || block > sb->su_blocks) return -EIO; phys = inode->iu_sblock + block; @@ -90,24 +91,25 @@ static int bfs_get_block(struct inode * inode, long block, /* if the last data block for this file is the last allocated block, we can extend the file trivially, without moving it anywhere */ - if (inode->iu_eblock == s->su_lf_eblk) { + if (inode->iu_eblock == sb->su_lf_eblk) { dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n", create, block, phys); bh_result->b_dev = inode->i_dev; bh_result->b_blocknr = phys; bh_result->b_state |= (1UL << BH_Mapped); - s->su_lf_eblk = inode->iu_eblock = inode->iu_sblock + block; + sb->su_freeb -= phys - inode->iu_eblock; + sb->su_lf_eblk = inode->iu_eblock = phys; mark_inode_dirty(inode); - mark_buffer_dirty(s->su_sbh); + mark_buffer_dirty(sbh); err = 0; goto out; } /* Ok, we have to move this entire file to the next free block */ - next_free_block = s->su_lf_eblk + 1; + phys = sb->su_lf_eblk + 1; if (inode->iu_sblock) { /* if data starts on block 0 then there is no data */ err = bfs_move_blocks(inode->i_dev, inode->iu_sblock, - inode->iu_eblock, next_free_block); + inode->iu_eblock, phys); if (err) { dprintf("failed to move ino=%08lx -> fs corruption\n", inode->i_ino); goto out; @@ -115,12 +117,18 @@ static int bfs_get_block(struct inode * inode, long block, } else err = 0; - inode->iu_sblock = next_free_block; - s->su_lf_eblk = inode->iu_eblock = next_free_block + block; + dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n", create, block, phys); + inode->iu_sblock = phys; + phys += block; + sb->su_lf_eblk = inode->iu_eblock = phys; + + /* this assumes nothing can write the inode back while we are here + * and thus update inode->i_blocks! (XXX)*/ + sb->su_freeb -= inode->iu_eblock - inode->iu_sblock + 1 - inode->i_blocks; mark_inode_dirty(inode); - mark_buffer_dirty(s->su_sbh); + mark_buffer_dirty(sbh); bh_result->b_dev = inode->i_dev; - bh_result->b_blocknr = inode->iu_sblock + block; + bh_result->b_blocknr = phys; bh_result->b_state |= (1UL << BH_Mapped); out: unlock_kernel(); @@ -153,8 +161,7 @@ struct address_space_operations bfs_aops = { sync_page: block_sync_page, prepare_write: bfs_prepare_write, commit_write: generic_commit_write, - bmap: bfs_bmap + bmap: bfs_bmap, }; -struct inode_operations bfs_file_inops = { -}; +struct inode_operations bfs_file_inops; diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index fe1396497..b3827a7ae 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -1,7 +1,7 @@ /* * fs/bfs/inode.c * BFS superblock and inode operations. - * Copyright (C) 1999 Tigran Aivazian <tigran@veritas.com> + * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds. */ @@ -325,7 +325,7 @@ out: return NULL; } -static DECLARE_FSTYPE_DEV( bfs_fs_type, "bfs", bfs_read_super); +static DECLARE_FSTYPE_DEV(bfs_fs_type, "bfs", bfs_read_super); static int __init init_bfs_fs(void) { diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 445c47aa6..861ede356 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -33,6 +33,7 @@ #include <linux/smp_lock.h> #include <asm/uaccess.h> +#include <asm/param.h> #include <asm/pgalloc.h> #define DLINFO_ITEMS 13 @@ -159,23 +160,24 @@ create_elf_tables(char *p, int argc, int envc, sp -= 2; NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform); } - sp -= 2; + sp -= 3*2; NEW_AUX_ENT(0, AT_HWCAP, hwcap); + NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE); + NEW_AUX_ENT(2, AT_CLKTCK, CLOCKS_PER_SEC); if (exec) { - sp -= 11*2; + sp -= 10*2; NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff); NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr)); NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum); - NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE); - NEW_AUX_ENT(4, AT_BASE, interp_load_addr); - NEW_AUX_ENT(5, AT_FLAGS, 0); - NEW_AUX_ENT(6, AT_ENTRY, load_bias + exec->e_entry); - NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid); - NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid); - NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid); - NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid); + NEW_AUX_ENT(3, AT_BASE, interp_load_addr); + NEW_AUX_ENT(4, AT_FLAGS, 0); + NEW_AUX_ENT(5, AT_ENTRY, load_bias + exec->e_entry); + NEW_AUX_ENT(6, AT_UID, (elf_addr_t) current->uid); + NEW_AUX_ENT(7, AT_EUID, (elf_addr_t) current->euid); + NEW_AUX_ENT(8, AT_GID, (elf_addr_t) current->gid); + NEW_AUX_ENT(9, AT_EGID, (elf_addr_t) current->egid); } #undef NEW_AUX_ENT diff --git a/fs/buffer.c b/fs/buffer.c index 145e11793..4de38a0e4 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -586,7 +586,7 @@ unsigned int get_hardblocksize(kdev_t dev) These are two special cases. Normal usage imply the device driver to issue a sync on the device (without waiting I/O completation) and - then an invalidate_buffers call that doesn't trashes dirty buffers. */ + then an invalidate_buffers call that doesn't trash dirty buffers. */ void __invalidate_buffers(kdev_t dev, int destroy_dirty_buffers) { int i, nlist, slept; @@ -618,6 +618,8 @@ void __invalidate_buffers(kdev_t dev, int destroy_dirty_buffers) __remove_from_queues(bh); put_last_free(bh); } + /* else complain loudly? */ + write_unlock(&hash_table_lock); if (slept) goto out; @@ -706,7 +708,7 @@ void set_blocksize(kdev_t dev, int size) static void refill_freelist(int size) { if (!grow_buffers(size)) { - wakeup_bdflush(1); + wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */ current->policy |= SCHED_YIELD; schedule(); } @@ -1041,13 +1043,9 @@ struct buffer_head * breada(kdev_t dev, int block, int bufsize, blocks = (filesize - pos) >> (9+index); - if (blocks < (read_ahead[MAJOR(dev)] >> index)) - blocks = read_ahead[MAJOR(dev)] >> index; if (blocks > NBUF) blocks = NBUF; -/* if (blocks) printk("breada (new) %d blocks\n",blocks); */ - bhlist[0] = bh; j = 1; for(i=1; i<blocks; i++) { @@ -2060,7 +2058,7 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[], buffer_heads and exit. */ spin_lock(&unused_list_lock); for (i = bhind; --i >= 0; ) { - __put_unused_buffer_head(bh[bhind]); + __put_unused_buffer_head(bh[i]); } spin_unlock(&unused_list_lock); goto finished; diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 1629be782..e1ab9e896 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -58,7 +58,7 @@ static int coda_venus_readdir(struct file *filp, void *dirent, filldir_t filldir); int coda_fsync(struct file *, struct dentry *dentry, int datasync); -int coda_hasmknod = 0; +int coda_hasmknod; struct dentry_operations coda_dentry_operations = { diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 94a3be389..45acf28c6 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -93,7 +93,7 @@ static int get_device_index(struct coda_mount_data *data) static struct super_block * coda_read_super(struct super_block *sb, void *data, int silent) { - struct inode *psdev = 0, *root = 0; + struct inode *root = 0; struct coda_sb_info *sbi = NULL; struct venus_comm *vc = NULL; ViceFid fid; diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 486e42185..ef05ac2fb 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -54,7 +54,7 @@ extern struct file_system_type coda_fs_type; /* statistics */ -int coda_hard = 0; /* allows signals during upcalls */ +int coda_hard; /* allows signals during upcalls */ unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */ @@ -376,7 +376,7 @@ static struct file_operations coda_psdev_fops = { release: coda_psdev_release, }; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static int init_coda_psdev(void) { diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index a0cf6ba97..4b34da094 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -95,7 +95,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod static unsigned char read_buffers[READ_BUFFERS][BUFFER_SIZE]; static unsigned buffer_blocknr[READ_BUFFERS]; static struct super_block * buffer_dev[READ_BUFFERS]; -static int next_buffer = 0; +static int next_buffer; /* * Returns a pointer to a buffer containing at least LEN bytes of diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 3ffb8275e..264992d3f 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -654,7 +654,7 @@ struct devfs_entry }; /* The root of the device tree */ -static struct devfs_entry *root_entry = NULL; +static struct devfs_entry *root_entry; struct devfsd_buf_entry { diff --git a/fs/devfs/util.c b/fs/devfs/util.c index 9f71763b1..05b681b6c 100644 --- a/fs/devfs/util.c +++ b/fs/devfs/util.c @@ -114,8 +114,8 @@ void devfs_register_tape (devfs_handle_t de) int pos; devfs_handle_t parent, slave; char name[16], dest[64]; - static unsigned int tape_counter = 0; - static devfs_handle_t tape_dir = NULL; + static unsigned int tape_counter; + static devfs_handle_t tape_dir; if (tape_dir == NULL) tape_dir = devfs_mk_dir (NULL, "tapes", NULL); parent = devfs_get_parent (de); @@ -314,9 +314,9 @@ int setup_arg_pages(struct linux_binprm *bprm) mpnt->vm_pgoff = 0; mpnt->vm_file = NULL; mpnt->vm_private_data = (void *) 0; - vmlist_modify_lock(current->mm); + spin_lock(¤t->mm->page_table_lock); insert_vm_struct(current->mm, mpnt); - vmlist_modify_unlock(current->mm); + spin_unlock(¤t->mm->page_table_lock); current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; } diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index e4234cb45..3c981f75c 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -183,25 +183,22 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry) return NULL; } +#define S_SHIFT 12 +static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = { + [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE, + [S_IFDIR >> S_SHIFT] EXT2_FT_DIR, + [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV, + [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV, + [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO, + [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK, + [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK, +}; + static inline void ext2_set_de_type(struct super_block *sb, struct ext2_dir_entry_2 *de, umode_t mode) { - if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)) - return; - if (S_ISREG(mode)) - de->file_type = EXT2_FT_REG_FILE; - else if (S_ISDIR(mode)) - de->file_type = EXT2_FT_DIR; - else if (S_ISLNK(mode)) - de->file_type = EXT2_FT_SYMLINK; - else if (S_ISSOCK(mode)) - de->file_type = EXT2_FT_SOCK; - else if (S_ISFIFO(mode)) - de->file_type = EXT2_FT_FIFO; - else if (S_ISCHR(mode)) - de->file_type = EXT2_FT_CHRDEV; - else if (S_ISBLK(mode)) - de->file_type = EXT2_FT_BLKDEV; + if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)) + de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; } /* @@ -437,7 +434,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) inode->i_nlink--; /* is this nlink == 0? */ mark_inode_dirty(inode); iput (inode); - return -EIO; + return err; } de = (struct ext2_dir_entry_2 *) dir_block->b_data; de->inode = cpu_to_le32(inode->i_ino); diff --git a/fs/fat/cvf.c b/fs/fat/cvf.c index 5bfbaeb64..91462e135 100644 --- a/fs/fat/cvf.c +++ b/fs/fat/cvf.c @@ -98,8 +98,8 @@ struct cvf_format bigblock_cvf = { NULL }; -struct cvf_format *cvf_formats[MAX_CVF_FORMATS]={NULL,NULL,NULL}; -int cvf_format_use_count[MAX_CVF_FORMATS]={0,0,0}; +struct cvf_format *cvf_formats[MAX_CVF_FORMATS]; +int cvf_format_use_count[MAX_CVF_FORMATS]; int register_cvf_format(struct cvf_format*cvf_format) { int i,j; diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c index fe8d02ad6..2e5127703 100644 --- a/fs/hfs/trans.c +++ b/fs/hfs/trans.c @@ -514,7 +514,7 @@ void hfs_latin2mac(struct hfs_name *out, const char *in, int len) int hi, lo; unsigned char code, c, *count; unsigned char *p = out->Name; - static int map_initialized = 0; + static int map_initialized; if (!map_initialized) { int i; diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index 43eb2cb57..5f5ec196f 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c @@ -125,8 +125,7 @@ void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head kdev_t dev = s->s_dev; struct buffer_head *bh; - /* vvvv - workaround for the breada bug */ - if (!ahead || secno + ahead + (read_ahead[MAJOR(dev)] >> 9) >= s->s_hpfs_fs_size) + if (!ahead || secno + ahead >= s->s_hpfs_fs_size) *bhp = bh = bread(dev, secno, 512); else *bhp = bh = breada(dev, secno, 512, 0, (ahead + 1) << 9); if (bh != NULL) @@ -174,8 +173,7 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe goto bail; } - /* vvvv - workaround for the breada bug */ - if (!ahead || secno + 4 + ahead + (read_ahead[MAJOR(dev)] >> 9) > s->s_hpfs_fs_size) + if (!ahead || secno + 4 + ahead > s->s_hpfs_fs_size) qbh->bh[0] = bh = bread(dev, secno, 512); else qbh->bh[0] = bh = breada(dev, secno, 512, 0, (ahead + 4) << 9); if (!bh) diff --git a/fs/inode.c b/fs/inode.c index ba0a3546f..96e3664e5 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -547,7 +547,7 @@ static void clean_inode(struct inode *inode) struct inode * get_empty_inode(void) { - static unsigned long last_ino = 0; + static unsigned long last_ino; struct inode * inode; inode = alloc_inode(); diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 4413b9989..1a7cbe374 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -215,7 +215,7 @@ int get_rock_ridge_filename(struct iso_directory_record * de, printk("RR: RE (%x)\n", inode->i_ino); #endif if (buffer) kfree(buffer); - return -1; + return 0; default: break; } diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 820bc4c7b..249e7514d 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -41,7 +41,7 @@ struct nlm_wait { u32 b_status; /* grant callback status */ }; -static struct nlm_wait * nlm_blocked = NULL; +static struct nlm_wait * nlm_blocked; /* * Block on a lock diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index c60f48da1..dbe3f69b5 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -11,6 +11,7 @@ #include <linux/fs.h> #include <linux/nfs_fs.h> #include <linux/utsname.h> +#include <linux/smp_lock.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/lockd/lockd.h> @@ -64,11 +65,11 @@ nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) int nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) { - nlmclnt_next_cookie(&call->a_args.cookie); - call->a_args.lock = *lock; + locks_copy_lock(&call->a_args.lock.fl, &lock->fl); + memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh)); call->a_args.lock.caller = system_utsname.nodename; + call->a_args.lock.oh.len = lock->oh.len; - init_waitqueue_head(&call->a_args.lock.fl.fl_wait); /* set default data area */ call->a_args.lock.oh.data = call->a_owner; @@ -406,15 +407,19 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl) static void nlmclnt_insert_lock_callback(struct file_lock *fl) { + lock_kernel(); nlm_get_host(fl->fl_u.nfs_fl.host); + unlock_kernel(); } static void nlmclnt_remove_lock_callback(struct file_lock *fl) { + lock_kernel(); if (fl->fl_u.nfs_fl.host) { nlm_release_host(fl->fl_u.nfs_fl.host); fl->fl_u.nfs_fl.host = NULL; } + unlock_kernel(); } /* diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 283d66e97..9fcbad317 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -24,7 +24,7 @@ extern struct rpc_program nsm_program; /* * Local NSM state */ -u32 nsm_local_state = 0; +u32 nsm_local_state; /* * Common procedure for SM_MON/SM_UNMON calls diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index a175d39eb..5460e8c9f 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -24,6 +24,8 @@ #include <linux/types.h> #include <linux/errno.h> #include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/smp_lock.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/lockd/nlm.h> @@ -40,7 +42,7 @@ static void nlmsvc_notify_blocked(struct file_lock *); /* * The list of blocked locks to retry */ -static struct nlm_block * nlm_blocked = NULL; +static struct nlm_block * nlm_blocked; /* * Insert a blocked lock into the global list @@ -53,9 +55,15 @@ nlmsvc_insert_block(struct nlm_block *block, unsigned long when) dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when); if (block->b_queued) nlmsvc_remove_block(block); - for (bp = &nlm_blocked; (b = *bp); bp = &b->b_next) - if (when < b->b_when) - break; + bp = &nlm_blocked; + if (when != NLM_NEVER) { + if ((when += jiffies) == NLM_NEVER) + when ++; + while ((b = *bp) && time_before_eq(b->b_when,when)) + bp = &b->b_next; + } else + while ((b = *bp)) + bp = &b->b_next; block->b_queued = 1; block->b_when = when; @@ -106,8 +114,10 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove) (long long)fl->fl_end, fl->fl_type, *(unsigned int*)(block->b_call.a_args.cookie.data)); if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { - if (remove) + if (remove) { *head = block->b_next; + block->b_queued = 0; + } return block; } } @@ -173,10 +183,11 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, locks_init_lock(&block->b_call.a_args.lock.fl); locks_init_lock(&block->b_call.a_res.lock.fl); - /* Set notifier function for VFS, and init args */ - lock->fl.fl_notify = nlmsvc_notify_blocked; if (!nlmclnt_setgrantargs(&block->b_call, lock)) goto failed_free; + + /* Set notifier function for VFS, and init args */ + block->b_call.a_args.lock.fl.fl_notify = nlmsvc_notify_blocked; block->b_call.a_args.cookie = *cookie; /* see above */ dprintk("lockd: created block %p...\n", block); @@ -349,7 +360,7 @@ again: /* Append to list of blocked */ nlmsvc_insert_block(block, NLM_NEVER); - if (list_empty(&block->b_call.a_args.lock.fl.fl_list)) { + if (list_empty(&block->b_call.a_args.lock.fl.fl_block)) { /* Now add block to block list of the conflicting lock if we haven't done so. */ dprintk("lockd: blocking on this lock.\n"); @@ -457,13 +468,15 @@ nlmsvc_notify_blocked(struct file_lock *fl) dprintk("lockd: VFS unblock notification for block %p\n", fl); posix_unblock_lock(fl); + lock_kernel(); for (bp = &nlm_blocked; (block = *bp); bp = &block->b_next) { if (nlm_compare_locks(&block->b_call.a_args.lock.fl, fl)) { - svc_wake_up(block->b_daemon); nlmsvc_insert_block(block, 0); + svc_wake_up(block->b_daemon); return; } } + unlock_kernel(); printk(KERN_WARNING "lockd: notification for unknown block!\n"); } @@ -520,7 +533,7 @@ nlmsvc_grant_blocked(struct nlm_block *block) if ((error = posix_lock_file(&file->f_file, &lock->fl, 0)) < 0) { printk(KERN_WARNING "lockd: unexpected error %d in %s!\n", -error, __FUNCTION__); - nlmsvc_insert_block(block, jiffies + 10 * HZ); + nlmsvc_insert_block(block, 10 * HZ); up(&file->f_sema); return; } @@ -532,7 +545,7 @@ callback: block->b_incall = 1; /* Schedule next grant callback in 30 seconds */ - nlmsvc_insert_block(block, jiffies + 30 * HZ); + nlmsvc_insert_block(block, 30 * HZ); /* Call the client */ nlm_get_host(block->b_call.a_host); @@ -570,13 +583,13 @@ nlmsvc_grant_callback(struct rpc_task *task) * can be done, though. */ if (task->tk_status < 0) { /* RPC error: Re-insert for retransmission */ - timeout = jiffies + 10 * HZ; + timeout = 10 * HZ; } else if (block->b_done) { /* Block already removed, kill it for real */ timeout = 0; } else { /* Call was successful, now wait for client callback */ - timeout = jiffies + 60 * HZ; + timeout = 60 * HZ; } nlmsvc_insert_block(block, timeout); svc_wake_up(block->b_daemon); @@ -604,7 +617,7 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status) if ((block = nlmsvc_find_block(cookie)) != NULL) { if (status == NLM_LCK_DENIED_GRACE_PERIOD) { /* Try again in a couple of seconds */ - nlmsvc_insert_block(block, jiffies + 10 * HZ); + nlmsvc_insert_block(block, 10 * HZ); block = NULL; } else { /* Lock is now held by client, or has been rejected. @@ -635,7 +648,11 @@ nlmsvc_retry_blocked(void) dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", nlm_blocked, nlm_blocked? nlm_blocked->b_when : 0); - while ((block = nlm_blocked) && block->b_when <= jiffies) { + while ((block = nlm_blocked)) { + if (block->b_when == NLM_NEVER) + break; + if (time_after(block->b_when,jiffies)) + break; dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n", block, block->b_when, block->b_done); if (block->b_done) diff --git a/fs/locks.c b/fs/locks.c index 95310133d..0e92b740f 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -164,7 +164,7 @@ static inline void locks_free_lock(struct file_lock *fl) if (!list_empty(&fl->fl_block)) panic("Attempting to free lock with active block list"); - if (!list_empty(&fl->fl_link) || !list_empty(&fl->fl_list)) + if (!list_empty(&fl->fl_link)) panic("Attempting to free lock on active lock list"); kmem_cache_free(filelock_cache, fl); @@ -174,7 +174,6 @@ void locks_init_lock(struct file_lock *fl) { INIT_LIST_HEAD(&fl->fl_link); INIT_LIST_HEAD(&fl->fl_block); - INIT_LIST_HEAD(&fl->fl_list); init_waitqueue_head(&fl->fl_wait); fl->fl_next = NULL; fl->fl_fasync = NULL; @@ -403,8 +402,8 @@ locks_same_owner(struct file_lock *fl1, struct file_lock *fl2) */ static void locks_delete_block(struct file_lock *waiter) { - list_del(&waiter->fl_list); - INIT_LIST_HEAD(&waiter->fl_list); + list_del(&waiter->fl_block); + INIT_LIST_HEAD(&waiter->fl_block); list_del(&waiter->fl_link); INIT_LIST_HEAD(&waiter->fl_link); waiter->fl_next = NULL; @@ -418,13 +417,13 @@ static void locks_delete_block(struct file_lock *waiter) static void locks_insert_block(struct file_lock *blocker, struct file_lock *waiter) { - if (!list_empty(&waiter->fl_list)) { + if (!list_empty(&waiter->fl_block)) { printk(KERN_ERR "locks_insert_block: removing duplicated lock " "(pid=%d %Ld-%Ld type=%d)\n", waiter->fl_pid, waiter->fl_start, waiter->fl_end, waiter->fl_type); locks_delete_block(waiter); } - list_add_tail(&waiter->fl_list, &blocker->fl_block); + list_add_tail(&waiter->fl_block, &blocker->fl_block); waiter->fl_next = blocker; list_add(&waiter->fl_link, &blocked_list); } @@ -436,7 +435,7 @@ static void locks_insert_block(struct file_lock *blocker, static void locks_wake_up_blocks(struct file_lock *blocker, unsigned int wait) { while (!list_empty(&blocker->fl_block)) { - struct file_lock *waiter = list_entry(blocker->fl_block.next, struct file_lock, fl_list); + struct file_lock *waiter = list_entry(blocker->fl_block.next, struct file_lock, fl_block); /* N.B. Is it possible for the notify function to block?? */ if (waiter->fl_notify) waiter->fl_notify(waiter); @@ -644,7 +643,6 @@ static int posix_locks_deadlock(struct file_lock *caller_fl, caller_pid = caller_fl->fl_pid; blocked_owner = block_fl->fl_owner; blocked_pid = block_fl->fl_pid; - tmp = blocked_list.next; next_task: if (caller_owner == blocked_owner && caller_pid == blocked_pid) @@ -1708,7 +1706,7 @@ void posix_unblock_lock(struct file_lock *waiter) { acquire_fl_sem(); - if (!list_empty(&waiter->fl_list)) { + if (!list_empty(&waiter->fl_block)) { locks_delete_block(waiter); wake_up(&waiter->fl_wait); } @@ -1815,7 +1813,7 @@ int get_locks_status(char *buffer, char **start, off_t offset, int length) list_for_each(btmp, &fl->fl_block) { struct file_lock *bfl = list_entry(btmp, - struct file_lock, fl_list); + struct file_lock, fl_block); lock_get_status(q, bfl, i, " ->"); move_lock_status(&q, &pos, offset); diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index a268be2f1..dce2687ee 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -225,13 +225,16 @@ struct inode * minix_new_inode(const struct inode * dir, int * error) int i,j; inode = get_empty_inode(); - if (!inode) + if (!inode) { + *error = -ENOMEM; return NULL; + } sb = dir->i_sb; inode->i_sb = sb; inode->i_flags = 0; j = 8192; bh = NULL; + *error = -ENOSPC; lock_super(sb); for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) { bh = inode->i_sb->u.minix_sb.s_imap[i]; diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 870656cb7..eadbb79e3 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -210,10 +210,8 @@ static int minix_create(struct inode * dir, struct dentry *dentry, int mode) struct minix_dir_entry * de; inode = minix_new_inode(dir, &error); - if (error) - return error; if (!inode) - return -ENOSPC; + return error; inode->i_op = &minix_file_inode_operations; inode->i_fop = &minix_file_operations; inode->i_mapping->a_ops = &minix_aops; @@ -242,10 +240,8 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int struct minix_dir_entry * de; inode = minix_new_inode(dir, &error); - if (error) - return error; if (!inode) - return -ENOSPC; + return error; inode->i_uid = current->fsuid; init_special_inode(inode, mode, rdev); mark_inode_dirty(inode); @@ -275,10 +271,8 @@ static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode) if (dir->i_nlink >= info->s_link_max) return -EMLINK; inode = minix_new_inode(dir, &error); - if (error) - return error; if (!inode) - return -ENOSPC; + return error; inode->i_op = &minix_dir_inode_operations; inode->i_fop = &minix_dir_operations; inode->i_size = 2 * info->s_dirsize; @@ -461,9 +455,6 @@ static int minix_symlink(struct inode * dir, struct dentry *dentry, if (i>1024) goto out; inode = minix_new_inode(dir, &err); - if (err) - goto out; - err = -ENOSPC; if (!inode) goto out; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ec4540f12..3f6b770aa 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -796,7 +796,7 @@ static int nfs_rmdir(struct inode *dir_i, struct dentry *dentry) static int nfs_sillyrename(struct inode *dir_i, struct dentry *dentry) { struct dentry *dir = dentry->d_parent; - static unsigned int sillycounter = 0; + static unsigned int sillycounter; const int i_inosize = sizeof(dir_i->i_ino)*2; const int countersize = sizeof(sillycounter)*2; const int slen = strlen(".nfs") + i_inosize + countersize; diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 21ae090a3..c30fc5062 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -176,11 +176,16 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offse */ static int nfs_sync_page(struct page *page) { - struct inode *inode = (struct inode *)page->mapping->host; + struct address_space *mapping; + struct inode *inode; unsigned long index = page_index(page); unsigned int rpages, wpages; int result; + mapping = page->mapping; + if (!mapping) + return 0; + inode = (struct inode *)mapping->host; if (!inode) return 0; @@ -281,7 +286,9 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl) * Flush all pending writes before doing anything * with locks.. */ + down(&filp->f_dentry->d_inode->i_sem); status = nfs_wb_all(inode); + up(&filp->f_dentry->d_inode->i_sem); if (status < 0) return status; @@ -296,8 +303,10 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl) */ out_ok: if ((cmd == F_SETLK || cmd == F_SETLKW) && fl->fl_type != F_UNLCK) { + down(&filp->f_dentry->d_inode->i_sem); nfs_wb_all(inode); /* we may have slept */ nfs_zap_caches(inode); + up(&filp->f_dentry->d_inode->i_sem); } return status; } diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index a8b61c2e7..7fef7da99 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -104,7 +104,8 @@ xdr_decode_string2(u32 *p, char **string, unsigned int *len, static inline u32* xdr_decode_time(u32 *p, u64 *timep) { - *timep = ((u64)ntohl(*p++) << 32) + (u64)ntohl(*p++); + u64 tmp = (u64)ntohl(*p++) << 32; + *timep = tmp + (u64)ntohl(*p++); return p; } diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index ef8580c02..f6260a552 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -143,7 +143,8 @@ xdr_encode_time(u32 *p, time_t time) static inline u32 * xdr_decode_time3(u32 *p, u64 *timep) { - *timep = ((u64)ntohl(*p++) << 32) + (u64)ntohl(*p++); + u64 tmp = (u64)ntohl(*p++) << 32; + *timep = tmp + (u64)ntohl(*p++); return p; } @@ -184,7 +185,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) p = xdr_decode_hyper(p, &fattr->size); p = xdr_decode_hyper(p, &fattr->du.nfs3.used); /* Turn remote device info into Linux-specific dev_t */ - fattr->rdev = (ntohl(*p++) << MINORBITS) | (ntohl(*p++) & MINORMASK); + fattr->rdev = ntohl(*p++) << MINORBITS; + fattr->rdev |= ntohl(*p++) & MINORMASK; p = xdr_decode_hyper(p, &fattr->fsid); p = xdr_decode_hyper(p, &fattr->fileid); p = xdr_decode_time3(p, &fattr->atime); diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 6575040d9..7c1aad253 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -54,7 +54,7 @@ static void nfs_readpage_result(struct rpc_task *task); # define IS_SWAPFILE(inode) (0) #endif -static kmem_cache_t *nfs_rdata_cachep = NULL; +static kmem_cache_t *nfs_rdata_cachep; static __inline__ struct nfs_read_data *nfs_readdata_alloc(void) { diff --git a/fs/nfs/write.c b/fs/nfs/write.c index a5bda60ba..5346e6302 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -102,8 +102,8 @@ static void nfs_commit_done(struct rpc_task *); # define IS_SWAPFILE(inode) (0) #endif -static kmem_cache_t *nfs_page_cachep = NULL; -static kmem_cache_t *nfs_wdata_cachep = NULL; +static kmem_cache_t *nfs_page_cachep; +static kmem_cache_t *nfs_wdata_cachep; static __inline__ struct nfs_page *nfs_page_alloc(void) { @@ -1207,7 +1207,7 @@ nfs_writeback_done(struct rpc_task *task) /* We can't handle that yet but we check for it nevertheless */ if (resp->count < argp->count && task->tk_status >= 0) { - static unsigned long complain = 0; + static unsigned long complain; if (time_before(complain, jiffies)) { printk(KERN_WARNING "NFS: Server wrote less than requested.\n"); @@ -1227,7 +1227,7 @@ nfs_writeback_done(struct rpc_task *task) * NFS_FILE_SYNC. We therefore implement this checking * as a dprintk() in order to avoid filling syslog. */ - static unsigned long complain = 0; + static unsigned long complain; if (time_before(complain, jiffies)) { dprintk("NFS: faulty NFSv3 server %s:" @@ -1239,9 +1239,6 @@ nfs_writeback_done(struct rpc_task *task) } #endif - /* Update attributes as result of writeback. */ - nfs_write_attributes(inode, resp->fattr); - while (!list_empty(&data->pages)) { req = nfs_list_entry(data->pages.next); nfs_list_remove_request(req); @@ -1281,6 +1278,9 @@ nfs_writeback_done(struct rpc_task *task) next: nfs_unlock_request(req); } + /* Update attributes as result of writeback. */ + nfs_write_attributes(inode, resp->fattr); + } @@ -1395,7 +1395,6 @@ nfs_commit_done(struct rpc_task *task) dprintk("NFS: %4d nfs_commit_done (status %d)\n", task->tk_pid, task->tk_status); - nfs_refresh_inode(inode, resp->fattr); while (!list_empty(&data->pages)) { req = nfs_list_entry(data->pages.next); nfs_list_remove_request(req); @@ -1427,6 +1426,8 @@ nfs_commit_done(struct rpc_task *task) next: nfs_unlock_request(req); } + + nfs_write_attributes(inode, resp->fattr); } #endif diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index d97e1717d..4cf7c897c 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -144,9 +144,9 @@ decode_sattr3(u32 *p, struct iattr *iap) iap->ia_valid |= ATTR_SIZE; p = dec64(p, &newsize); if (newsize <= NFS_OFFSET_MAX) - iap->ia_size = (u32) newsize; + iap->ia_size = newsize; else - iap->ia_size = ~(size_t) 0; + iap->ia_size = NFS_OFFSET_MAX; } if ((tmp = ntohl(*p++)) == 1) { /* set to server time */ iap->ia_valid |= ATTR_ATIME; diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 425778412..8a061ebcb 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -38,7 +38,7 @@ static struct nfscache_head * hash_list; static struct svc_cacherep * lru_head; static struct svc_cacherep * lru_tail; static struct svc_cacherep * nfscache; -static int cache_initialized = 0; +static int cache_initialized; static int cache_disabled = 1; static int nfsd_cache_append(struct svc_rqst *rqstp, struct svc_buf *data); @@ -215,7 +215,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type) /* This should not happen */ if (rp == NULL) { - static int complaints = 0; + static int complaints; printk(KERN_WARNING "nfsd: all repcache entries locked!\n"); if (++complaints > 5) { diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 672d66bf8..7bf572e34 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -25,8 +25,8 @@ /* #define NFSD_DEBUG_VERBOSE 1 */ -static int nfsd_nr_verified = 0; -static int nfsd_nr_put = 0; +static int nfsd_nr_verified; +static int nfsd_nr_put; struct nfsd_getdents_callback { diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a796885e3..f01f1de86 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -74,8 +74,8 @@ struct raparms { p_rawin; }; -static struct raparms * raparml = NULL; -static struct raparms * raparm_cache = NULL; +static struct raparms * raparml; +static struct raparms * raparm_cache; /* * Look up one component of a pathname. @@ -714,7 +714,7 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, } if (err >= 0 && stable) { - static unsigned long last_ino = 0; + static unsigned long last_ino; static kdev_t last_dev = NODEV; /* diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 3ea51cdfa..e98d8490c 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -20,7 +20,7 @@ #endif #include <linux/spinlock.h> -static struct nls_table *tables = (struct nls_table *) NULL; +static struct nls_table *tables; static spinlock_t nls_lock = SPIN_LOCK_UNLOCKED; /* diff --git a/fs/nls/nls_big5.c b/fs/nls/nls_big5.c index 847904ba1..250098337 100644 --- a/fs/nls/nls_big5.c +++ b/fs/nls/nls_big5.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; static struct nls_table table = { "big5", diff --git a/fs/nls/nls_euc-jp.c b/fs/nls/nls_euc-jp.c index 98b380e59..196a07698 100644 --- a/fs/nls/nls_euc-jp.c +++ b/fs/nls/nls_euc-jp.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; #define SS2 (0x8E) /* Single Shift 2 */ diff --git a/fs/nls/nls_euc-kr.c b/fs/nls/nls_euc-kr.c index 5219c2371..f015c21bf 100644 --- a/fs/nls/nls_euc-kr.c +++ b/fs/nls/nls_euc-kr.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; static struct nls_table table = { "euc-kr", diff --git a/fs/nls/nls_gb2312.c b/fs/nls/nls_gb2312.c index 542a10e97..06c184a27 100644 --- a/fs/nls/nls_gb2312.c +++ b/fs/nls/nls_gb2312.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; static struct nls_table table = { "gb2312", diff --git a/fs/nls/nls_sjis.c b/fs/nls/nls_sjis.c index ec6fb598f..463ee02a5 100644 --- a/fs/nls/nls_sjis.c +++ b/fs/nls/nls_sjis.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; static struct nls_table table = { "sjis", diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index c99e81e6a..f9ffb0a40 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -416,8 +416,7 @@ static struct file_operations ntfs_file_operations_nommap = { #endif }; -static struct inode_operations ntfs_inode_operations_nobmap = { -}; +static struct inode_operations ntfs_inode_operations_nobmap; #ifdef CONFIG_NTFS_RW static int @@ -577,8 +576,7 @@ static struct file_operations ntfs_file_operations = { #endif }; -static struct inode_operations ntfs_inode_operations = { -}; +static struct inode_operations ntfs_inode_operations; static struct file_operations ntfs_dir_operations = { read: generic_read_dir, @@ -103,7 +103,7 @@ static inline long do_sys_truncate(const char * path, loff_t length) inode = nd.dentry->d_inode; error = -EACCES; - if (S_ISDIR(inode->i_mode)) + if (!S_ISREG(inode->i_mode)) goto dput_and_out; error = permission(inode,MAY_WRITE); @@ -164,7 +164,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length) dentry = file->f_dentry; inode = dentry->d_inode; error = -EACCES; - if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE)) + if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE)) goto out_putf; error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) diff --git a/fs/partitions/atari.c b/fs/partitions/atari.c index a94f8f5fc..0180daca8 100644 --- a/fs/partitions/atari.c +++ b/fs/partitions/atari.c @@ -62,6 +62,7 @@ int atari_partition (struct gendisk *hd, kdev_t dev, /* if there's no valid primary partition, assume that no Atari format partition table (there's no reliable magic or the like :-() */ + brelse(bh); return 0; } diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 5d4c2526c..87b88d04a 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -338,8 +338,8 @@ static void devfs_register_disc (struct gendisk *dev, int minor) devfs_handle_t dir, slave; unsigned int devfs_flags = DEVFS_FL_DEFAULT; char dirname[64], symlink[16]; - static unsigned int disc_counter = 0; - static devfs_handle_t devfs_handle = NULL; + static unsigned int disc_counter; + static devfs_handle_t devfs_handle; if (dev->part[minor].de) return; if ( dev->flags && (dev->flags[devnum] & GENHD_FL_REMOVABLE) ) @@ -284,7 +284,7 @@ pipe_poll(struct file *filp, poll_table *wait) poll_wait(filp, PIPE_WAIT(*inode), wait); - /* Reading only -- no need for aquiring the semaphore. */ + /* Reading only -- no need for acquiring the semaphore. */ mask = POLLIN | POLLRDNORM; if (PIPE_EMPTY(*inode)) mask = POLLOUT | POLLWRNORM; diff --git a/fs/proc/array.c b/fs/proc/array.c index 81884a281..d12a577fa 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -157,7 +157,7 @@ static inline char * task_state(struct task_struct *p, char *buffer) "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), - p->pid, p->p_opptr->pid, p->p_pptr->pid != p->p_opptr->pid ? p->p_opptr->pid : 0, + p->pid, p->p_opptr->pid, p->p_pptr->pid != p->p_opptr->pid ? p->p_pptr->pid : 0, p->uid, p->euid, p->suid, p->fsuid, p->gid, p->egid, p->sgid, p->fsgid); read_unlock(&tasklist_lock); @@ -575,7 +575,7 @@ ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char * goto getlen_out; /* Check whether the mmaps could change if we sleep */ - volatile_task = (task != current || atomic_read(&mm->mm_users) > 1); + volatile_task = (task != current || atomic_read(&mm->mm_users) > 2); /* decode f_pos */ lineno = *ppos >> MAPS_LINE_SHIFT; diff --git a/fs/proc/base.c b/fs/proc/base.c index 7625e4d5a..a1f7efe0f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -347,6 +347,10 @@ static ssize_t mem_read(struct file * file, char * buf, return copied; } +#define mem_write NULL + +#ifndef mem_write +/* This is a security hazard */ static ssize_t mem_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { @@ -385,6 +389,7 @@ static ssize_t mem_write(struct file * file, const char * buf, free_page((unsigned long) page); return copied; } +#endif static struct file_operations proc_mem_operations = { read: mem_read, diff --git a/fs/super.c b/fs/super.c index fb5c5895c..4f2e3908a 100644 --- a/fs/super.c +++ b/fs/super.c @@ -884,24 +884,27 @@ static struct super_block *get_sb_single(struct file_system_type *fs_type, return sb; } -static struct block_device *kill_super(struct super_block *sb, int umount_root) +static void kill_super(struct super_block *sb, int umount_root) { struct block_device *bdev; kdev_t dev; struct dentry *root = sb->s_root; + struct file_system_type *fs = sb->s_type; + struct super_operations *sop = sb->s_op; + sb->s_root = NULL; /* Need to clean after the sucker */ - if (sb->s_type->fs_flags & FS_LITTER) + if (fs->fs_flags & FS_LITTER) d_genocide(root); - if (sb->s_type->fs_flags & (FS_SINGLE|FS_LITTER)) + if (fs->fs_flags & (FS_SINGLE|FS_LITTER)) shrink_dcache_parent(root); dput(root); lock_super(sb); - if (sb->s_op) { - if (sb->s_op->write_super && sb->s_dirt) - sb->s_op->write_super(sb); - if (sb->s_op->put_super) - sb->s_op->put_super(sb); + if (sop) { + if (sop->write_super && sb->s_dirt) + sop->write_super(sb); + if (sop->put_super) + sop->put_super(sb); } /* Forget any remaining inodes */ @@ -914,7 +917,7 @@ static struct block_device *kill_super(struct super_block *sb, int umount_root) sb->s_dev = 0; /* Free the superblock */ bdev = sb->s_bdev; sb->s_bdev = NULL; - put_filesystem(sb->s_type); + put_filesystem(fs); sb->s_type = NULL; unlock_super(sb); if (umount_root) { @@ -928,7 +931,6 @@ static struct block_device *kill_super(struct super_block *sb, int umount_root) bdput(bdev); } else put_unnamed_dev(dev); - return bdev; } /* diff --git a/fs/umsdos/inode.c b/fs/umsdos/inode.c index 4aebe9bda..4b661b5af 100644 --- a/fs/umsdos/inode.c +++ b/fs/umsdos/inode.c @@ -22,8 +22,8 @@ extern struct dentry_operations umsdos_dentry_operations; -struct dentry *saved_root = NULL; /* Original root if changed */ -struct inode *pseudo_root = NULL; /* Useful to simulate the pseudo DOS */ +struct dentry *saved_root; /* Original root if changed */ +struct inode *pseudo_root; /* Useful to simulate the pseudo DOS */ /* directory. See UMSDOS_readdir_x() */ static struct dentry *check_pseudo_root(struct super_block *); diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 0ac6d5314..1f4829709 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -618,12 +618,11 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls, sz = len; ext_start = NULL; } - break; + goto stop0; } } - if (charbuf[chi] == '.') - break; } +stop0:; if (ext_start == name - 1) { sz = len; ext_start = NULL; @@ -640,10 +639,12 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls, if (chl == 0) break; for (chi = 0; chi < chl; chi++) - if (!strchr(skip_chars, charbuf[chi])) - break; + if (!strchr(skip_chars, charbuf[chi])) { + goto stop1; + } name_start++; } +stop1:; if (name_start != ext_start) { sz = ext_start - name; ext_start++; diff --git a/include/asm-alpha/byteorder.h b/include/asm-alpha/byteorder.h index e574bb6e7..edc376a04 100644 --- a/include/asm-alpha/byteorder.h +++ b/include/asm-alpha/byteorder.h @@ -3,52 +3,6 @@ #include <asm/types.h> -/* EGCS 1.1 can, without scheduling, do just as good as we do here - with the standard macros. And since it can schedule, it does even - better in the end. */ - -#if defined(__GNUC__) && __GNUC_MINOR__ < 91 - -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) -{ - __u64 t1, t2, t3; - - /* Break the final or's out of the block so that gcc can - schedule them at will. Further, use add not or so that - we elide the sign extend gcc will put in because the - return type is not a long. */ - - __asm__( - "insbl %3,3,%1 # %1 = dd000000\n\t" - "zapnot %3,2,%2 # %2 = 0000cc00\n\t" - "sll %2,8,%2 # %2 = 00cc0000\n\t" - "or %2,%1,%1 # %1 = ddcc0000\n\t" - "zapnot %3,4,%2 # %2 = 00bb0000\n\t" - "extbl %3,3,%0 # %0 = 000000aa\n\t" - "srl %2,8,%2 # %2 = 0000bb00" - : "=r"(t3), "=&r"(t1), "=&r"(t2) - : "r"(x)); - - return t3 + t2 + t1; -} - -static __inline__ __const__ __u16 ___arch__swab16(__u16 x) -{ - __u64 t1, t2; - - __asm__( - "insbl %2,1,%1 # %1 = bb00\n\t" - "extbl %2,1,%0 # %0 = 00aa" - : "=r"(t1), "=&r"(t2) : "r"(x)); - - return t1 | t2; -} - -#define __arch__swab32(x) ___arch__swab32(x) -#define __arch__swab16(x) ___arch__swab16(x) - -#endif /* __GNUC__ */ - #define __BYTEORDER_HAS_U64__ #include <linux/byteorder/little_endian.h> diff --git a/include/asm-alpha/compiler.h b/include/asm-alpha/compiler.h index d3b2808e8..70d6ce775 100644 --- a/include/asm-alpha/compiler.h +++ b/include/asm-alpha/compiler.h @@ -9,11 +9,7 @@ * these tests and macros. */ -/* - * EGCS (of varying versions) does a good job of using insxl and extxl. - */ - -#if 0 && (__GNUC__ > 2 || __GNUC_MINOR__ >= 91) +#if 0 #define __kernel_insbl(val, shift) \ (((unsigned long)(val) & 0xfful) << ((shift) * 8)) #define __kernel_inswl(val, shift) \ diff --git a/include/asm-alpha/fcntl.h b/include/asm-alpha/fcntl.h index 86a73667f..292765efa 100644 --- a/include/asm-alpha/fcntl.h +++ b/include/asm-alpha/fcntl.h @@ -48,7 +48,7 @@ #define F_EXLCK 16 /* or 3 */ #define F_SHLCK 32 /* or 4 */ -#define F_INPROGRESS 16 +#define F_INPROGRESS 64 /* operations for bsd flock(), also used by the kernel implementation */ #define LOCK_SH 1 /* shared lock */ diff --git a/include/asm-alpha/pgalloc.h b/include/asm-alpha/pgalloc.h index dc23ef74d..dd09a2eec 100644 --- a/include/asm-alpha/pgalloc.h +++ b/include/asm-alpha/pgalloc.h @@ -80,7 +80,7 @@ ev5_flush_tlb_current(struct mm_struct *mm) __load_new_mm_context(mm); } -extern inline void +static inline void flush_tlb_other(struct mm_struct *mm) { mm->context = 0; @@ -234,27 +234,13 @@ extern struct pgtable_cache_struct { #define pte_quicklist (quicklists.pte_cache) #define pgtable_cache_size (quicklists.pgtable_cache_sz) -extern __inline__ pgd_t *get_pgd_slow(void) -{ - pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init; - - if (ret) { - init = pgd_offset(&init_mm, 0UL); - memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); - memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - - pgd_val(ret[PTRS_PER_PGD]) - = pte_val(mk_pte(virt_to_page(ret), PAGE_KERNEL)); - } - return ret; -} +extern pgd_t *get_pgd_slow(void); -extern __inline__ pgd_t *get_pgd_fast(void) +static inline pgd_t *get_pgd_fast(void) { unsigned long *ret; - if((ret = pgd_quicklist) != NULL) { + if ((ret = pgd_quicklist) != NULL) { pgd_quicklist = (unsigned long *)(*ret); ret[0] = ret[1]; pgtable_cache_size--; @@ -263,25 +249,25 @@ extern __inline__ pgd_t *get_pgd_fast(void) return (pgd_t *)ret; } -extern __inline__ void free_pgd_fast(pgd_t *pgd) +static inline void free_pgd_fast(pgd_t *pgd) { *(unsigned long *)pgd = (unsigned long) pgd_quicklist; pgd_quicklist = (unsigned long *) pgd; pgtable_cache_size++; } -extern __inline__ void free_pgd_slow(pgd_t *pgd) +static inline void free_pgd_slow(pgd_t *pgd) { free_page((unsigned long)pgd); } extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_premasked); -extern __inline__ pmd_t *get_pmd_fast(void) +static inline pmd_t *get_pmd_fast(void) { unsigned long *ret; - if((ret = (unsigned long *)pte_quicklist) != NULL) { + if ((ret = (unsigned long *)pte_quicklist) != NULL) { pte_quicklist = (unsigned long *)(*ret); ret[0] = ret[1]; pgtable_cache_size--; @@ -289,25 +275,25 @@ extern __inline__ pmd_t *get_pmd_fast(void) return (pmd_t *)ret; } -extern __inline__ void free_pmd_fast(pmd_t *pmd) +static inline void free_pmd_fast(pmd_t *pmd) { *(unsigned long *)pmd = (unsigned long) pte_quicklist; pte_quicklist = (unsigned long *) pmd; pgtable_cache_size++; } -extern __inline__ void free_pmd_slow(pmd_t *pmd) +static inline void free_pmd_slow(pmd_t *pmd) { free_page((unsigned long)pmd); } extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); -extern __inline__ pte_t *get_pte_fast(void) +static inline pte_t *get_pte_fast(void) { unsigned long *ret; - if((ret = (unsigned long *)pte_quicklist) != NULL) { + if ((ret = (unsigned long *)pte_quicklist) != NULL) { pte_quicklist = (unsigned long *)(*ret); ret[0] = ret[1]; pgtable_cache_size--; @@ -315,14 +301,14 @@ extern __inline__ pte_t *get_pte_fast(void) return (pte_t *)ret; } -extern __inline__ void free_pte_fast(pte_t *pte) +static inline void free_pte_fast(pte_t *pte) { *(unsigned long *)pte = (unsigned long) pte_quicklist; pte_quicklist = (unsigned long *) pte; pgtable_cache_size++; } -extern __inline__ void free_pte_slow(pte_t *pte) +static inline void free_pte_slow(pte_t *pte) { free_page((unsigned long)pte); } @@ -337,7 +323,7 @@ extern void __bad_pmd(pgd_t *pgd); #define pgd_free(pgd) free_pgd_fast(pgd) #define pgd_alloc() get_pgd_fast() -extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address) +static inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); if (pmd_none(*pmd)) { @@ -355,7 +341,7 @@ extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address) return (pte_t *) pmd_page(*pmd) + address; } -extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) +static inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) { address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); if (pgd_none(*pgd)) { @@ -378,20 +364,4 @@ extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) extern int do_check_pgt_cache(int, int); -extern inline void set_pgdir(unsigned long address, pgd_t entry) -{ - struct task_struct * p; - pgd_t *pgd; - - read_lock(&tasklist_lock); - for_each_task(p) { - if (!p->mm) - continue; - *pgd_offset(p->mm,address) = entry; - } - read_unlock(&tasklist_lock); - for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[(address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)] = entry; -} - #endif /* _ALPHA_PGALLOC_H */ diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h index d68e18332..5c4373d3b 100644 --- a/include/asm-alpha/pgtable.h +++ b/include/asm-alpha/pgtable.h @@ -33,22 +33,23 @@ /* * Entries per page directory level: the Alpha is three-level, with * all levels having a one-page page table. - * - * The PGD is special: the last entry is reserved for self-mapping. */ #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) #define PTRS_PER_PMD (1UL << (PAGE_SHIFT-3)) -#define PTRS_PER_PGD ((1UL << (PAGE_SHIFT-3))-1) +#define PTRS_PER_PGD (1UL << (PAGE_SHIFT-3)) #define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 /* Number of pointers that fit on a page: this will go away. */ #define PTRS_PER_PAGE (1UL << (PAGE_SHIFT-3)) -#define CONSOLE_REMAP_START 0xFFFFFE0000000000 -#define VMALLOC_START (CONSOLE_REMAP_START + PMD_SIZE) +#ifdef CONFIG_ALPHA_LARGE_VMALLOC +#define VMALLOC_START 0xfffffe0000000000 +#else +#define VMALLOC_START (-2*PGDIR_SIZE) +#endif #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END (~0UL) +#define VMALLOC_END (-PGDIR_SIZE) /* * OSF/1 PAL-code-imposed page table bits @@ -260,7 +261,7 @@ extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; retu #define pgd_offset_k(address) pgd_offset(&init_mm, address) /* to find an entry in a page-table-directory. */ -#define pgd_index(address) ((address >> PGDIR_SHIFT) & PTRS_PER_PGD) +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) #define __pgd_offset(address) pgd_index(address) #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) @@ -319,4 +320,6 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) extern void paging_init(void); +#include <asm-generic/pgtable.h> + #endif /* _ALPHA_PGTABLE_H */ diff --git a/include/asm-alpha/string.h b/include/asm-alpha/string.h index 2b9cf9438..9e44fea66 100644 --- a/include/asm-alpha/string.h +++ b/include/asm-alpha/string.h @@ -18,28 +18,19 @@ extern void * memmove(void *, const void *, size_t); /* For backward compatibility with modules. Unused otherwise. */ extern void * __memcpy(void *, const void *, size_t); -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 #define memcpy __builtin_memcpy -#endif #define __HAVE_ARCH_MEMSET extern void * __constant_c_memset(void *, unsigned long, size_t); extern void * __memset(void *, int, size_t); extern void * memset(void *, int, size_t); -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 #define memset(s, c, n) \ (__builtin_constant_p(c) \ ? (__builtin_constant_p(n) && (c) == 0 \ ? __builtin_memset((s),0,(n)) \ : __constant_c_memset((s),0x0101010101010101UL*(unsigned char)(c),(n))) \ : __memset((s),(c),(n))) -#else -#define memset(s, c, n) \ -(__builtin_constant_p(c) \ - ? __constant_c_memset((s),0x0101010101010101UL*(unsigned char)(c),(n)) \ - : __memset((s),(c),(n))) -#endif #define __HAVE_ARCH_STRCPY extern char * strcpy(char *,const char *); diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index b97d0c5b6..6d34c5472 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -36,6 +36,7 @@ #define START_ADDR (PAGE_OFFSET+KERNEL_START_PHYS+0x10000) #ifndef __ASSEMBLY__ +#include <linux/kernel.h> /* * This is the logout header that should be common to all platforms diff --git a/include/asm-alpha/unaligned.h b/include/asm-alpha/unaligned.h index 8017f6bfa..1ec3e969e 100644 --- a/include/asm-alpha/unaligned.h +++ b/include/asm-alpha/unaligned.h @@ -31,59 +31,20 @@ struct __una_u16 { __u16 x __attribute__((packed)); }; extern inline unsigned long __uldq(const unsigned long * r11) { -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 const struct __una_u64 *ptr = (const struct __una_u64 *) r11; return ptr->x; -#else - unsigned long r1,r2; - __asm__("ldq_u %0,%3\n\t" - "ldq_u %1,%4\n\t" - "extql %0,%2,%0\n\t" - "extqh %1,%2,%1" - :"=&r" (r1), "=&r" (r2) - :"r" (r11), - "m" (*r11), - "m" (*(const unsigned long *)(7+(char *) r11))); - return r1 | r2; -#endif } extern inline unsigned long __uldl(const unsigned int * r11) { -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 const struct __una_u32 *ptr = (const struct __una_u32 *) r11; return ptr->x; -#else - unsigned long r1,r2; - __asm__("ldq_u %0,%3\n\t" - "ldq_u %1,%4\n\t" - "extll %0,%2,%0\n\t" - "extlh %1,%2,%1" - :"=&r" (r1), "=&r" (r2) - :"r" (r11), - "m" (*r11), - "m" (*(const unsigned long *)(3+(char *) r11))); - return r1 | r2; -#endif } extern inline unsigned long __uldw(const unsigned short * r11) { -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 const struct __una_u16 *ptr = (const struct __una_u16 *) r11; return ptr->x; -#else - unsigned long r1,r2; - __asm__("ldq_u %0,%3\n\t" - "ldq_u %1,%4\n\t" - "extwl %0,%2,%0\n\t" - "extwh %1,%2,%1" - :"=&r" (r1), "=&r" (r2) - :"r" (r11), - "m" (*r11), - "m" (*(const unsigned long *)(1+(char *) r11))); - return r1 | r2; -#endif } /* @@ -92,77 +53,20 @@ extern inline unsigned long __uldw(const unsigned short * r11) extern inline void __ustq(unsigned long r5, unsigned long * r11) { -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 struct __una_u64 *ptr = (struct __una_u64 *) r11; ptr->x = r5; -#else - unsigned long r1,r2,r3,r4; - - __asm__("ldq_u %3,%1\n\t" - "ldq_u %2,%0\n\t" - "insqh %6,%7,%5\n\t" - "insql %6,%7,%4\n\t" - "mskqh %3,%7,%3\n\t" - "mskql %2,%7,%2\n\t" - "bis %3,%5,%3\n\t" - "bis %2,%4,%2\n\t" - "stq_u %3,%1\n\t" - "stq_u %2,%0" - :"=m" (*r11), - "=m" (*(unsigned long *)(7+(char *) r11)), - "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) - :"r" (r5), "r" (r11)); -#endif } extern inline void __ustl(unsigned long r5, unsigned int * r11) { -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 struct __una_u32 *ptr = (struct __una_u32 *) r11; ptr->x = r5; -#else - unsigned long r1,r2,r3,r4; - - __asm__("ldq_u %3,%1\n\t" - "ldq_u %2,%0\n\t" - "inslh %6,%7,%5\n\t" - "insll %6,%7,%4\n\t" - "msklh %3,%7,%3\n\t" - "mskll %2,%7,%2\n\t" - "bis %3,%5,%3\n\t" - "bis %2,%4,%2\n\t" - "stq_u %3,%1\n\t" - "stq_u %2,%0" - :"=m" (*r11), - "=m" (*(unsigned long *)(3+(char *) r11)), - "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) - :"r" (r5), "r" (r11)); -#endif } extern inline void __ustw(unsigned long r5, unsigned short * r11) { -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 struct __una_u16 *ptr = (struct __una_u16 *) r11; ptr->x = r5; -#else - unsigned long r1,r2,r3,r4; - - __asm__("ldq_u %3,%1\n\t" - "ldq_u %2,%0\n\t" - "inswh %6,%7,%5\n\t" - "inswl %6,%7,%4\n\t" - "mskwh %3,%7,%3\n\t" - "mskwl %2,%7,%2\n\t" - "bis %3,%5,%3\n\t" - "bis %2,%4,%2\n\t" - "stq_u %3,%1\n\t" - "stq_u %2,%0" - :"=m" (*r11), - "=m" (*(unsigned long *)(1+(char *) r11)), - "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) - :"r" (r5), "r" (r11)); -#endif } extern inline unsigned long __get_unaligned(const void *ptr, size_t size) diff --git a/include/asm-arm/byteorder.h b/include/asm-arm/byteorder.h index 60a191cc3..f1e1d78ae 100644 --- a/include/asm-arm/byteorder.h +++ b/include/asm-arm/byteorder.h @@ -3,43 +3,6 @@ #include <asm/types.h> -#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ < 8 - -/* Recent versions of GCC can open code the swaps at least as well - as we can write them by hand, so the "optimisations" here only - make sense for older compilers. Worse, some versions of GCC - actually go wrong in the presence of the assembler versions. - We play it safe and only turn them on for compilers older than - GCC 2.8.0. */ - -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) -{ - unsigned long xx; - __asm__("eor\t%1, %0, %0, ror #16\n\t" - "bic\t%1, %1, #0xff0000\n\t" - "mov\t%0, %0, ror #8\n\t" - "eor\t%0, %0, %1, lsr #8\n\t" - : "=r" (x), "=&r" (xx) - : "0" (x)); - return x; -} - -static __inline__ __const__ __u16 ___arch__swab16(__u16 x) -{ - __asm__("eor\t%0, %0, %0, lsr #8\n\t" - "eor\t%0, %0, %0, lsl #8\n\t" - "bic\t%0, %0, #0xff0000\n\t" - "eor\t%0, %0, %0, lsr #8\n\t" - : "=r" (x) - : "0" (x)); - return x; -} - -#define __arch__swab32(x) ___arch__swab32(x) -#define __arch__swab16(x) ___arch__swab16(x) - -#endif /* __GNUC__ */ - #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) # define __BYTEORDER_HAS_U64__ # define __SWAB_64_THRU_32__ diff --git a/include/asm-arm/current.h b/include/asm-arm/current.h index 3a06c2a8a..597a8773c 100644 --- a/include/asm-arm/current.h +++ b/include/asm-arm/current.h @@ -1,11 +1,7 @@ #ifndef _ASMARM_CURRENT_H #define _ASMARM_CURRENT_H -/* Old compilers seem to generate bad code if we allow `current' to be - non volatile. */ -#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 90) static inline struct task_struct *get_current(void) __attribute__ (( __const__ )); -#endif static inline struct task_struct *get_current(void) { diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h index a18b26035..09c7421cc 100644 --- a/include/asm-arm/pgtable.h +++ b/include/asm-arm/pgtable.h @@ -185,6 +185,8 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; #define io_remap_page_range remap_page_range +#include <asm-generic/pgtable.h> + #endif /* !__ASSEMBLY__ */ #endif /* _ASMARM_PGTABLE_H */ diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h new file mode 100644 index 000000000..a65546820 --- /dev/null +++ b/include/asm-generic/pgtable.h @@ -0,0 +1,43 @@ +#ifndef _ASM_GENERIC_PGTABLE_H +#define _ASM_GENERIC_PGTABLE_H + +static inline int ptep_test_and_clear_young(pte_t *ptep) +{ + pte_t pte = *ptep; + if (!pte_young(pte)) + return 0; + set_pte(ptep, pte_mkold(pte)); + return 1; +} + +static inline int ptep_test_and_clear_dirty(pte_t *ptep) +{ + pte_t pte = *ptep; + if (!pte_dirty(pte)) + return 0; + set_pte(ptep, pte_mkclean(pte)); + return 1; +} + +static inline pte_t ptep_get_and_clear(pte_t *ptep) +{ + pte_t pte = *ptep; + pte_clear(ptep); + return pte; +} + +static inline void ptep_clear_wrprotect(pte_t *ptep) +{ + pte_t old_pte = *ptep; + set_pte(ptep, pte_wrprotect(old_pte)); +} + +static inline void ptep_mkdirty(pte_t *ptep) +{ + pte_t old_pte = *ptep; + set_pte(ptep, pte_mkdirty(old_pte)); +} + +#define pte_same(A,B) (pte_val(A) == pte_val(B)) + +#endif /* _ASM_GENERIC_PGTABLE_H */ diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h index 008a3d47d..4b95d09cd 100644 --- a/include/asm-i386/bugs.h +++ b/include/asm-i386/bugs.h @@ -94,7 +94,6 @@ static void __init check_fpu(void) printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... "); set_in_cr4(X86_CR4_OSXMMEXCPT); printk("done.\n"); - load_mxcsr(0x1f80); } #endif @@ -166,6 +165,7 @@ __asm__(".align 4\nvide: ret"); static void __init check_amd_k6(void) { if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 == 5 && boot_cpu_data.x86_model == 6 && boot_cpu_data.x86_mask == 1) { @@ -426,5 +426,5 @@ static void __init check_bugs(void) check_pentium_f00f(); #endif check_cyrix_coma(); - system_utsname.machine[1] = '0' + boot_cpu_data.x86; + system_utsname.machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); } diff --git a/include/asm-i386/cache.h b/include/asm-i386/cache.h index de4a7a87c..615911e5b 100644 --- a/include/asm-i386/cache.h +++ b/include/asm-i386/cache.h @@ -6,7 +6,8 @@ #include <linux/config.h> -/* bytes per L1 cache line */ -#define L1_CACHE_BYTES CONFIG_X86_L1_CACHE_BYTES +/* L1 cache line size */ +#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #endif diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h index de59b793a..55ffacff1 100644 --- a/include/asm-i386/elf.h +++ b/include/asm-i386/elf.h @@ -93,7 +93,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t; For the moment, we have only optimizations for the Intel generations, but that could change... */ -#define ELF_PLATFORM ("i386\0i486\0i586\0i686"+((boot_cpu_data.x86-3)*5)) +#define ELF_PLATFORM ("i386\0i486\0i586\0i686"+(((boot_cpu_data.x86>6?6:boot_cpu_data.x86)-3)*5)) #ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) diff --git a/include/asm-i386/floppy.h b/include/asm-i386/floppy.h index 04a41eb58..641fa495a 100644 --- a/include/asm-i386/floppy.h +++ b/include/asm-i386/floppy.h @@ -45,11 +45,11 @@ #define FLOPPY_CAN_FALLBACK_ON_NODMA -static int virtual_dma_count=0; -static int virtual_dma_residue=0; -static char *virtual_dma_addr=0; -static int virtual_dma_mode=0; -static int doing_pdma=0; +static int virtual_dma_count; +static int virtual_dma_residue; +static char *virtual_dma_addr; +static int virtual_dma_mode; +static int doing_pdma; static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs) { diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h index ec7650841..f8ebabe1b 100644 --- a/include/asm-i386/i387.h +++ b/include/asm-i386/i387.h @@ -16,16 +16,16 @@ #include <asm/sigcontext.h> #include <asm/user.h> +extern void init_fpu(void); /* * FPU lazy state save handling... */ -extern void save_fpu( struct task_struct *tsk ); extern void save_init_fpu( struct task_struct *tsk ); extern void restore_fpu( struct task_struct *tsk ); #define unlazy_fpu( tsk ) do { \ if ( tsk->flags & PF_USEDFPU ) \ - save_fpu( tsk ); \ + save_init_fpu( tsk ); \ } while (0) #define clear_fpu( tsk ) do { \ diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index 03b2ba400..8272b8f29 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -37,20 +37,20 @@ * These are used to make use of C type-checking.. */ #if CONFIG_X86_PAE -typedef struct { unsigned long long pte; } pte_t; +typedef struct { unsigned long pte_low, pte_high; } pte_t; typedef struct { unsigned long long pmd; } pmd_t; typedef struct { unsigned long long pgd; } pgd_t; -#define PTE_MASK (~(unsigned long long) (PAGE_SIZE-1)) +#define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) #else -typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pte_low; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; -#define PTE_MASK PAGE_MASK +#define pte_val(x) ((x).pte_low) #endif +#define PTE_MASK PAGE_MASK typedef struct { unsigned long pgprot; } pgprot_t; -#define pte_val(x) ((x).pte) #define pmd_val(x) ((x).pmd) #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h index ae818a9ab..ae1edc8d4 100644 --- a/include/asm-i386/param.h +++ b/include/asm-i386/param.h @@ -20,4 +20,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ +#endif + #endif diff --git a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h index 74c9b3798..64a9a7f68 100644 --- a/include/asm-i386/pgalloc.h +++ b/include/asm-i386/pgalloc.h @@ -152,33 +152,6 @@ fix: extern int do_check_pgt_cache(int, int); -extern inline void set_pgdir(unsigned long address, pgd_t entry) -{ - struct task_struct * p; - pgd_t *pgd; -#ifdef CONFIG_SMP - int i; -#endif - - read_lock(&tasklist_lock); - for_each_task(p) { - if (!p->mm) - continue; - *pgd_offset(p->mm,address) = entry; - } - read_unlock(&tasklist_lock); -#ifndef CONFIG_SMP - for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; -#else - /* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can - modify pgd caches of other CPUs as well. -jj */ - for (i = 0; i < NR_CPUS; i++) - for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; -#endif -} - /* * TLB flushing: * diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h index dbb12f801..bb5c2077e 100644 --- a/include/asm-i386/pgtable-2level.h +++ b/include/asm-i386/pgtable-2level.h @@ -18,7 +18,7 @@ #define PTRS_PER_PTE 1024 #define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low) #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ @@ -54,5 +54,10 @@ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { return (pmd_t *) dir; } +#define ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte_low, 0)) +#define pte_same(a, b) ((a).pte_low == (b).pte_low) +#define pte_page(x) (mem_map+((unsigned long)(((x).pte_low >> PAGE_SHIFT)))) +#define pte_none(x) (!(x).pte_low) +#define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot)) #endif /* _I386_PGTABLE_2LEVEL_H */ diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h index 5ee848ef3..aac1e3121 100644 --- a/include/asm-i386/pgtable-3level.h +++ b/include/asm-i386/pgtable-3level.h @@ -27,7 +27,7 @@ #define PTRS_PER_PTE 512 #define pte_ERROR(e) \ - printk("%s:%d: bad pte %p(%016Lx).\n", __FILE__, __LINE__, &(e), pte_val(e)) + printk("%s:%d: bad pte %p(%08lx%08lx).\n", __FILE__, __LINE__, &(e), (e).pte_high, (e).pte_low) #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pmd_val(e)) #define pgd_ERROR(e) \ @@ -45,8 +45,18 @@ extern inline int pgd_bad(pgd_t pgd) { return 0; } extern inline int pgd_present(pgd_t pgd) { return !pgd_none(pgd); } -#define set_pte(pteptr,pteval) \ - set_64bit((unsigned long long *)(pteptr),pte_val(pteval)) +/* Rules for using set_pte: the pte being assigned *must* be + * either not present or in a state where the hardware will + * not attempt to update the pte. In places where this is + * not possible, use pte_get_and_clear to obtain the old pte + * value and then use set_pte to update it. -ben + */ +static inline void set_pte(pte_t *ptep, pte_t pte) +{ + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} #define set_pmd(pmdptr,pmdval) \ set_64bit((unsigned long long *)(pmdptr),pmd_val(pmdval)) #define set_pgd(pgdptr,pgdval) \ @@ -76,4 +86,33 @@ extern inline void pgd_clear (pgd_t * pgd) #define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \ __pmd_offset(address)) +static inline pte_t ptep_get_and_clear(pte_t *ptep) +{ + pte_t res; + + /* xchg acts as a barrier before the setting of the high bits */ + res.pte_low = xchg(&ptep->pte_low, 0); + res.pte_high = ptep->pte_high; + ptep->pte_high = 0; + + return res; +} + +static inline int pte_same(pte_t a, pte_t b) +{ + return a.pte_low == b.pte_low && a.pte_high == b.pte_high; +} + +#define pte_page(x) (mem_map+(((x).pte_low >> PAGE_SHIFT) | ((x).pte_high << (32 - PAGE_SHIFT)))) +#define pte_none(x) (!(x).pte_low && !(x).pte_high) + +static inline pte_t __mk_pte(unsigned long page_nr, pgprot_t pgprot) +{ + pte_t pte; + + pte.pte_high = page_nr >> (32 - PAGE_SHIFT); + pte.pte_low = (page_nr << PAGE_SHIFT) | pgprot_val(pgprot); + return pte; +} + #endif /* _I386_PGTABLE_3LEVEL_H */ diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 4de265da0..5460e6ccc 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -17,6 +17,10 @@ #include <asm/fixmap.h> #include <linux/threads.h> +#ifndef _I386_BITOPS_H +#include <asm/bitops.h> +#endif + extern pgd_t swapper_pg_dir[1024]; extern void paging_init(void); @@ -145,6 +149,16 @@ extern unsigned long empty_zero_page[1024]; * the page directory entry points directly to a 4MB-aligned block of * memory. */ +#define _PAGE_BIT_PRESENT 0 +#define _PAGE_BIT_RW 1 +#define _PAGE_BIT_USER 2 +#define _PAGE_BIT_PWT 3 +#define _PAGE_BIT_PCD 4 +#define _PAGE_BIT_ACCESSED 5 +#define _PAGE_BIT_DIRTY 6 +#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page, Pentium+, if present.. */ +#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ + #define _PAGE_PRESENT 0x001 #define _PAGE_RW 0x002 #define _PAGE_USER 0x004 @@ -231,8 +245,7 @@ extern unsigned long pg0[1024]; extern void __handle_bad_pmd(pmd_t * pmd); extern void __handle_bad_pmd_kernel(pmd_t * pmd); -#define pte_none(x) (!pte_val(x)) -#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) +#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) #define pte_clear(xp) do { set_pte(xp, __pte(0)); } while (0) #define pmd_none(x) (!pmd_val(x)) @@ -246,49 +259,49 @@ extern void __handle_bad_pmd_kernel(pmd_t * pmd); */ #define page_address(page) ((page)->virtual) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) -#define pte_page(x) (mem_map+((unsigned long)((pte_val(x) >> PAGE_SHIFT)))) /* * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } - -extern inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; } -extern inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; } -extern inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; } -extern inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; } -extern inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; } -extern inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } -extern inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } -extern inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } -extern inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } -extern inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } +static inline int pte_read(pte_t pte) { return (pte).pte_low & _PAGE_USER; } +static inline int pte_exec(pte_t pte) { return (pte).pte_low & _PAGE_USER; } +static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; } +static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; } + +static inline pte_t pte_rdprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; } +static inline pte_t pte_exprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; } +static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; } +static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; } +static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; } +static inline pte_t pte_mkexec(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; } + +static inline int ptep_test_and_clear_dirty(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep); } +static inline int ptep_test_and_clear_young(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep); } +static inline void ptep_clear_wrprotect(pte_t *ptep) { clear_bit(_PAGE_BIT_RW, ptep); } +static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_RW, ptep); } /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -#define mk_pte(page,pgprot) \ -({ \ - pte_t __pte; \ - \ - set_pte(&__pte, __pte(((page)-mem_map) * \ - (unsigned long long)PAGE_SIZE + pgprot_val(pgprot))); \ - __pte; \ -}) +#define mk_pte(page, pgprot) __mk_pte((page) - mem_map, (pgprot)) /* This takes a physical page address that is used by the remapping functions */ -#define mk_pte_phys(physpage, pgprot) \ -({ pte_t __pte; set_pte(&__pte, __pte(physpage + pgprot_val(pgprot))); __pte; }) +#define mk_pte_phys(physpage, pgprot) __mk_pte((physpage) >> PAGE_SHIFT, pgprot) -extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; } +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte.pte_low &= _PAGE_CHG_MASK; + pte.pte_low |= pgprot_val(newprot); + return pte; +} #define page_pte(page) page_pte_prot(page, __pgprot(0)) @@ -324,7 +337,7 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define SWP_TYPE(x) (((x).val >> 1) & 0x3f) #define SWP_OFFSET(x) ((x).val >> 8) #define SWP_ENTRY(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) -#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low }) #define swp_entry_to_pte(x) ((pte_t) { (x).val }) #define module_map vmalloc diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 769269192..76ac26cae 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -85,7 +85,7 @@ struct cpuinfo_x86 { #define X86_FEATURE_CMOV 0x00008000 /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ #define X86_FEATURE_PAT 0x00010000 /* Page Attribute Table */ #define X86_FEATURE_PSE36 0x00020000 /* 36-bit PSEs */ -#define X86_FEATURE_18 0x00040000 +#define X86_FEATURE_PN 0x00040000 #define X86_FEATURE_19 0x00080000 #define X86_FEATURE_20 0x00100000 #define X86_FEATURE_21 0x00200000 diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h index 6a52f4e76..207d5a104 100644 --- a/include/asm-i386/ptrace.h +++ b/include/asm-i386/ptrace.h @@ -49,6 +49,11 @@ struct pt_regs { #define PTRACE_GETFPXREGS 18 #define PTRACE_SETFPXREGS 19 +#define PTRACE_SETOPTIONS 21 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + #ifdef __KERNEL__ #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) #define instruction_pointer(regs) ((regs)->eip) diff --git a/include/asm-i386/user.h b/include/asm-i386/user.h index dcd555159..ddc06ea01 100644 --- a/include/asm-i386/user.h +++ b/include/asm-i386/user.h @@ -48,8 +48,8 @@ struct user_i387_struct { long twd; long fip; long fcs; - long fdp; - long fds; + long foo; + long fos; long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ }; diff --git a/include/asm-ia64/acpi-ext.h b/include/asm-ia64/acpi-ext.h index 24f9822e6..e5acd26a5 100644 --- a/include/asm-ia64/acpi-ext.h +++ b/include/asm-ia64/acpi-ext.h @@ -60,7 +60,7 @@ typedef struct { #define LSAPIC_PERFORMANCE_RESTRICTED (1<<1) #define LSAPIC_PRESENT (1<<2) -typedef struct { +typedef struct acpi_entry_lsapic { u8 type; u8 length; u16 acpi_processor_id; diff --git a/include/asm-ia64/acpikcfg.h b/include/asm-ia64/acpikcfg.h new file mode 100644 index 000000000..1bf49cf01 --- /dev/null +++ b/include/asm-ia64/acpikcfg.h @@ -0,0 +1,29 @@ +/* + * acpikcfg.h - ACPI based Kernel Configuration Manager External Interfaces + * + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee <jung-ik.lee@intel.com> + */ + +#include <linux/config.h> + +#ifdef CONFIG_ACPI_KERNEL_CONFIG + +u32 __init acpi_cf_init (void * rsdp); +u32 __init acpi_cf_terminate (void ); + +u32 __init +acpi_cf_get_pci_vectors ( + struct pci_vector_struct **vectors, + int *num_pci_vectors + ); + + +#ifdef CONFIG_ACPI_KERNEL_CONFIG_DEBUG +void __init +acpi_cf_print_pci_vectors ( + struct pci_vector_struct *vectors, + int num_pci_vectors + ); +#endif +#endif /* CONFIG_ACPI_KERNEL_CONFIG */ diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h index 43a44f4ad..08fc25c57 100644 --- a/include/asm-ia64/atomic.h +++ b/include/asm-ia64/atomic.h @@ -17,13 +17,6 @@ #include <asm/system.h> /* - * Make sure gcc doesn't try to be clever and move things around - * on us. We need to use _exactly_ the address the user gave us, - * not some alias that contains the same information. - */ -#define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x) - -/* * On IA-64, counter must always be volatile to ensure that that the * memory accesses are ordered. */ diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h index 054704c47..33da4a962 100644 --- a/include/asm-ia64/bitops.h +++ b/include/asm-ia64/bitops.h @@ -20,7 +20,7 @@ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). */ -extern __inline__ void +static __inline__ void set_bit (int nr, volatile void *addr) { __u32 bit, old, new; @@ -36,7 +36,12 @@ set_bit (int nr, volatile void *addr) } while (cmpxchg_acq(m, old, new) != old); } -extern __inline__ void +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() +static __inline__ void clear_bit (int nr, volatile void *addr) { __u32 mask, old, new; @@ -52,7 +57,7 @@ clear_bit (int nr, volatile void *addr) } while (cmpxchg_acq(m, old, new) != old); } -extern __inline__ void +static __inline__ void change_bit (int nr, volatile void *addr) { __u32 bit, old, new; @@ -68,7 +73,7 @@ change_bit (int nr, volatile void *addr) } while (cmpxchg_acq(m, old, new) != old); } -extern __inline__ int +static __inline__ int test_and_set_bit (int nr, volatile void *addr) { __u32 bit, old, new; @@ -85,7 +90,7 @@ test_and_set_bit (int nr, volatile void *addr) return (old & bit) != 0; } -extern __inline__ int +static __inline__ int test_and_clear_bit (int nr, volatile void *addr) { __u32 mask, old, new; @@ -102,7 +107,7 @@ test_and_clear_bit (int nr, volatile void *addr) return (old & ~mask) != 0; } -extern __inline__ int +static __inline__ int test_and_change_bit (int nr, volatile void *addr) { __u32 bit, old, new; @@ -119,7 +124,7 @@ test_and_change_bit (int nr, volatile void *addr) return (old & bit) != 0; } -extern __inline__ int +static __inline__ int test_bit (int nr, volatile void *addr) { return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31)); @@ -129,7 +134,7 @@ test_bit (int nr, volatile void *addr) * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. */ -extern inline unsigned long +static inline unsigned long ffz (unsigned long x) { unsigned long result; @@ -164,7 +169,7 @@ ia64_fls (unsigned long x) * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ -extern __inline__ unsigned long +static __inline__ unsigned long hweight64 (unsigned long x) { unsigned long result; @@ -181,7 +186,7 @@ hweight64 (unsigned long x) /* * Find next zero bit in a bitmap reasonably efficiently.. */ -extern inline int +static inline int find_next_zero_bit (void *addr, unsigned long size, unsigned long offset) { unsigned long *p = ((unsigned long *) addr) + (offset >> 6); diff --git a/include/asm-ia64/delay.h b/include/asm-ia64/delay.h index cca4ecdf6..dda714e20 100644 --- a/include/asm-ia64/delay.h +++ b/include/asm-ia64/delay.h @@ -18,13 +18,13 @@ #include <asm/processor.h> -extern __inline__ void +static __inline__ void ia64_set_itm (unsigned long val) { __asm__ __volatile__("mov cr.itm=%0;; srlz.d;;" :: "r"(val) : "memory"); } -extern __inline__ unsigned long +static __inline__ unsigned long ia64_get_itm (void) { unsigned long result; @@ -33,7 +33,7 @@ ia64_get_itm (void) return result; } -extern __inline__ void +static __inline__ void ia64_set_itv (unsigned char vector, unsigned char masked) { if (masked > 1) @@ -43,13 +43,13 @@ ia64_set_itv (unsigned char vector, unsigned char masked) :: "r"((masked << 16) | vector) : "memory"); } -extern __inline__ void +static __inline__ void ia64_set_itc (unsigned long val) { __asm__ __volatile__("mov ar.itc=%0;; srlz.d;;" :: "r"(val) : "memory"); } -extern __inline__ unsigned long +static __inline__ unsigned long ia64_get_itc (void) { unsigned long result; @@ -58,7 +58,7 @@ ia64_get_itc (void) return result; } -extern __inline__ void +static __inline__ void __delay (unsigned long loops) { unsigned long saved_ar_lc; @@ -72,7 +72,7 @@ __delay (unsigned long loops) __asm__ __volatile__("mov ar.lc=%0" :: "r"(saved_ar_lc)); } -extern __inline__ void +static __inline__ void udelay (unsigned long usecs) { #ifdef CONFIG_IA64_SOFTSDV_HACKS diff --git a/include/asm-ia64/efi.h b/include/asm-ia64/efi.h index 5d311d32e..cfdfd4efd 100644 --- a/include/asm-ia64/efi.h +++ b/include/asm-ia64/efi.h @@ -219,7 +219,7 @@ extern struct efi { efi_reset_system_t *reset_system; } efi; -extern inline int +static inline int efi_guidcmp (efi_guid_t left, efi_guid_t right) { return memcmp(&left, &right, sizeof (efi_guid_t)); diff --git a/include/asm-ia64/fcntl.h b/include/asm-ia64/fcntl.h index c20ab10ec..eeb42f793 100644 --- a/include/asm-ia64/fcntl.h +++ b/include/asm-ia64/fcntl.h @@ -3,8 +3,8 @@ /* * This is mostly compatible with Linux/x86. * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> + * Copyright (C) 1998-2000 Hewlett-Packard Co + * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com> */ /* @@ -78,5 +78,9 @@ struct flock { pid_t l_pid; }; +#ifdef __KERNEL__ +# define flock64 flock +#endif + #define F_LINUX_SPECIFIC_BASE 1024 #endif /* _ASM_IA64_FCNTL_H */ diff --git a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h index 38a12be6e..7c1a4d109 100644 --- a/include/asm-ia64/hardirq.h +++ b/include/asm-ia64/hardirq.h @@ -39,8 +39,8 @@ typedef struct { # define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) # define hardirq_endlock(cpu) do { } while (0) -# define irq_enter(cpu, irq) (++local_irq_count(cpu)) -# define irq_exit(cpu, irq) (--local_irq_count(cpu)) +# define irq_enter(cpu, irq) (local_irq_count(cpu)++) +# define irq_exit(cpu, irq) (local_irq_count(cpu)--) # define synchronize_irq() barrier() #else @@ -72,7 +72,7 @@ static inline void release_irqlock(int cpu) static inline void irq_enter(int cpu, int irq) { - ++local_irq_count(cpu); + local_irq_count(cpu)++; while (test_bit(0,&global_irq_lock)) { /* nothing */; @@ -81,7 +81,7 @@ static inline void irq_enter(int cpu, int irq) static inline void irq_exit(int cpu, int irq) { - --local_irq_count(cpu); + local_irq_count(cpu)--; } static inline int hardirq_trylock(int cpu) diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h index e4dd5c1ee..06528f8d2 100644 --- a/include/asm-ia64/hw_irq.h +++ b/include/asm-ia64/hw_irq.h @@ -6,8 +6,6 @@ * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com> */ -#include <linux/config.h> - #include <linux/types.h> #include <asm/ptrace.h> @@ -67,17 +65,7 @@ extern void ipi_send (int cpu, int vector, int delivery_mode, int redirect); static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector) { - int my_cpu_id; - -#ifdef CONFIG_SMP - my_cpu_id = smp_processor_id(); -#else - __u64 lid; - - __asm__ ("mov %0=cr.lid" : "=r"(lid)); - my_cpu_id = (lid >> 24) & 0xff; /* extract id (ignore eid) */ -#endif - ipi_send(my_cpu_id, vector, IA64_IPI_DM_INT, 0); + ipi_send(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); } #endif /* _ASM_IA64_HW_IRQ_H */ diff --git a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h index c6732837c..48a6d0bd4 100644 --- a/include/asm-ia64/ia32.h +++ b/include/asm-ia64/ia32.h @@ -351,6 +351,8 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; (granularity << IA32_SEG_G) | \ (((base >> 24) & 0xFF) << IA32_SEG_HIGH_BASE)) +#define IA32_IOBASE 0x2000000000000000 /* Virtual addres for I/O space */ + #define IA32_CR0 0x80000001 /* Enable PG and PE bits */ #define IA32_CR4 0 /* No architectural extensions */ diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h index 0740af45f..3dcc496fa 100644 --- a/include/asm-ia64/io.h +++ b/include/asm-ia64/io.h @@ -63,16 +63,15 @@ phys_to_virt(unsigned long address) */ #define __ia64_mf_a() __asm__ __volatile__ ("mf.a" ::: "memory") -extern inline const unsigned long +static inline const unsigned long __ia64_get_io_port_base (void) { - unsigned long addr; + extern unsigned long ia64_iobase; - __asm__ ("mov %0=ar.k0;;" : "=r"(addr)); - return __IA64_UNCACHED_OFFSET | addr; + return ia64_iobase; } -extern inline void* +static inline void* __ia64_mk_io_addr (unsigned long port) { const unsigned long io_base = __ia64_get_io_port_base(); @@ -100,7 +99,7 @@ __ia64_mk_io_addr (unsigned long port) * order. --davidm 99/12/07 */ -extern inline unsigned int +static inline unsigned int __inb (unsigned long port) { volatile unsigned char *addr = __ia64_mk_io_addr(port); @@ -111,7 +110,7 @@ __inb (unsigned long port) return ret; } -extern inline unsigned int +static inline unsigned int __inw (unsigned long port) { volatile unsigned short *addr = __ia64_mk_io_addr(port); @@ -122,7 +121,7 @@ __inw (unsigned long port) return ret; } -extern inline unsigned int +static inline unsigned int __inl (unsigned long port) { volatile unsigned int *addr = __ia64_mk_io_addr(port); @@ -133,7 +132,7 @@ __inl (unsigned long port) return ret; } -extern inline void +static inline void __insb (unsigned long port, void *dst, unsigned long count) { volatile unsigned char *addr = __ia64_mk_io_addr(port); @@ -147,7 +146,7 @@ __insb (unsigned long port, void *dst, unsigned long count) return; } -extern inline void +static inline void __insw (unsigned long port, void *dst, unsigned long count) { volatile unsigned short *addr = __ia64_mk_io_addr(port); @@ -161,7 +160,7 @@ __insw (unsigned long port, void *dst, unsigned long count) return; } -extern inline void +static inline void __insl (unsigned long port, void *dst, unsigned long count) { volatile unsigned int *addr = __ia64_mk_io_addr(port); @@ -175,7 +174,7 @@ __insl (unsigned long port, void *dst, unsigned long count) return; } -extern inline void +static inline void __outb (unsigned char val, unsigned long port) { volatile unsigned char *addr = __ia64_mk_io_addr(port); @@ -184,7 +183,7 @@ __outb (unsigned char val, unsigned long port) __ia64_mf_a(); } -extern inline void +static inline void __outw (unsigned short val, unsigned long port) { volatile unsigned short *addr = __ia64_mk_io_addr(port); @@ -193,7 +192,7 @@ __outw (unsigned short val, unsigned long port) __ia64_mf_a(); } -extern inline void +static inline void __outl (unsigned int val, unsigned long port) { volatile unsigned int *addr = __ia64_mk_io_addr(port); @@ -202,7 +201,7 @@ __outl (unsigned int val, unsigned long port) __ia64_mf_a(); } -extern inline void +static inline void __outsb (unsigned long port, const void *src, unsigned long count) { volatile unsigned char *addr = __ia64_mk_io_addr(port); @@ -215,7 +214,7 @@ __outsb (unsigned long port, const void *src, unsigned long count) return; } -extern inline void +static inline void __outsw (unsigned long port, const void *src, unsigned long count) { volatile unsigned short *addr = __ia64_mk_io_addr(port); @@ -228,7 +227,7 @@ __outsw (unsigned long port, const void *src, unsigned long count) return; } -extern inline void +static inline void __outsl (unsigned long port, void *src, unsigned long count) { volatile unsigned int *addr = __ia64_mk_io_addr(port); @@ -257,49 +256,49 @@ __outsl (unsigned long port, void *src, unsigned long count) /* * The address passed to these functions are ioremap()ped already. */ -extern inline unsigned char +static inline unsigned char __readb (void *addr) { return *(volatile unsigned char *)addr; } -extern inline unsigned short +static inline unsigned short __readw (void *addr) { return *(volatile unsigned short *)addr; } -extern inline unsigned int +static inline unsigned int __readl (void *addr) { return *(volatile unsigned int *) addr; } -extern inline unsigned long +static inline unsigned long __readq (void *addr) { return *(volatile unsigned long *) addr; } -extern inline void +static inline void __writeb (unsigned char val, void *addr) { *(volatile unsigned char *) addr = val; } -extern inline void +static inline void __writew (unsigned short val, void *addr) { *(volatile unsigned short *) addr = val; } -extern inline void +static inline void __writel (unsigned int val, void *addr) { *(volatile unsigned int *) addr = val; } -extern inline void +static inline void __writeq (unsigned long val, void *addr) { *(volatile unsigned long *) addr = val; diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h index c50eacaf0..f385b15cb 100644 --- a/include/asm-ia64/mmu_context.h +++ b/include/asm-ia64/mmu_context.h @@ -57,7 +57,7 @@ enter_lazy_tlb (struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { } -extern inline unsigned long +static inline unsigned long ia64_rid (unsigned long context, unsigned long region_addr) { # ifdef CONFIG_IA64_TLB_CHECKS_REGION_NUMBER @@ -67,7 +67,7 @@ ia64_rid (unsigned long context, unsigned long region_addr) # endif } -extern inline void +static inline void get_new_mmu_context (struct mm_struct *mm) { spin_lock(&ia64_ctx.lock); @@ -80,7 +80,7 @@ get_new_mmu_context (struct mm_struct *mm) } -extern inline void +static inline void get_mmu_context (struct mm_struct *mm) { /* check if our ASN is of an older generation and thus invalid: */ @@ -88,20 +88,20 @@ get_mmu_context (struct mm_struct *mm) get_new_mmu_context(mm); } -extern inline int +static inline int init_new_context (struct task_struct *p, struct mm_struct *mm) { mm->context = 0; return 0; } -extern inline void +static inline void destroy_context (struct mm_struct *mm) { /* Nothing to do. */ } -extern inline void +static inline void reload_context (struct mm_struct *mm) { unsigned long rid; diff --git a/include/asm-ia64/module.h b/include/asm-ia64/module.h new file mode 100644 index 000000000..d8d19cb2f --- /dev/null +++ b/include/asm-ia64/module.h @@ -0,0 +1,108 @@ +#ifndef _ASM_IA64_MODULE_H +#define _ASM_IA64_MODULE_H +/* + * This file contains the ia64 architecture specific module code. + * + * Copyright (C) 2000 Intel Corporation. + * Copyright (C) 2000 Mike Stephens <mike.stephens@intel.com> + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/vmalloc.h> +#include <asm/unwind.h> + +#define module_map(x) vmalloc(x) +#define module_unmap(x) ia64_module_unmap(x) +#define module_arch_init(x) ia64_module_init(x) + +/* + * This must match in size and layout the data created by + * modutils/obj/obj-ia64.c + */ +struct archdata { + const char *unw_table; + const char *segment_base; + const char *unw_start; + const char *unw_end; + const char *gp; +}; + +/* + * functions to add/remove a modules unwind info when + * it is loaded or unloaded. + */ +static inline int +ia64_module_init(struct module *mod) +{ +#ifdef CONFIG_IA64_NEW_UNWIND + struct archdata *archdata; + + if (!mod_member_present(mod, archdata_start) || !mod->archdata_start) + return 0; + archdata = (struct archdata *)(mod->archdata_start); + + /* + * Make sure the unwind pointers are sane. + */ + + if (archdata->unw_table) + { + printk(KERN_ERR "arch_init_module: archdata->unw_table must be zero.\n"); + return 1; + } + if (!mod_bound(archdata->gp, 0, mod)) + { + printk(KERN_ERR "arch_init_module: archdata->gp out of bounds.\n"); + return 1; + } + if (!mod_bound(archdata->unw_start, 0, mod)) + { + printk(KERN_ERR "arch_init_module: archdata->unw_start out of bounds.\n"); + return 1; + } + if (!mod_bound(archdata->unw_end, 0, mod)) + { + printk(KERN_ERR "arch_init_module: archdata->unw_end out of bounds.\n"); + return 1; + } + if (!mod_bound(archdata->segment_base, 0, mod)) + { + printk(KERN_ERR "arch_init_module: archdata->unw_table out of bounds.\n"); + return 1; + } + + /* + * Pointers are reasonable, add the module unwind table + */ + archdata->unw_table = unw_add_unwind_table(mod->name, archdata->segment_base, + (unsigned long) archdata->gp, + (unsigned long) archdata->unw_start, + (unsigned long) archdata->unw_end); +#endif /* CONFIG_IA64_NEW_UNWIND */ + return 0; +} + +static inline void +ia64_module_unmap(void * addr) +{ +#ifdef CONFIG_IA64_NEW_UNWIND + struct module *mod = (struct module *) addr; + struct archdata *archdata; + + /* + * Before freeing the module memory remove the unwind table entry + */ + if (mod_member_present(mod, archdata_start) && mod->archdata_start) + { + archdata = (struct archdata *)(mod->archdata_start); + + if (archdata->unw_table != NULL) + unw_remove_unwind_table(archdata->unw_table); + } +#endif /* CONFIG_IA64_NEW_UNWIND */ + + vfree(addr); +} + +#endif /* _ASM_IA64_MODULE_H */ diff --git a/include/asm-ia64/offsets.h b/include/asm-ia64/offsets.h index 88cad88d5..64e9f2fef 100644 --- a/include/asm-ia64/offsets.h +++ b/include/asm-ia64/offsets.h @@ -11,7 +11,7 @@ #define PT_PTRACED_BIT 0 #define PT_TRACESYS_BIT 1 -#define IA64_TASK_SIZE 2864 /* 0xb30 */ +#define IA64_TASK_SIZE 3328 /* 0xd00 */ #define IA64_PT_REGS_SIZE 400 /* 0x190 */ #define IA64_SWITCH_STACK_SIZE 560 /* 0x230 */ #define IA64_SIGINFO_SIZE 128 /* 0x80 */ @@ -21,9 +21,9 @@ #define IA64_TASK_SIGPENDING_OFFSET 16 /* 0x10 */ #define IA64_TASK_NEED_RESCHED_OFFSET 40 /* 0x28 */ #define IA64_TASK_PROCESSOR_OFFSET 100 /* 0x64 */ -#define IA64_TASK_THREAD_OFFSET 896 /* 0x380 */ -#define IA64_TASK_THREAD_KSP_OFFSET 896 /* 0x380 */ -#define IA64_TASK_THREAD_SIGMASK_OFFSET 2744 /* 0xab8 */ +#define IA64_TASK_THREAD_OFFSET 1424 /* 0x590 */ +#define IA64_TASK_THREAD_KSP_OFFSET 1424 /* 0x590 */ +#define IA64_TASK_THREAD_SIGMASK_OFFSET 3184 /* 0xc70 */ #define IA64_TASK_PID_OFFSET 188 /* 0xbc */ #define IA64_TASK_MM_OFFSET 88 /* 0x58 */ #define IA64_PT_REGS_CR_IPSR_OFFSET 0 /* 0x0 */ diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h index 62881b538..c81337e07 100644 --- a/include/asm-ia64/page.h +++ b/include/asm-ia64/page.h @@ -102,15 +102,13 @@ typedef unsigned long pgprot_t; #ifdef CONFIG_IA64_GENERIC # include <asm/machvec.h> # define virt_to_page(kaddr) (mem_map + platform_map_nr(kaddr)) -#elif defined (CONFIG_IA64_SN_SN1_SIM) +#elif defined (CONFIG_IA64_SN_SN1) # define virt_to_page(kaddr) (mem_map + MAP_NR_SN1(kaddr)) #else # define virt_to_page(kaddr) (mem_map + MAP_NR_DENSE(kaddr)) #endif #define VALID_PAGE(page) ((page - mem_map) < max_mapnr) -# endif /* __KERNEL__ */ - typedef union ia64_va { struct { unsigned long off : 61; /* intra-region offset */ @@ -138,7 +136,7 @@ typedef union ia64_va { #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) #define PAGE_BUG(page) do { BUG(); } while (0) -extern __inline__ int +static __inline__ int get_order (unsigned long size) { double d = size - 1; @@ -151,6 +149,7 @@ get_order (unsigned long size) return order; } +# endif /* __KERNEL__ */ #endif /* !ASSEMBLY */ #define PAGE_OFFSET 0xe000000000000000 diff --git a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h index d55b16253..ad3efe1ec 100644 --- a/include/asm-ia64/pal.h +++ b/include/asm-ia64/pal.h @@ -66,6 +66,7 @@ #define PAL_CACHE_PROT_INFO 38 /* get i/d cache protection info */ #define PAL_REGISTER_INFO 39 /* return AR and CR register information*/ #define PAL_SHUTDOWN 40 /* enter processor shutdown state */ +#define PAL_PREFETCH_VISIBILITY 41 #define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */ #define PAL_HALT_INFO 257 /* return the low power capabilities of processor */ @@ -644,15 +645,16 @@ struct ia64_pal_retval { * (generally 0) MUST be passed. Reserved parameters are not optional * parameters. */ -extern struct ia64_pal_retval ia64_pal_call_static (u64, u64, u64, u64); -extern struct ia64_pal_retval ia64_pal_call_stacked (u64, u64, u64, u64); -extern struct ia64_pal_retval ia64_pal_call_phys_static (u64, u64, u64, u64); -extern struct ia64_pal_retval ia64_pal_call_phys_stacked (u64, u64, u64, u64); +extern struct ia64_pal_retval ia64_pal_call_static (u64, u64, u64, u64, u64); +extern struct ia64_pal_retval ia64_pal_call_stacked (u64, u64, u64, u64); +extern struct ia64_pal_retval ia64_pal_call_phys_static (u64, u64, u64, u64); +extern struct ia64_pal_retval ia64_pal_call_phys_stacked (u64, u64, u64, u64); -#define PAL_CALL(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_static(a0, a1, a2, a3) -#define PAL_CALL_STK(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_stacked(a0, a1, a2, a3) -#define PAL_CALL_PHYS(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_phys_static(a0, a1, a2, a3) -#define PAL_CALL_PHYS_STK(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_phys_stacked(a0, a1, a2, a3) +#define PAL_CALL(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_static(a0, a1, a2, a3, 0) +#define PAL_CALL_IC_OFF(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_static(a0, a1, a2, a3, 1) +#define PAL_CALL_STK(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_stacked(a0, a1, a2, a3) +#define PAL_CALL_PHYS(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_phys_static(a0, a1, a2, a3) +#define PAL_CALL_PHYS_STK(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_phys_stacked(a0, a1, a2, a3) typedef int (*ia64_pal_handler) (u64, ...); extern ia64_pal_handler ia64_pal; @@ -706,7 +708,7 @@ typedef union pal_bus_features_u { extern void pal_bus_features_print (u64); /* Provide information about configurable processor bus features */ -extern inline s64 +static inline s64 ia64_pal_bus_get_features (pal_bus_features_u_t *features_avail, pal_bus_features_u_t *features_status, pal_bus_features_u_t *features_control) @@ -723,7 +725,7 @@ ia64_pal_bus_get_features (pal_bus_features_u_t *features_avail, } /* Enables/disables specific processor bus features */ -extern inline s64 +static inline s64 ia64_pal_bus_set_features (pal_bus_features_u_t feature_select) { struct ia64_pal_retval iprv; @@ -732,7 +734,7 @@ ia64_pal_bus_set_features (pal_bus_features_u_t feature_select) } /* Get detailed cache information */ -extern inline s64 +static inline s64 ia64_pal_cache_config_info (u64 cache_level, u64 cache_type, pal_cache_config_info_t *conf) { struct ia64_pal_retval iprv; @@ -750,7 +752,7 @@ ia64_pal_cache_config_info (u64 cache_level, u64 cache_type, pal_cache_config_in } /* Get detailed cche protection information */ -extern inline s64 +static inline s64 ia64_pal_cache_prot_info (u64 cache_level, u64 cache_type, pal_cache_protection_info_t *prot) { struct ia64_pal_retval iprv; @@ -773,18 +775,18 @@ ia64_pal_cache_prot_info (u64 cache_level, u64 cache_type, pal_cache_protection_ * Flush the processor instruction or data caches. *PROGRESS must be * initialized to zero before calling this for the first time.. */ -extern inline s64 +static inline s64 ia64_pal_cache_flush (u64 cache_type, u64 invalidate, u64 *progress) { struct ia64_pal_retval iprv; - PAL_CALL(iprv, PAL_CACHE_FLUSH, cache_type, invalidate, *progress); + PAL_CALL_IC_OFF(iprv, PAL_CACHE_FLUSH, cache_type, invalidate, *progress); *progress = iprv.v1; return iprv.status; } /* Initialize the processor controlled caches */ -extern inline s64 +static inline s64 ia64_pal_cache_init (u64 level, u64 cache_type, u64 restrict) { struct ia64_pal_retval iprv; @@ -796,7 +798,7 @@ ia64_pal_cache_init (u64 level, u64 cache_type, u64 restrict) * processor controlled cache to known values without the availability * of backing memory. */ -extern inline s64 +static inline s64 ia64_pal_cache_line_init (u64 physical_addr, u64 data_value) { struct ia64_pal_retval iprv; @@ -806,7 +808,7 @@ ia64_pal_cache_line_init (u64 physical_addr, u64 data_value) /* Read the data and tag of a processor controlled cache line for diags */ -extern inline s64 +static inline s64 ia64_pal_cache_read (pal_cache_line_id_u_t line_id, u64 physical_addr) { struct ia64_pal_retval iprv; @@ -815,7 +817,7 @@ ia64_pal_cache_read (pal_cache_line_id_u_t line_id, u64 physical_addr) } /* Return summary information about the heirarchy of caches controlled by the processor */ -extern inline s64 +static inline s64 ia64_pal_cache_summary (u64 *cache_levels, u64 *unique_caches) { struct ia64_pal_retval iprv; @@ -828,7 +830,7 @@ ia64_pal_cache_summary (u64 *cache_levels, u64 *unique_caches) } /* Write the data and tag of a processor-controlled cache line for diags */ -extern inline s64 +static inline s64 ia64_pal_cache_write (pal_cache_line_id_u_t line_id, u64 physical_addr, u64 data) { struct ia64_pal_retval iprv; @@ -838,7 +840,7 @@ ia64_pal_cache_write (pal_cache_line_id_u_t line_id, u64 physical_addr, u64 data /* Return the parameters needed to copy relocatable PAL procedures from ROM to memory */ -extern inline s64 +static inline s64 ia64_pal_copy_info (u64 copy_type, u64 num_procs, u64 num_iopics, u64 *buffer_size, u64 *buffer_align) { @@ -852,7 +854,7 @@ ia64_pal_copy_info (u64 copy_type, u64 num_procs, u64 num_iopics, } /* Copy relocatable PAL procedures from ROM to memory */ -extern inline s64 +static inline s64 ia64_pal_copy_pal (u64 target_addr, u64 alloc_size, u64 processor, u64 *pal_proc_offset) { struct ia64_pal_retval iprv; @@ -863,7 +865,7 @@ ia64_pal_copy_pal (u64 target_addr, u64 alloc_size, u64 processor, u64 *pal_proc } /* Return the number of instruction and data debug register pairs */ -extern inline s64 +static inline s64 ia64_pal_debug_info (u64 *inst_regs, u64 *data_regs) { struct ia64_pal_retval iprv; @@ -878,7 +880,7 @@ ia64_pal_debug_info (u64 *inst_regs, u64 *data_regs) #ifdef TBD /* Switch from IA64-system environment to IA-32 system environment */ -extern inline s64 +static inline s64 ia64_pal_enter_ia32_env (ia32_env1, ia32_env2, ia32_env3) { struct ia64_pal_retval iprv; @@ -888,7 +890,7 @@ ia64_pal_enter_ia32_env (ia32_env1, ia32_env2, ia32_env3) #endif /* Get unique geographical address of this processor on its bus */ -extern inline s64 +static inline s64 ia64_pal_fixed_addr (u64 *global_unique_addr) { struct ia64_pal_retval iprv; @@ -899,7 +901,7 @@ ia64_pal_fixed_addr (u64 *global_unique_addr) } /* Get base frequency of the platform if generated by the processor */ -extern inline s64 +static inline s64 ia64_pal_freq_base (u64 *platform_base_freq) { struct ia64_pal_retval iprv; @@ -913,7 +915,7 @@ ia64_pal_freq_base (u64 *platform_base_freq) * Get the ratios for processor frequency, bus frequency and interval timer to * to base frequency of the platform */ -extern inline s64 +static inline s64 ia64_pal_freq_ratios (struct pal_freq_ratio *proc_ratio, struct pal_freq_ratio *bus_ratio, struct pal_freq_ratio *itc_ratio) { @@ -932,7 +934,7 @@ ia64_pal_freq_ratios (struct pal_freq_ratio *proc_ratio, struct pal_freq_ratio * * power states where prefetching and execution are suspended and cache and * TLB coherency is not maintained. */ -extern inline s64 +static inline s64 ia64_pal_halt (u64 halt_state) { struct ia64_pal_retval iprv; @@ -952,7 +954,7 @@ typedef union pal_power_mgmt_info_u { } pal_power_mgmt_info_u_t; /* Return information about processor's optional power management capabilities. */ -extern inline s64 +static inline s64 ia64_pal_halt_info (pal_power_mgmt_info_u_t *power_buf) { struct ia64_pal_retval iprv; @@ -963,7 +965,7 @@ ia64_pal_halt_info (pal_power_mgmt_info_u_t *power_buf) /* Cause the processor to enter LIGHT HALT state, where prefetching and execution are * suspended, but cache and TLB coherency is maintained. */ -extern inline s64 +static inline s64 ia64_pal_halt_light (void) { struct ia64_pal_retval iprv; @@ -975,7 +977,7 @@ ia64_pal_halt_light (void) * the error logging registers to be written. This procedure also checks the pending * machine check bit and pending INIT bit and reports their states. */ -extern inline s64 +static inline s64 ia64_pal_mc_clear_log (u64 *pending_vector) { struct ia64_pal_retval iprv; @@ -988,7 +990,7 @@ ia64_pal_mc_clear_log (u64 *pending_vector) /* Ensure that all outstanding transactions in a processor are completed or that any * MCA due to thes outstanding transaction is taken. */ -extern inline s64 +static inline s64 ia64_pal_mc_drain (void) { struct ia64_pal_retval iprv; @@ -997,7 +999,7 @@ ia64_pal_mc_drain (void) } /* Return the machine check dynamic processor state */ -extern inline s64 +static inline s64 ia64_pal_mc_dynamic_state (u64 offset, u64 *size, u64 *pds) { struct ia64_pal_retval iprv; @@ -1010,7 +1012,7 @@ ia64_pal_mc_dynamic_state (u64 offset, u64 *size, u64 *pds) } /* Return processor machine check information */ -extern inline s64 +static inline s64 ia64_pal_mc_error_info (u64 info_index, u64 type_index, u64 *size, u64 *error_info) { struct ia64_pal_retval iprv; @@ -1025,7 +1027,7 @@ ia64_pal_mc_error_info (u64 info_index, u64 type_index, u64 *size, u64 *error_in /* Inform PALE_CHECK whether a machine check is expected so that PALE_CHECK willnot * attempt to correct any expected machine checks. */ -extern inline s64 +static inline s64 ia64_pal_mc_expected (u64 expected, u64 *previous) { struct ia64_pal_retval iprv; @@ -1039,7 +1041,7 @@ ia64_pal_mc_expected (u64 expected, u64 *previous) * minimal processor state in the event of a machine check or initialization * event. */ -extern inline s64 +static inline s64 ia64_pal_mc_register_mem (u64 physical_addr) { struct ia64_pal_retval iprv; @@ -1050,7 +1052,7 @@ ia64_pal_mc_register_mem (u64 physical_addr) /* Restore minimal architectural processor state, set CMC interrupt if necessary * and resume execution */ -extern inline s64 +static inline s64 ia64_pal_mc_resume (u64 set_cmci, u64 save_ptr) { struct ia64_pal_retval iprv; @@ -1059,7 +1061,7 @@ ia64_pal_mc_resume (u64 set_cmci, u64 save_ptr) } /* Return the memory attributes implemented by the processor */ -extern inline s64 +static inline s64 ia64_pal_mem_attrib (u64 *mem_attrib) { struct ia64_pal_retval iprv; @@ -1072,7 +1074,7 @@ ia64_pal_mem_attrib (u64 *mem_attrib) /* Return the amount of memory needed for second phase of processor * self-test and the required alignment of memory. */ -extern inline s64 +static inline s64 ia64_pal_mem_for_test (u64 *bytes_needed, u64 *alignment) { struct ia64_pal_retval iprv; @@ -1098,7 +1100,7 @@ typedef union pal_perf_mon_info_u { /* Return the performance monitor information about what can be counted * and how to configure the monitors to count the desired events. */ -extern inline s64 +static inline s64 ia64_pal_perf_mon_info (u64 *pm_buffer, pal_perf_mon_info_u_t *pm_info) { struct ia64_pal_retval iprv; @@ -1111,7 +1113,7 @@ ia64_pal_perf_mon_info (u64 *pm_buffer, pal_perf_mon_info_u_t *pm_info) /* Specifies the physical address of the processor interrupt block * and I/O port space. */ -extern inline s64 +static inline s64 ia64_pal_platform_addr (u64 type, u64 physical_addr) { struct ia64_pal_retval iprv; @@ -1120,7 +1122,7 @@ ia64_pal_platform_addr (u64 type, u64 physical_addr) } /* Set the SAL PMI entrypoint in memory */ -extern inline s64 +static inline s64 ia64_pal_pmi_entrypoint (u64 sal_pmi_entry_addr) { struct ia64_pal_retval iprv; @@ -1130,7 +1132,7 @@ ia64_pal_pmi_entrypoint (u64 sal_pmi_entry_addr) struct pal_features_s; /* Provide information about configurable processor features */ -extern inline s64 +static inline s64 ia64_pal_proc_get_features (u64 *features_avail, u64 *features_status, u64 *features_control) @@ -1146,7 +1148,7 @@ ia64_pal_proc_get_features (u64 *features_avail, } /* Enable/disable processor dependent features */ -extern inline s64 +static inline s64 ia64_pal_proc_set_features (u64 feature_select) { struct ia64_pal_retval iprv; @@ -1167,7 +1169,7 @@ typedef struct ia64_ptce_info_s { /* Return the information required for the architected loop used to purge * (initialize) the entire TC */ -extern inline s64 +static inline s64 ia64_get_ptce (ia64_ptce_info_t *ptce) { struct ia64_pal_retval iprv; @@ -1187,7 +1189,7 @@ ia64_get_ptce (ia64_ptce_info_t *ptce) } /* Return info about implemented application and control registers. */ -extern inline s64 +static inline s64 ia64_pal_register_info (u64 info_request, u64 *reg_info_1, u64 *reg_info_2) { struct ia64_pal_retval iprv; @@ -1211,7 +1213,7 @@ typedef union pal_hints_u { /* Return information about the register stack and RSE for this processor * implementation. */ -extern inline s64 +static inline s64 ia64_pal_rse_info (u64 *num_phys_stacked, pal_hints_u_t *hints) { struct ia64_pal_retval iprv; @@ -1227,7 +1229,7 @@ ia64_pal_rse_info (u64 *num_phys_stacked, pal_hints_u_t *hints) * suspended, but cause cache and TLB coherency to be maintained. * This is usually called in IA-32 mode. */ -extern inline s64 +static inline s64 ia64_pal_shutdown (void) { struct ia64_pal_retval iprv; @@ -1236,7 +1238,7 @@ ia64_pal_shutdown (void) } /* Perform the second phase of processor self-test. */ -extern inline s64 +static inline s64 ia64_pal_test_proc (u64 test_addr, u64 test_size, u64 attributes, u64 *self_test_state) { struct ia64_pal_retval iprv; @@ -1261,7 +1263,7 @@ typedef union pal_version_u { /* Return PAL version information */ -extern inline s64 +static inline s64 ia64_pal_version (pal_version_u_t *pal_min_version, pal_version_u_t *pal_cur_version) { struct ia64_pal_retval iprv; @@ -1299,7 +1301,7 @@ typedef union pal_tc_info_u { /* Return information about the virtual memory characteristics of the processor * implementation. */ -extern inline s64 +static inline s64 ia64_pal_vm_info (u64 tc_level, u64 tc_type, pal_tc_info_u_t *tc_info, u64 *tc_pages) { struct ia64_pal_retval iprv; @@ -1314,7 +1316,7 @@ ia64_pal_vm_info (u64 tc_level, u64 tc_type, pal_tc_info_u_t *tc_info, u64 *tc_ /* Get page size information about the virtual memory characteristics of the processor * implementation. */ -extern inline s64 +static inline s64 ia64_pal_vm_page_size (u64 *tr_pages, u64 *vw_pages) { struct ia64_pal_retval iprv; @@ -1353,7 +1355,7 @@ typedef union pal_vm_info_2_u { /* Get summary information about the virtual memory characteristics of the processor * implementation. */ -extern inline s64 +static inline s64 ia64_pal_vm_summary (pal_vm_info_1_u_t *vm_info_1, pal_vm_info_2_u_t *vm_info_2) { struct ia64_pal_retval iprv; @@ -1377,7 +1379,7 @@ typedef union pal_itr_valid_u { } pal_tr_valid_u_t; /* Read a translation register */ -extern inline s64 +static inline s64 ia64_pal_tr_read (u64 reg_num, u64 tr_type, u64 *tr_buffer, pal_tr_valid_u_t *tr_valid) { struct ia64_pal_retval iprv; @@ -1387,6 +1389,14 @@ ia64_pal_tr_read (u64 reg_num, u64 tr_type, u64 *tr_buffer, pal_tr_valid_u_t *tr return iprv.status; } +static inline s64 +ia64_pal_prefetch_visibility (void) +{ + struct ia64_pal_retval iprv; + PAL_CALL(iprv, PAL_PREFETCH_VISIBILITY, 0, 0, 0); + return iprv.status; +} + #endif /* __ASSEMBLY__ */ #endif /* _ASM_IA64_PAL_H */ diff --git a/include/asm-ia64/param.h b/include/asm-ia64/param.h index a410b8892..e8920ea76 100644 --- a/include/asm-ia64/param.h +++ b/include/asm-ia64/param.h @@ -15,7 +15,7 @@ * Yeah, simulating stuff is slow, so let us catch some breath between * timer interrupts... */ -# define HZ 20 +# define HZ 32 #else # define HZ 1024 #endif @@ -36,4 +36,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ +#endif + #endif /* _ASM_IA64_PARAM_H */ diff --git a/include/asm-ia64/parport.h b/include/asm-ia64/parport.h new file mode 100644 index 000000000..67e16adfc --- /dev/null +++ b/include/asm-ia64/parport.h @@ -0,0 +1,20 @@ +/* + * parport.h: platform-specific PC-style parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk> + * + * This file should only be included by drivers/parport/parport_pc.c. + */ + +#ifndef _ASM_IA64_PARPORT_H +#define _ASM_IA64_PARPORT_H 1 + +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); + +static int __devinit +parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + return parport_pc_find_isa_ports(autoirq, autodma); +} + +#endif /* _ASM_IA64_PARPORT_H */ diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index 01c038774..652aaffca 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h @@ -21,12 +21,12 @@ struct pci_dev; -extern inline void pcibios_set_master(struct pci_dev *dev) +static inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ } -extern inline void pcibios_penalize_isa_irq(int irq) +static inline void pcibios_penalize_isa_irq(int irq) { /* We don't do dynamic PCI IRQ allocation */ } @@ -127,7 +127,7 @@ extern void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int n * only drive the low 24-bits during PCI bus mastering, then * you would pass 0x00ffffff as the mask to this function. */ -extern inline int +static inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) { return 1; diff --git a/include/asm-ia64/pgalloc.h b/include/asm-ia64/pgalloc.h index 7c35de4bc..5256a4fff 100644 --- a/include/asm-ia64/pgalloc.h +++ b/include/asm-ia64/pgalloc.h @@ -32,7 +32,7 @@ #define pte_quicklist (my_cpu_data.pte_quick) #define pgtable_cache_size (my_cpu_data.pgtable_cache_sz) -extern __inline__ pgd_t* +static __inline__ pgd_t* get_pgd_slow (void) { pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL); @@ -41,7 +41,7 @@ get_pgd_slow (void) return ret; } -extern __inline__ pgd_t* +static __inline__ pgd_t* get_pgd_fast (void) { unsigned long *ret = pgd_quicklist; @@ -54,7 +54,7 @@ get_pgd_fast (void) return (pgd_t *)ret; } -extern __inline__ pgd_t* +static __inline__ pgd_t* pgd_alloc (void) { pgd_t *pgd; @@ -65,7 +65,7 @@ pgd_alloc (void) return pgd; } -extern __inline__ void +static __inline__ void free_pgd_fast (pgd_t *pgd) { *(unsigned long *)pgd = (unsigned long) pgd_quicklist; @@ -73,7 +73,7 @@ free_pgd_fast (pgd_t *pgd) ++pgtable_cache_size; } -extern __inline__ pmd_t * +static __inline__ pmd_t * get_pmd_slow (void) { pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL); @@ -83,7 +83,7 @@ get_pmd_slow (void) return pmd; } -extern __inline__ pmd_t * +static __inline__ pmd_t * get_pmd_fast (void) { unsigned long *ret = (unsigned long *)pmd_quicklist; @@ -96,7 +96,7 @@ get_pmd_fast (void) return (pmd_t *)ret; } -extern __inline__ void +static __inline__ void free_pmd_fast (pmd_t *pmd) { *(unsigned long *)pmd = (unsigned long) pmd_quicklist; @@ -104,7 +104,7 @@ free_pmd_fast (pmd_t *pmd) ++pgtable_cache_size; } -extern __inline__ void +static __inline__ void free_pmd_slow (pmd_t *pmd) { free_page((unsigned long)pmd); @@ -112,7 +112,7 @@ free_pmd_slow (pmd_t *pmd) extern pte_t *get_pte_slow (pmd_t *pmd, unsigned long address_preadjusted); -extern __inline__ pte_t * +static __inline__ pte_t * get_pte_fast (void) { unsigned long *ret = (unsigned long *)pte_quicklist; @@ -125,7 +125,7 @@ get_pte_fast (void) return (pte_t *)ret; } -extern __inline__ void +static __inline__ void free_pte_fast (pte_t *pte) { *(unsigned long *)pte = (unsigned long) pte_quicklist; @@ -142,7 +142,7 @@ free_pte_fast (pte_t *pte) extern void __handle_bad_pgd (pgd_t *pgd); extern void __handle_bad_pmd (pmd_t *pmd); -extern __inline__ pte_t* +static __inline__ pte_t* pte_alloc (pmd_t *pmd, unsigned long vmaddr) { unsigned long offset; @@ -163,7 +163,7 @@ pte_alloc (pmd_t *pmd, unsigned long vmaddr) return (pte_t *) pmd_page(*pmd) + offset; } -extern __inline__ pmd_t* +static __inline__ pmd_t* pmd_alloc (pgd_t *pgd, unsigned long vmaddr) { unsigned long offset; @@ -228,7 +228,7 @@ extern spinlock_t ptcg_lock; /* * Flush a specified user mapping */ -extern __inline__ void +static __inline__ void flush_tlb_mm (struct mm_struct *mm) { if (mm) { diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h index fcf340ee0..6fbed9cc1 100644 --- a/include/asm-ia64/pgtable.h +++ b/include/asm-ia64/pgtable.h @@ -3,9 +3,9 @@ /* * This file contains the functions and defines necessary to modify and use - * the ia-64 page table tree. + * the IA-64 page table tree. * - * This hopefully works with any (fixed) ia-64 page-size, as defined + * This hopefully works with any (fixed) IA-64 page-size, as defined * in <asm/page.h> (currently 8192). * * Copyright (C) 1998-2000 Hewlett-Packard Co @@ -19,12 +19,6 @@ #define IA64_MAX_PHYS_BITS 50 /* max. number of physical address bits (architected) */ -/* Is ADDR a valid kernel address? */ -#define kern_addr_valid(addr) ((addr) >= TASK_SIZE) - -/* Is ADDR a valid physical address? */ -#define phys_addr_valid(addr) (((addr) & my_cpu_data.unimpl_pa_mask) == 0) - /* * First, define the various bits in a PTE. Note that the PTE format * matches the VHPT short format, the firt doubleword of the VHPD long @@ -166,7 +160,7 @@ * Given a pointer to an mem_map[] entry, return the kernel virtual * address corresponding to that page. */ -#define page_address(page) ((void *) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))) +#define page_address(page) ((page)->virtual) /* * Now for some cache flushing routines. This is the kind of stuff @@ -190,6 +184,28 @@ do { \ ia64_flush_icache_page((unsigned long) page_address(pg)); \ } while (0) +/* Quick test to see if ADDR is a (potentially) valid physical address. */ +static __inline__ long +ia64_phys_addr_valid (unsigned long addr) +{ + return (addr & (my_cpu_data.unimpl_pa_mask)) == 0; +} + +/* + * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel + * memory. For the return value to be meaningful, ADDR must be >= + * PAGE_OFFSET. This operation can be relatively expensive (e.g., + * require a hash-, or multi-level tree-lookup or something of that + * sort) but it guarantees to return TRUE only if accessing the page + * at that address does not cause an error. Note that there may be + * addresses for which kern_addr_valid() returns FALSE even though an + * access would not cause an error (e.g., this is typically true for + * memory mapped I/O regions. + * + * XXX Need to implement this for IA-64. + */ +#define kern_addr_valid(addr) (1) + /* * Now come the defines and routines to manage and access the three-level * page table. @@ -248,14 +264,14 @@ extern pmd_t *ia64_bad_pagetable (void); #define pmd_set(pmdp, ptep) (pmd_val(*(pmdp)) = __pa(ptep)) #define pmd_none(pmd) (!pmd_val(pmd)) -#define pmd_bad(pmd) (!phys_addr_valid(pmd_val(pmd))) +#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd))) #define pmd_present(pmd) (pmd_val(pmd) != 0UL) #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) #define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & _PFN_MASK)) #define pgd_set(pgdp, pmdp) (pgd_val(*(pgdp)) = __pa(pmdp)) #define pgd_none(pgd) (!pgd_val(pgd)) -#define pgd_bad(pgd) (!phys_addr_valid(pgd_val(pgd))) +#define pgd_bad(pgd) (!ia64_phys_addr_valid(pgd_val(pgd))) #define pgd_present(pgd) (pgd_val(pgd) != 0UL) #define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL) #define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & _PFN_MASK)) @@ -301,7 +317,7 @@ extern pmd_t *ia64_bad_pagetable (void); /* * Return the region index for virtual address ADDRESS. */ -extern __inline__ unsigned long +static __inline__ unsigned long rgn_index (unsigned long address) { ia64_va a; @@ -313,7 +329,7 @@ rgn_index (unsigned long address) /* * Return the region offset for virtual address ADDRESS. */ -extern __inline__ unsigned long +static __inline__ unsigned long rgn_offset (unsigned long address) { ia64_va a; @@ -325,7 +341,7 @@ rgn_offset (unsigned long address) #define RGN_SIZE (1UL << 61) #define RGN_KERNEL 7 -extern __inline__ unsigned long +static __inline__ unsigned long pgd_index (unsigned long address) { unsigned long region = address >> 61; @@ -336,7 +352,7 @@ pgd_index (unsigned long address) /* The offset in the 1-level directory is given by the 3 region bits (61..63) and the seven level-1 bits (33-39). */ -extern __inline__ pgd_t* +static __inline__ pgd_t* pgd_offset (struct mm_struct *mm, unsigned long address) { return mm->pgd + pgd_index(address); @@ -409,9 +425,6 @@ do { \ #define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define swp_entry_to_pte(x) ((pte_t) { (x).val }) -#define module_map vmalloc -#define module_unmap vfree - /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ #define PageSkip(page) (0) @@ -421,9 +434,11 @@ do { \ * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. */ -extern unsigned long empty_zero_page[1024]; +extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) +#include <asm-generic/pgtable.h> + # endif /* !__ASSEMBLY__ */ #endif /* _ASM_IA64_PGTABLE_H */ diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index c37fc76b1..37a8c2ba4 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -253,9 +253,9 @@ struct cpuinfo_ia64 { #define my_cpu_data cpu_data[smp_processor_id()] #ifdef CONFIG_SMP -# define loops_per_sec() my_cpu_data.loops_per_sec +# define ia64_loops_per_sec() my_cpu_data.loops_per_sec #else -# define loops_per_sec() loops_per_sec +# define ia64_loops_per_sec() loops_per_sec #endif extern struct cpuinfo_ia64 cpu_data[NR_CPUS]; @@ -305,10 +305,11 @@ struct thread_struct { __u64 csd; /* IA32 code selector descriptor */ __u64 ssd; /* IA32 stack selector descriptor */ __u64 tssd; /* IA32 TSS descriptor */ + __u64 old_iob; /* old IOBase value */ union { __u64 sigmask; /* aligned mask for sigsuspend scall */ } un; -# define INIT_THREAD_IA32 , 0, 0, 0x17800000037fULL, 0, 0, 0, 0, 0, {0} +# define INIT_THREAD_IA32 , 0, 0, 0x17800000037fULL, 0, 0, 0, 0, 0, 0, {0} #else # define INIT_THREAD_IA32 #endif /* CONFIG_IA32_SUPPORT */ @@ -334,6 +335,8 @@ struct thread_struct { #define start_thread(regs,new_ip,new_sp) do { \ set_fs(USER_DS); \ + ia64_psr(regs)->dfh = 1; /* disable fph */ \ + ia64_psr(regs)->mfh = 0; /* clear mfh */ \ ia64_psr(regs)->cpl = 3; /* set user mode */ \ ia64_psr(regs)->ri = 0; /* clear return slot number */ \ ia64_psr(regs)->is = 0; /* IA-64 instruction set */ \ @@ -390,6 +393,8 @@ extern unsigned long get_wchan (struct task_struct *p); /* Return stack pointer of blocked task TSK. */ #define KSTK_ESP(tsk) ((tsk)->thread.ksp) +#ifndef CONFIG_SMP + static inline struct task_struct * ia64_get_fpu_owner (void) { @@ -404,6 +409,8 @@ ia64_set_fpu_owner (struct task_struct *t) __asm__ __volatile__ ("mov ar.k5=%0" :: "r"(t)); } +#endif /* !CONFIG_SMP */ + extern void __ia64_init_fpu (void); extern void __ia64_save_fpu (struct ia64_fpreg *fph); extern void __ia64_load_fpu (struct ia64_fpreg *fph); @@ -447,31 +454,31 @@ ia64_load_fpu (struct ia64_fpreg *fph) { ia64_fph_disable(); } -extern inline void +static inline void ia64_fc (void *addr) { __asm__ __volatile__ ("fc %0" :: "r"(addr) : "memory"); } -extern inline void +static inline void ia64_sync_i (void) { __asm__ __volatile__ (";; sync.i" ::: "memory"); } -extern inline void +static inline void ia64_srlz_i (void) { __asm__ __volatile__ (";; srlz.i ;;" ::: "memory"); } -extern inline void +static inline void ia64_srlz_d (void) { __asm__ __volatile__ (";; srlz.d" ::: "memory"); } -extern inline __u64 +static inline __u64 ia64_get_rr (__u64 reg_bits) { __u64 r; @@ -479,13 +486,13 @@ ia64_get_rr (__u64 reg_bits) return r; } -extern inline void +static inline void ia64_set_rr (__u64 reg_bits, __u64 rr_val) { __asm__ __volatile__ ("mov rr[%0]=%1" :: "r"(reg_bits), "r"(rr_val) : "memory"); } -extern inline __u64 +static inline __u64 ia64_get_dcr (void) { __u64 r; @@ -493,14 +500,14 @@ ia64_get_dcr (void) return r; } -extern inline void +static inline void ia64_set_dcr (__u64 val) { __asm__ __volatile__ ("mov cr.dcr=%0;;" :: "r"(val) : "memory"); ia64_srlz_d(); } -extern inline __u64 +static inline __u64 ia64_get_lid (void) { __u64 r; @@ -508,7 +515,7 @@ ia64_get_lid (void) return r; } -extern inline void +static inline void ia64_invala (void) { __asm__ __volatile__ ("invala" ::: "memory"); @@ -526,7 +533,7 @@ ia64_invala (void) * Insert a translation into an instruction and/or data translation * register. */ -extern inline void +static inline void ia64_itr (__u64 target_mask, __u64 tr_num, __u64 vmaddr, __u64 pte, __u64 log_page_size) @@ -545,7 +552,7 @@ ia64_itr (__u64 target_mask, __u64 tr_num, * Insert a translation into the instruction and/or data translation * cache. */ -extern inline void +static inline void ia64_itc (__u64 target_mask, __u64 vmaddr, __u64 pte, __u64 log_page_size) { @@ -562,7 +569,7 @@ ia64_itc (__u64 target_mask, __u64 vmaddr, __u64 pte, * Purge a range of addresses from instruction and/or data translation * register(s). */ -extern inline void +static inline void ia64_ptr (__u64 target_mask, __u64 vmaddr, __u64 log_size) { if (target_mask & 0x1) @@ -572,21 +579,21 @@ ia64_ptr (__u64 target_mask, __u64 vmaddr, __u64 log_size) } /* Set the interrupt vector address. The address must be suitably aligned (32KB). */ -extern inline void +static inline void ia64_set_iva (void *ivt_addr) { __asm__ __volatile__ ("mov cr.iva=%0;; srlz.i;;" :: "r"(ivt_addr) : "memory"); } /* Set the page table address and control bits. */ -extern inline void +static inline void ia64_set_pta (__u64 pta) { /* Note: srlz.i implies srlz.d */ __asm__ __volatile__ ("mov cr.pta=%0;; srlz.i;;" :: "r"(pta) : "memory"); } -extern inline __u64 +static inline __u64 ia64_get_cpuid (__u64 regnum) { __u64 r; @@ -595,13 +602,13 @@ ia64_get_cpuid (__u64 regnum) return r; } -extern inline void +static inline void ia64_eoi (void) { __asm__ ("mov cr.eoi=r0;; srlz.d;;" ::: "memory"); } -extern __inline__ void +static inline void ia64_set_lrr0 (__u8 vector, __u8 masked) { if (masked > 1) @@ -612,7 +619,7 @@ ia64_set_lrr0 (__u8 vector, __u8 masked) } -extern __inline__ void +static inline void ia64_set_lrr1 (__u8 vector, __u8 masked) { if (masked > 1) @@ -622,13 +629,13 @@ ia64_set_lrr1 (__u8 vector, __u8 masked) :: "r"((masked << 16) | vector) : "memory"); } -extern __inline__ void +static inline void ia64_set_pmv (__u64 val) { __asm__ __volatile__ ("mov cr.pmv=%0" :: "r"(val) : "memory"); } -extern __inline__ __u64 +static inline __u64 ia64_get_pmc (__u64 regnum) { __u64 retval; @@ -637,13 +644,13 @@ ia64_get_pmc (__u64 regnum) return retval; } -extern __inline__ void +static inline void ia64_set_pmc (__u64 regnum, __u64 value) { __asm__ __volatile__ ("mov pmc[%0]=%1" :: "r"(regnum), "r"(value)); } -extern __inline__ __u64 +static inline __u64 ia64_get_pmd (__u64 regnum) { __u64 retval; @@ -652,7 +659,7 @@ ia64_get_pmd (__u64 regnum) return retval; } -extern __inline__ void +static inline void ia64_set_pmd (__u64 regnum, __u64 value) { __asm__ __volatile__ ("mov pmd[%0]=%1" :: "r"(regnum), "r"(value)); @@ -662,7 +669,7 @@ ia64_set_pmd (__u64 regnum, __u64 value) * Given the address to which a spill occurred, return the unat bit * number that corresponds to this address. */ -extern inline __u64 +static inline __u64 ia64_unat_pos (void *spill_addr) { return ((__u64) spill_addr >> 3) & 0x3f; @@ -672,7 +679,7 @@ ia64_unat_pos (void *spill_addr) * Set the NaT bit of an integer register which was spilled at address * SPILL_ADDR. UNAT is the mask to be updated. */ -extern inline void +static inline void ia64_set_unat (__u64 *unat, void *spill_addr, unsigned long nat) { __u64 bit = ia64_unat_pos(spill_addr); @@ -685,7 +692,7 @@ ia64_set_unat (__u64 *unat, void *spill_addr, unsigned long nat) * Return saved PC of a blocked thread. * Note that the only way T can block is through a call to schedule() -> switch_to(). */ -extern inline unsigned long +static inline unsigned long thread_saved_pc (struct thread_struct *t) { struct unw_frame_info info; @@ -720,7 +727,7 @@ thread_saved_pc (struct thread_struct *t) /* * Set the correctable machine check vector register */ -extern __inline__ void +static inline void ia64_set_cmcv (__u64 val) { __asm__ __volatile__ ("mov cr.cmcv=%0" :: "r"(val) : "memory"); @@ -729,7 +736,7 @@ ia64_set_cmcv (__u64 val) /* * Read the correctable machine check vector register */ -extern __inline__ __u64 +static inline __u64 ia64_get_cmcv (void) { __u64 val; @@ -738,7 +745,7 @@ ia64_get_cmcv (void) return val; } -extern inline __u64 +static inline __u64 ia64_get_ivr (void) { __u64 r; @@ -746,13 +753,13 @@ ia64_get_ivr (void) return r; } -extern inline void +static inline void ia64_set_tpr (__u64 val) { __asm__ __volatile__ ("mov cr.tpr=%0" :: "r"(val)); } -extern inline __u64 +static inline __u64 ia64_get_tpr (void) { __u64 r; @@ -760,71 +767,75 @@ ia64_get_tpr (void) return r; } -extern __inline__ void +static inline void ia64_set_irr0 (__u64 val) { __asm__ __volatile__("mov cr.irr0=%0;;" :: "r"(val) : "memory"); ia64_srlz_d(); } -extern __inline__ __u64 +static inline __u64 ia64_get_irr0 (void) { __u64 val; - __asm__ ("mov %0=cr.irr0" : "=r"(val)); + /* this is volatile because irr may change unbeknownst to gcc... */ + __asm__ __volatile__("mov %0=cr.irr0" : "=r"(val)); return val; } -extern __inline__ void +static inline void ia64_set_irr1 (__u64 val) { __asm__ __volatile__("mov cr.irr1=%0;;" :: "r"(val) : "memory"); ia64_srlz_d(); } -extern __inline__ __u64 +static inline __u64 ia64_get_irr1 (void) { __u64 val; - __asm__ ("mov %0=cr.irr1" : "=r"(val)); + /* this is volatile because irr may change unbeknownst to gcc... */ + __asm__ __volatile__("mov %0=cr.irr1" : "=r"(val)); return val; } -extern __inline__ void +static inline void ia64_set_irr2 (__u64 val) { __asm__ __volatile__("mov cr.irr2=%0;;" :: "r"(val) : "memory"); ia64_srlz_d(); } -extern __inline__ __u64 +static inline __u64 ia64_get_irr2 (void) { __u64 val; - __asm__ ("mov %0=cr.irr2" : "=r"(val)); + /* this is volatile because irr may change unbeknownst to gcc... */ + __asm__ __volatile__("mov %0=cr.irr2" : "=r"(val)); return val; } -extern __inline__ void +static inline void ia64_set_irr3 (__u64 val) { __asm__ __volatile__("mov cr.irr3=%0;;" :: "r"(val) : "memory"); ia64_srlz_d(); } -extern __inline__ __u64 +static inline __u64 ia64_get_irr3 (void) { __u64 val; - __asm__ ("mov %0=cr.irr3" : "=r"(val)); + /* this is volatile because irr may change unbeknownst to gcc... */ + __asm__ __volatile__("mov %0=cr.irr3" : "=r"(val)); return val; } -extern __inline__ __u64 +static inline __u64 ia64_get_gp(void) { __u64 val; @@ -852,7 +863,7 @@ ia64_get_gp(void) #define ia64_rotl(w,n) ia64_rotr((w),(64)-(n)) -extern __inline__ __u64 +static inline __u64 ia64_thash (__u64 addr) { __u64 result; diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h index b71acee5f..68ebe286e 100644 --- a/include/asm-ia64/ptrace.h +++ b/include/asm-ia64/ptrace.h @@ -219,6 +219,7 @@ struct switch_stack { extern void show_regs (struct pt_regs *); extern long ia64_peek (struct pt_regs *, struct task_struct *, unsigned long addr, long *val); extern long ia64_poke (struct pt_regs *, struct task_struct *, unsigned long addr, long val); + extern void ia64_flush_fph (struct task_struct *t); extern void ia64_sync_fph (struct task_struct *t); #ifdef CONFIG_IA64_NEW_UNWIND diff --git a/include/asm-ia64/ptrace_offsets.h b/include/asm-ia64/ptrace_offsets.h index b32b6c89d..6fa6fb446 100644 --- a/include/asm-ia64/ptrace_offsets.h +++ b/include/asm-ia64/ptrace_offsets.h @@ -17,6 +17,8 @@ * unsigned long dbr[8]; * unsigned long rsvd2[504]; * unsigned long ibr[8]; + * unsigned long rsvd3[504]; + * unsigned long pmd[4]; * } */ @@ -157,6 +159,7 @@ #define PT_B4 0x07f0 #define PT_B5 0x07f8 +#define PT_AR_EC 0x0800 #define PT_AR_LC 0x0808 /* pt_regs */ @@ -209,5 +212,6 @@ #define PT_DBR 0x2000 /* data breakpoint registers */ #define PT_IBR 0x3000 /* instruction breakpoint registers */ +#define PT_PMD 0x4000 /* performance monitoring counters */ #endif /* _ASM_IA64_PTRACE_OFFSETS_H */ diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h index 06096644b..9f02ac571 100644 --- a/include/asm-ia64/sal.h +++ b/include/asm-ia64/sal.h @@ -17,6 +17,7 @@ */ #include <linux/config.h> +#include <linux/spinlock.h> #include <asm/pal.h> #include <asm/system.h> @@ -158,12 +159,22 @@ struct ia64_sal_desc_tr { char reserved2[8]; }; -struct ia64_sal_desc_ptc { +typedef struct ia64_sal_desc_ptc { char type; char reserved1[3]; unsigned int num_domains; /* # of coherence domains */ - long domain_info; /* physical address of domain info table */ -}; + s64 domain_info; /* physical address of domain info table */ +} ia64_sal_desc_ptc_t; + +typedef struct ia64_sal_ptc_domain_info { + unsigned long proc_count; /* number of processors in domain */ + long proc_list; /* physical address of LID array */ +} ia64_sal_ptc_domain_info_t; + +typedef struct ia64_sal_ptc_domain_proc_entry { + unsigned char id; /* id of processor */ + unsigned char eid; /* eid of processor */ +} ia64_sal_ptc_domain_proc_entry_t; #define IA64_SAL_AP_EXTERNAL_INT 0 @@ -175,6 +186,7 @@ struct ia64_sal_desc_ap_wakeup { }; extern ia64_sal_handler ia64_sal; +extern struct ia64_sal_desc_ptc *ia64_ptc_domain_info; extern const char *ia64_sal_strerror (long status); extern void ia64_sal_init (struct ia64_sal_systab *sal_systab); @@ -387,7 +399,7 @@ typedef struct psilog * Now define a couple of inline functions for improved type checking * and convenience. */ -extern inline long +static inline long ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second, unsigned long *drift_info) { @@ -400,7 +412,7 @@ ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second, } /* Flush all the processor and platform level instruction and/or data caches */ -extern inline s64 +static inline s64 ia64_sal_cache_flush (u64 cache_type) { struct ia64_sal_retval isrv; @@ -411,7 +423,7 @@ ia64_sal_cache_flush (u64 cache_type) /* Initialize all the processor and platform level instruction and data caches */ -extern inline s64 +static inline s64 ia64_sal_cache_init (void) { struct ia64_sal_retval isrv; @@ -422,7 +434,7 @@ ia64_sal_cache_init (void) /* Clear the processor and platform information logged by SAL with respect to the * machine state at the time of MCA's, INITs or CMCs */ -extern inline s64 +static inline s64 ia64_sal_clear_state_info (u64 sal_info_type, u64 sal_info_sub_type) { struct ia64_sal_retval isrv; @@ -434,7 +446,7 @@ ia64_sal_clear_state_info (u64 sal_info_type, u64 sal_info_sub_type) /* Get the processor and platform information logged by SAL with respect to the machine * state at the time of the MCAs, INITs or CMCs. */ -extern inline u64 +static inline u64 ia64_sal_get_state_info (u64 sal_info_type, u64 sal_info_sub_type, u64 *sal_info) { struct ia64_sal_retval isrv; @@ -446,7 +458,7 @@ ia64_sal_get_state_info (u64 sal_info_type, u64 sal_info_sub_type, u64 *sal_info /* Get the maximum size of the information logged by SAL with respect to the machine * state at the time of MCAs, INITs or CMCs */ -extern inline u64 +static inline u64 ia64_sal_get_state_info_size (u64 sal_info_type, u64 sal_info_sub_type) { struct ia64_sal_retval isrv; @@ -459,7 +471,7 @@ ia64_sal_get_state_info_size (u64 sal_info_type, u64 sal_info_sub_type) /* Causes the processor to go into a spin loop within SAL where SAL awaits a wakeup * from the monarch processor. */ -extern inline s64 +static inline s64 ia64_sal_mc_rendez (void) { struct ia64_sal_retval isrv; @@ -471,7 +483,7 @@ ia64_sal_mc_rendez (void) * the machine check rendezvous sequence as well as the mechanism to wake up the * non-monarch processor at the end of machine check processing. */ -extern inline s64 +static inline s64 ia64_sal_mc_set_params (u64 param_type, u64 i_or_m, u64 i_or_m_val, u64 timeout) { struct ia64_sal_retval isrv; @@ -480,7 +492,7 @@ ia64_sal_mc_set_params (u64 param_type, u64 i_or_m, u64 i_or_m_val, u64 timeout) } /* Read from PCI configuration space */ -extern inline s64 +static inline s64 ia64_sal_pci_config_read (u64 pci_config_addr, u64 size, u64 *value) { struct ia64_sal_retval isrv; @@ -503,7 +515,7 @@ ia64_sal_pci_config_read (u64 pci_config_addr, u64 size, u64 *value) } /* Write to PCI configuration space */ -extern inline s64 +static inline s64 ia64_sal_pci_config_write (u64 pci_config_addr, u64 size, u64 value) { struct ia64_sal_retval isrv; @@ -527,7 +539,7 @@ ia64_sal_pci_config_write (u64 pci_config_addr, u64 size, u64 value) * Register physical addresses of locations needed by SAL when SAL * procedures are invoked in virtual mode. */ -extern inline s64 +static inline s64 ia64_sal_register_physical_addr (u64 phys_entry, u64 phys_addr) { struct ia64_sal_retval isrv; @@ -539,7 +551,7 @@ ia64_sal_register_physical_addr (u64 phys_entry, u64 phys_addr) * or entry points where SAL will pass control for the specified event. These event * handlers are for the bott rendezvous, MCAs and INIT scenarios. */ -extern inline s64 +static inline s64 ia64_sal_set_vectors (u64 vector_type, u64 handler_addr1, u64 gp1, u64 handler_len1, u64 handler_addr2, u64 gp2, u64 handler_len2) @@ -552,7 +564,7 @@ ia64_sal_set_vectors (u64 vector_type, return isrv.status; } /* Update the contents of PAL block in the non-volatile storage device */ -extern inline s64 +static inline s64 ia64_sal_update_pal (u64 param_buf, u64 scratch_buf, u64 scratch_buf_size, u64 *error_code, u64 *scratch_buf_size_needed) { diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h index c42aff9ad..f829713bf 100644 --- a/include/asm-ia64/semaphore.h +++ b/include/asm-ia64/semaphore.h @@ -39,7 +39,7 @@ struct semaphore { #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) -extern inline void +static inline void sema_init (struct semaphore *sem, int val) { *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); @@ -68,7 +68,7 @@ extern spinlock_t semaphore_wake_lock; * Atomically decrement the semaphore's count. If it goes negative, * block the calling thread in the TASK_UNINTERRUPTIBLE state. */ -extern inline void +static inline void down (struct semaphore *sem) { #if WAITQUEUE_DEBUG @@ -82,7 +82,7 @@ down (struct semaphore *sem) * Atomically decrement the semaphore's count. If it goes negative, * block the calling thread in the TASK_INTERRUPTIBLE state. */ -extern inline int +static inline int down_interruptible (struct semaphore * sem) { int ret = 0; @@ -95,7 +95,7 @@ down_interruptible (struct semaphore * sem) return ret; } -extern inline int +static inline int down_trylock (struct semaphore *sem) { int ret = 0; @@ -108,7 +108,7 @@ down_trylock (struct semaphore *sem) return ret; } -extern inline void +static inline void up (struct semaphore * sem) { #if WAITQUEUE_DEBUG @@ -181,7 +181,7 @@ extern void __down_read_failed (struct rw_semaphore *sem, long count); extern void __down_write_failed (struct rw_semaphore *sem, long count); extern void __rwsem_wake (struct rw_semaphore *sem, long count); -extern inline void +static inline void init_rwsem (struct rw_semaphore *sem) { sem->count = RW_LOCK_BIAS; @@ -196,7 +196,7 @@ init_rwsem (struct rw_semaphore *sem) #endif } -extern inline void +static inline void down_read (struct rw_semaphore *sem) { long count; @@ -218,7 +218,7 @@ down_read (struct rw_semaphore *sem) #endif } -extern inline void +static inline void down_write (struct rw_semaphore *sem) { long old_count, new_count; @@ -252,7 +252,7 @@ down_write (struct rw_semaphore *sem) * case is when there was a writer waiting, and we've * bumped the count to 0: we must wake the writer up. */ -extern inline void +static inline void __up_read (struct rw_semaphore *sem) { long count; @@ -271,7 +271,7 @@ __up_read (struct rw_semaphore *sem) * Releasing the writer is easy -- just release it and * wake up any sleepers. */ -extern inline void +static inline void __up_write (struct rw_semaphore *sem) { long old_count, new_count; @@ -290,7 +290,7 @@ __up_write (struct rw_semaphore *sem) __rwsem_wake(sem, new_count); } -extern inline void +static inline void up_read (struct rw_semaphore *sem) { #if WAITQUEUE_DEBUG @@ -303,7 +303,7 @@ up_read (struct rw_semaphore *sem) __up_read(sem); } -extern inline void +static inline void up_write (struct rw_semaphore *sem) { #if WAITQUEUE_DEBUG diff --git a/include/asm-ia64/siginfo.h b/include/asm-ia64/siginfo.h index a54312e12..dfafe187d 100644 --- a/include/asm-ia64/siginfo.h +++ b/include/asm-ia64/siginfo.h @@ -235,7 +235,8 @@ typedef struct sigevent { #ifdef __KERNEL__ #include <linux/string.h> -extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from) +static inline void +copy_siginfo (siginfo_t *to, siginfo_t *from) { if (from->si_code < 0) memcpy(to, from, sizeof(siginfo_t)); diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h index 0788865fc..156a1fbf2 100644 --- a/include/asm-ia64/smp.h +++ b/include/asm-ia64/smp.h @@ -25,54 +25,71 @@ #define smp_processor_id() (current->processor) -struct smp_boot_data { +extern struct smp_boot_data { int cpu_count; - int cpu_map[NR_CPUS]; -}; + int cpu_phys_id[NR_CPUS]; +} smp_boot_data __initdata; extern unsigned long cpu_present_map; extern unsigned long cpu_online_map; extern unsigned long ipi_base_addr; extern int bootstrap_processor; -extern volatile int __cpu_number_map[NR_CPUS]; -extern volatile int __cpu_logical_map[NR_CPUS]; +extern volatile int __cpu_physical_id[NR_CPUS]; extern unsigned char smp_int_redirect; extern char no_int_routing; - -#define cpu_number_map(i) __cpu_number_map[i] -#define cpu_logical_map(i) __cpu_logical_map[i] +extern int smp_num_cpus; + +#define cpu_physical_id(i) __cpu_physical_id[i] +#define cpu_number_map(i) (i) +#define cpu_logical_map(i) (i) extern unsigned long ap_wakeup_vector; /* + * Function to map hard smp processor id to logical id. Slow, so + * don't use this in performance-critical code. + */ +static inline int +cpu_logical_id (int cpuid) +{ + int i; + + for (i=0; i<smp_num_cpus; i++) { + if (cpu_physical_id(i) == cpuid) + break; + } + return i; +} + +/* * XTP control functions: * min_xtp : route all interrupts to this CPU * normal_xtp: nominal XTP value * max_xtp : never deliver interrupts to this CPU. */ -extern __inline void +static inline void min_xtp(void) { if (smp_int_redirect & SMP_IRQ_REDIRECTION) writeb(0x00, ipi_base_addr | XTP_OFFSET); /* XTP to min */ } -extern __inline void +static inline void normal_xtp(void) { if (smp_int_redirect & SMP_IRQ_REDIRECTION) writeb(0x08, ipi_base_addr | XTP_OFFSET); /* XTP normal */ } -extern __inline void +static inline void max_xtp(void) { if (smp_int_redirect & SMP_IRQ_REDIRECTION) writeb(0x0f, ipi_base_addr | XTP_OFFSET); /* Set XTP to max */ } -extern __inline__ unsigned int +static inline unsigned int hard_smp_processor_id(void) { struct { @@ -84,13 +101,7 @@ hard_smp_processor_id(void) __asm__ ("mov %0=cr.lid" : "=r" (lid)); -#ifdef LARGE_CPU_ID_OK - return lid.eid << 8 | lid.id; -#else - if (((lid.id << 8) | lid.eid) > NR_CPUS) - printk("WARNING: SMP ID %d > NR_CPUS\n", (lid.id << 8) | lid.eid); - return lid.id; -#endif + return lid.id << 8 | lid.eid; } #define NO_PROC_ID (-1) diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h index 24b85b4d6..eb421385c 100644 --- a/include/asm-ia64/spinlock.h +++ b/include/asm-ia64/spinlock.h @@ -29,48 +29,42 @@ typedef struct { * Streamlined test_and_set_bit(0, (x)). We use test-and-test-and-set * rather than a simple xchg to avoid writing the cache-line when * there is contention. - * - * XXX Fix me: instead of preserving ar.pfs, we should just mark it - * XXX as "clobbered". Unfortunately, the Mar 2000 release of the compiler - * XXX doesn't let us do that. The August release fixes that. */ -#define spin_lock(x) \ -{ \ +#define spin_lock(x) \ +{ \ + register char *addr __asm__ ("r31") = (char *) &(x)->lock; \ + \ + __asm__ __volatile__ ( \ + "mov r30=1\n" \ + "mov ar.ccv=r0\n" \ + ";;\n" \ + IA64_SEMFIX"cmpxchg1.acq r30=[%0],r30,ar.ccv\n" \ + ";;\n" \ + "cmp.ne p15,p0=r30,r0\n" \ + "(p15) br.call.spnt.few b7=ia64_spinlock_contention\n" \ + ";;\n" \ + "1:\n" /* force a new bundle */ \ + :: "r"(addr) \ + : "ar.ccv", "ar.pfs", "b7", "p15", "r28", "r29", "r30", "memory"); \ +} + +#define spin_trylock(x) \ +({ \ register char *addr __asm__ ("r31") = (char *) &(x)->lock; \ - long saved_pfs; \ + register long result; \ \ __asm__ __volatile__ ( \ "mov r30=1\n" \ "mov ar.ccv=r0\n" \ ";;\n" \ - IA64_SEMFIX"cmpxchg1.acq r30=[%1],r30,ar.ccv\n" \ - ";;\n" \ - "cmp.ne p15,p0=r30,r0\n" \ - "mov %0=ar.pfs\n" \ - "(p15) br.call.spnt.few b7=ia64_spinlock_contention\n" \ - ";;\n" \ - "1: (p15) mov ar.pfs=%0;;\n" /* force a new bundle */ \ - : "=&r"(saved_pfs) : "r"(addr) \ - : "p15", "r28", "r29", "r30", "memory"); \ -} - -#define spin_trylock(x) \ -({ \ - register char *addr __asm__ ("r31") = (char *) &(x)->lock; \ - register long result; \ - \ - __asm__ __volatile__ ( \ - "mov r30=1\n" \ - "mov ar.ccv=r0\n" \ - ";;\n" \ - IA64_SEMFIX"cmpxchg1.acq %0=[%1],r30,ar.ccv\n" \ - : "=r"(result) : "r"(addr) : "r30", "memory"); \ - (result == 0); \ + IA64_SEMFIX"cmpxchg1.acq %0=[%1],r30,ar.ccv\n" \ + : "=r"(result) : "r"(addr) : "ar.ccv", "r30", "memory"); \ + (result == 0); \ }) #define spin_is_locked(x) ((x)->lock != 0) -#define spin_unlock(x) ({((spinlock_t *) x)->lock = 0;}) -#define spin_unlock_wait(x) ({ while ((x)->lock); }) +#define spin_unlock(x) do {((spinlock_t *) x)->lock = 0;} while (0) +#define spin_unlock_wait(x) do {} while ((x)->lock) #else /* !NEW_LOCK */ @@ -91,21 +85,21 @@ typedef struct { "mov r29 = 1\n" \ ";;\n" \ "1:\n" \ - "ld4 r2 = %0\n" \ + "ld4 r2 = [%0]\n" \ ";;\n" \ "cmp4.eq p0,p7 = r0,r2\n" \ "(p7) br.cond.spnt.few 1b \n" \ - IA64_SEMFIX"cmpxchg4.acq r2 = %0, r29, ar.ccv\n" \ + IA64_SEMFIX"cmpxchg4.acq r2 = [%0], r29, ar.ccv\n" \ ";;\n" \ "cmp4.eq p0,p7 = r0, r2\n" \ "(p7) br.cond.spnt.few 1b\n" \ ";;\n" \ - :: "m" __atomic_fool_gcc((x)) : "r2", "r29", "memory") + :: "r"(&(x)->lock) : "r2", "r29", "memory") #define spin_is_locked(x) ((x)->lock != 0) -#define spin_unlock(x) ({((spinlock_t *) x)->lock = 0; barrier();}) +#define spin_unlock(x) do {((spinlock_t *) x)->lock = 0; barrier(); } while (0) #define spin_trylock(x) (cmpxchg_acq(&(x)->lock, 0, 1) == 0) -#define spin_unlock_wait(x) ({ do { barrier(); } while ((x)->lock); }) +#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock) #endif /* !NEW_LOCK */ @@ -115,44 +109,54 @@ typedef struct { } rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 } -#define read_lock(rw) \ -do { \ - int tmp = 0; \ - __asm__ __volatile__ ("1:\t"IA64_SEMFIX"fetchadd4.acq %0 = %1, 1\n" \ - ";;\n" \ - "tbit.nz p6,p0 = %0, 31\n" \ - "(p6) br.cond.sptk.few 2f\n" \ - ".section .text.lock,\"ax\"\n" \ - "2:\t"IA64_SEMFIX"fetchadd4.rel %0 = %1, -1\n" \ - ";;\n" \ - "3:\tld4.acq %0 = %1\n" \ - ";;\n" \ - "tbit.nz p6,p0 = %0, 31\n" \ - "(p6) br.cond.sptk.few 3b\n" \ - "br.cond.sptk.few 1b\n" \ - ";;\n" \ - ".previous\n" \ - : "=r" (tmp), "=m" (__atomic_fool_gcc(rw)) \ - :: "memory"); \ +#define read_lock(rw) \ +do { \ + int tmp = 0; \ + __asm__ __volatile__ ("1:\t"IA64_SEMFIX"fetchadd4.acq %0 = [%1], 1\n" \ + ";;\n" \ + "tbit.nz p6,p0 = %0, 31\n" \ + "(p6) br.cond.sptk.few 2f\n" \ + ".section .text.lock,\"ax\"\n" \ + "2:\t"IA64_SEMFIX"fetchadd4.rel %0 = [%1], -1\n" \ + ";;\n" \ + "3:\tld4.acq %0 = [%1]\n" \ + ";;\n" \ + "tbit.nz p6,p0 = %0, 31\n" \ + "(p6) br.cond.sptk.few 3b\n" \ + "br.cond.sptk.few 1b\n" \ + ";;\n" \ + ".previous\n" \ + : "=&r" (tmp) \ + : "r" (rw): "memory"); \ } while(0) -#define read_unlock(rw) \ -do { \ - int tmp = 0; \ - __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0 = %1, -1\n" \ - : "=r" (tmp) \ - : "m" (__atomic_fool_gcc(rw)) \ - : "memory"); \ +#define read_unlock(rw) \ +do { \ + int tmp = 0; \ + __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0 = [%1], -1\n" \ + : "=r" (tmp) \ + : "r" (rw) \ + : "memory"); \ } while(0) -#define write_lock(rw) \ -do { \ - do { \ - while ((rw)->write_lock); \ - } while (test_and_set_bit(31, (rw))); \ - while ((rw)->read_counter); \ - barrier(); \ -} while (0) +#define write_lock(rw) \ +do { \ + __asm__ __volatile__ ( \ + "mov ar.ccv = r0\n" \ + "movl r29 = 0x80000000\n" \ + ";;\n" \ + "1:\n" \ + "ld4 r2 = [%0]\n" \ + ";;\n" \ + "cmp4.eq p0,p7 = r0,r2\n" \ + "(p7) br.cond.spnt.few 1b \n" \ + IA64_SEMFIX"cmpxchg4.acq r2 = [%0], r29, ar.ccv\n" \ + ";;\n" \ + "cmp4.eq p0,p7 = r0, r2\n" \ + "(p7) br.cond.spnt.few 1b\n" \ + ";;\n" \ + :: "r"(rw) : "r2", "r29", "memory"); \ +} while(0) /* * clear_bit() has "acq" semantics; we're really need "rel" semantics, diff --git a/include/asm-ia64/string.h b/include/asm-ia64/string.h index 56bd64327..c17fc8de4 100644 --- a/include/asm-ia64/string.h +++ b/include/asm-ia64/string.h @@ -9,6 +9,9 @@ * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com> */ +#include <linux/config.h> /* remove this once we remove the A-step workaround... */ +#ifndef CONFIG_ITANIUM_ASTEP_SPECIFIC + #define __HAVE_ARCH_STRLEN 1 /* see arch/ia64/lib/strlen.S */ #define __HAVE_ARCH_MEMSET 1 /* see arch/ia64/lib/memset.S */ #define __HAVE_ARCH_MEMCPY 1 /* see arch/ia64/lib/memcpy.S */ @@ -18,4 +21,6 @@ extern __kernel_size_t strlen (const char *); extern void *memset (void *, int, __kernel_size_t); extern void *memcpy (void *, const void *, __kernel_size_t); +#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */ + #endif /* _ASM_IA64_STRING_H */ diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index 25438c18e..4bff3ff94 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h @@ -38,6 +38,7 @@ #ifndef __ASSEMBLY__ +#include <linux/kernel.h> #include <linux/types.h> struct pci_vector_struct { @@ -67,7 +68,7 @@ extern struct ia64_boot_param { __u64 initrd_size; } ia64_boot_param; -extern inline void +static inline void ia64_insn_group_barrier (void) { __asm__ __volatile__ (";;" ::: "memory"); @@ -99,6 +100,16 @@ ia64_insn_group_barrier (void) #define rmb() mb() #define wmb() mb() +#ifdef CONFIG_SMP +# define smp_mb() mb() +# define smp_rmb() rmb() +# define smp_wmb() wmb() +#else +# define smp_mb() barrier() +# define smp_rmb() barrier() +# define smp_wmb() barrier() +#endif + /* * XXX check on these---I suspect what Linus really wants here is * acquire vs release semantics but we can't discuss this stuff with @@ -240,15 +251,13 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void); ({ \ switch (sz) { \ case 4: \ - __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0=%1,%3" \ - : "=r"(tmp), "=m"(__atomic_fool_gcc(v)) \ - : "m" (__atomic_fool_gcc(v)), "i"(n)); \ + __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0=[%1],%2" \ + : "=r"(tmp) : "r"(v), "i"(n) : "memory"); \ break; \ \ case 8: \ - __asm__ __volatile__ (IA64_SEMFIX"fetchadd8.rel %0=%1,%3" \ - : "=r"(tmp), "=m"(__atomic_fool_gcc(v)) \ - : "m" (__atomic_fool_gcc(v)), "i"(n)); \ + __asm__ __volatile__ (IA64_SEMFIX"fetchadd8.rel %0=[%1],%2" \ + : "=r"(tmp) : "r"(v), "i"(n) : "memory"); \ break; \ \ default: \ @@ -289,23 +298,23 @@ __xchg (unsigned long x, volatile void *ptr, int size) switch (size) { case 1: - __asm__ __volatile (IA64_SEMFIX"xchg1 %0=%1,%2" : "=r" (result) - : "m" (*(char *) ptr), "r" (x) : "memory"); + __asm__ __volatile (IA64_SEMFIX"xchg1 %0=[%1],%2" : "=r" (result) + : "r" (ptr), "r" (x) : "memory"); return result; case 2: - __asm__ __volatile (IA64_SEMFIX"xchg2 %0=%1,%2" : "=r" (result) - : "m" (*(short *) ptr), "r" (x) : "memory"); + __asm__ __volatile (IA64_SEMFIX"xchg2 %0=[%1],%2" : "=r" (result) + : "r" (ptr), "r" (x) : "memory"); return result; case 4: - __asm__ __volatile (IA64_SEMFIX"xchg4 %0=%1,%2" : "=r" (result) - : "m" (*(int *) ptr), "r" (x) : "memory"); + __asm__ __volatile (IA64_SEMFIX"xchg4 %0=[%1],%2" : "=r" (result) + : "r" (ptr), "r" (x) : "memory"); return result; case 8: - __asm__ __volatile (IA64_SEMFIX"xchg8 %0=%1,%2" : "=r" (result) - : "m" (*(long *) ptr), "r" (x) : "memory"); + __asm__ __volatile (IA64_SEMFIX"xchg8 %0=[%1],%2" : "=r" (result) + : "r" (ptr), "r" (x) : "memory"); return result; } __xchg_called_with_bad_pointer(); @@ -329,9 +338,6 @@ __xchg (unsigned long x, volatile void *ptr, int size) */ extern long __cmpxchg_called_with_bad_pointer(void); -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) (*(struct __xchg_dummy *)(x)) - #define ia64_cmpxchg(sem,ptr,old,new,size) \ ({ \ __typeof__(ptr) _p_ = (ptr); \ @@ -348,27 +354,23 @@ struct __xchg_dummy { unsigned long a[100]; }; __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_)); \ switch (size) { \ case 1: \ - __asm__ __volatile__ (IA64_SEMFIX"cmpxchg1."sem" %0=%2,%3,ar.ccv" \ - : "=r"(_r_), "=m"(__xg(_p_)) \ - : "m"(__xg(_p_)), "r"(_n_)); \ + __asm__ __volatile__ (IA64_SEMFIX"cmpxchg1."sem" %0=[%1],%2,ar.ccv" \ + : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ break; \ \ case 2: \ - __asm__ __volatile__ (IA64_SEMFIX"cmpxchg2."sem" %0=%2,%3,ar.ccv" \ - : "=r"(_r_), "=m"(__xg(_p_)) \ - : "m"(__xg(_p_)), "r"(_n_)); \ + __asm__ __volatile__ (IA64_SEMFIX"cmpxchg2."sem" %0=[%1],%2,ar.ccv" \ + : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ break; \ \ case 4: \ - __asm__ __volatile__ (IA64_SEMFIX"cmpxchg4."sem" %0=%2,%3,ar.ccv" \ - : "=r"(_r_), "=m"(__xg(_p_)) \ - : "m"(__xg(_p_)), "r"(_n_)); \ + __asm__ __volatile__ (IA64_SEMFIX"cmpxchg4."sem" %0=[%1],%2,ar.ccv" \ + : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ break; \ \ case 8: \ - __asm__ __volatile__ (IA64_SEMFIX"cmpxchg8."sem" %0=%2,%3,ar.ccv" \ - : "=r"(_r_), "=m"(__xg(_p_)) \ - : "m"(__xg(_p_)), "r"(_n_)); \ + __asm__ __volatile__ (IA64_SEMFIX"cmpxchg8."sem" %0=[%1],%2,ar.ccv" \ + : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ break; \ \ default: \ @@ -433,33 +435,31 @@ extern void ia64_load_extra (struct task_struct *task); if (((next)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)) \ || IS_IA32_PROCESS(ia64_task_regs(next))) \ ia64_load_extra(next); \ - ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next)); \ (last) = ia64_switch_to((next)); \ } while (0) #ifdef CONFIG_SMP /* * In the SMP case, we save the fph state when context-switching - * away from a thread that owned and modified fph. This way, when - * the thread gets scheduled on another CPU, the CPU can pick up the - * state frm task->thread.fph, avoiding the complication of having - * to fetch the latest fph state from another CPU. If the thread - * happens to be rescheduled on the same CPU later on and nobody - * else has touched the FPU in the meantime, the thread will fault - * upon the first access to fph but since the state in fph is still - * valid, no other overheads are incurred. In other words, CPU - * affinity is a Good Thing. + * away from a thread that modified fph. This way, when the thread + * gets scheduled on another CPU, the CPU can pick up the state from + * task->thread.fph, avoiding the complication of having to fetch + * the latest fph state from another CPU. */ -# define switch_to(prev,next,last) do { \ - if (ia64_get_fpu_owner() == (prev) && ia64_psr(ia64_task_regs(prev))->mfh) { \ - ia64_psr(ia64_task_regs(prev))->mfh = 0; \ - (prev)->thread.flags |= IA64_THREAD_FPH_VALID; \ - __ia64_save_fpu((prev)->thread.fph); \ - } \ - __switch_to(prev,next,last); \ +# define switch_to(prev,next,last) do { \ + if (ia64_psr(ia64_task_regs(prev))->mfh) { \ + ia64_psr(ia64_task_regs(prev))->mfh = 0; \ + (prev)->thread.flags |= IA64_THREAD_FPH_VALID; \ + __ia64_save_fpu((prev)->thread.fph); \ + } \ + ia64_psr(ia64_task_regs(prev))->dfh = 1; \ + __switch_to(prev,next,last); \ } while (0) #else -# define switch_to(prev,next,last) __switch_to(prev,next,last) +# define switch_to(prev,next,last) do { \ + ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next)); \ + __switch_to(prev,next,last); \ +} while (0) #endif #endif /* __KERNEL__ */ diff --git a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h index 319784a5b..6e8aef3df 100644 --- a/include/asm-ia64/uaccess.h +++ b/include/asm-ia64/uaccess.h @@ -61,7 +61,7 @@ #define __access_ok(addr,size,segment) (((unsigned long) (addr)) <= (segment).seg) #define access_ok(type,addr,size) __access_ok((addr),(size),get_fs()) -extern inline int +static inline int verify_area (int type, const void *addr, unsigned long size) { return access_ok(type,addr,size) ? 0 : -EFAULT; @@ -126,7 +126,7 @@ struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct *)(x)) #define __get_user_64(addr) \ - __asm__ ("\n1:\tld8 %0=%2\t// %0 and %1 get overwritten by exception handler\n" \ + __asm__ ("\n1:\tld8 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ "2:\n" \ "\t.section __ex_table,\"a\"\n" \ "\t\tdata4 @gprel(1b)\n" \ @@ -136,7 +136,7 @@ struct __large_struct { unsigned long buf[100]; }; : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_32(addr) \ - __asm__ ("\n1:\tld4 %0=%2\t// %0 and %1 get overwritten by exception handler\n" \ + __asm__ ("\n1:\tld4 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ "2:\n" \ "\t.section __ex_table,\"a\"\n" \ "\t\tdata4 @gprel(1b)\n" \ @@ -146,7 +146,7 @@ struct __large_struct { unsigned long buf[100]; }; : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_16(addr) \ - __asm__ ("\n1:\tld2 %0=%2\t// %0 and %1 get overwritten by exception handler\n" \ + __asm__ ("\n1:\tld2 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ "2:\n" \ "\t.section __ex_table,\"a\"\n" \ "\t\tdata4 @gprel(1b)\n" \ @@ -156,7 +156,7 @@ struct __large_struct { unsigned long buf[100]; }; : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_8(addr) \ - __asm__ ("\n1:\tld1 %0=%2\t// %0 and %1 get overwritten by exception handler\n" \ + __asm__ ("\n1:\tld1 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ "2:\n" \ "\t.section __ex_table,\"a\"\n" \ "\t\tdata4 @gprel(1b)\n" \ @@ -205,7 +205,7 @@ extern void __put_user_unknown (void); */ #define __put_user_64(x,addr) \ __asm__ __volatile__ ( \ - "\n1:\tst8 %1=%r2\t// %0 gets overwritten by exception handler\n" \ + "\n1:\tst8 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ "2:\n" \ "\t.section __ex_table,\"a\"\n" \ "\t\tdata4 @gprel(1b)\n" \ @@ -216,7 +216,7 @@ extern void __put_user_unknown (void); #define __put_user_32(x,addr) \ __asm__ __volatile__ ( \ - "\n1:\tst4 %1=%r2\t// %0 gets overwritten by exception handler\n" \ + "\n1:\tst4 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ "2:\n" \ "\t.section __ex_table,\"a\"\n" \ "\t\tdata4 @gprel(1b)\n" \ @@ -227,7 +227,7 @@ extern void __put_user_unknown (void); #define __put_user_16(x,addr) \ __asm__ __volatile__ ( \ - "\n1:\tst2 %1=%r2\t// %0 gets overwritten by exception handler\n" \ + "\n1:\tst2 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ "2:\n" \ "\t.section __ex_table,\"a\"\n" \ "\t\tdata4 @gprel(1b)\n" \ @@ -238,7 +238,7 @@ extern void __put_user_unknown (void); #define __put_user_8(x,addr) \ __asm__ __volatile__ ( \ - "\n1:\tst1 %1=%r2\t// %0 gets overwritten by exception handler\n" \ + "\n1:\tst1 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ "2:\n" \ "\t.section __ex_table,\"a\"\n" \ "\t\tdata4 @gprel(1b)\n" \ diff --git a/include/asm-ia64/unaligned.h b/include/asm-ia64/unaligned.h index 6dc82c87e..c9d6dca0e 100644 --- a/include/asm-ia64/unaligned.h +++ b/include/asm-ia64/unaligned.h @@ -22,42 +22,42 @@ struct __una_u64 { __u64 x __attribute__((packed)); }; struct __una_u32 { __u32 x __attribute__((packed)); }; struct __una_u16 { __u16 x __attribute__((packed)); }; -extern inline unsigned long +static inline unsigned long __uldq (const unsigned long * r11) { const struct __una_u64 *ptr = (const struct __una_u64 *) r11; return ptr->x; } -extern inline unsigned long +static inline unsigned long __uldl (const unsigned int * r11) { const struct __una_u32 *ptr = (const struct __una_u32 *) r11; return ptr->x; } -extern inline unsigned long +static inline unsigned long __uldw (const unsigned short * r11) { const struct __una_u16 *ptr = (const struct __una_u16 *) r11; return ptr->x; } -extern inline void +static inline void __ustq (unsigned long r5, unsigned long * r11) { struct __una_u64 *ptr = (struct __una_u64 *) r11; ptr->x = r5; } -extern inline void +static inline void __ustl (unsigned long r5, unsigned int * r11) { struct __una_u32 *ptr = (struct __una_u32 *) r11; ptr->x = r5; } -extern inline void +static inline void __ustw (unsigned long r5, unsigned short * r11) { struct __una_u16 *ptr = (struct __una_u16 *) r11; diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h index 456376e1b..8b13b8f95 100644 --- a/include/asm-ia64/unistd.h +++ b/include/asm-ia64/unistd.h @@ -93,7 +93,7 @@ #define __NR_setpriority 1102 #define __NR_statfs 1103 #define __NR_fstatfs 1104 -#define __NR_ioperm 1105 +/* unused; used to be __NR_ioperm */ #define __NR_semget 1106 #define __NR_semop 1107 #define __NR_semctl 1108 diff --git a/include/asm-ia64/unwind.h b/include/asm-ia64/unwind.h index 60bb46cf9..95285ad99 100644 --- a/include/asm-ia64/unwind.h +++ b/include/asm-ia64/unwind.h @@ -52,36 +52,38 @@ struct unw_frame_info { unsigned int flags; short hint; short prev_script; - unsigned long bsp; - unsigned long sp; /* stack pointer */ - unsigned long psp; /* previous sp */ - unsigned long ip; /* instruction pointer */ - unsigned long pr_val; /* current predicates */ - unsigned long *cfm; + + /* current frame info: */ + unsigned long bsp; /* backing store pointer value */ + unsigned long sp; /* stack pointer value */ + unsigned long psp; /* previous sp value */ + unsigned long ip; /* instruction pointer value */ + unsigned long pr; /* current predicate values */ + unsigned long *cfm_loc; /* cfm save location (or NULL) */ struct task_struct *task; struct switch_stack *sw; /* preserved state: */ - unsigned long *pbsp; /* previous bsp */ - unsigned long *bspstore; - unsigned long *pfs; - unsigned long *rnat; - unsigned long *rp; - unsigned long *pri_unat; - unsigned long *unat; - unsigned long *pr; - unsigned long *lc; - unsigned long *fpsr; + unsigned long *bsp_loc; /* previous bsp save location */ + unsigned long *bspstore_loc; + unsigned long *pfs_loc; + unsigned long *rnat_loc; + unsigned long *rp_loc; + unsigned long *pri_unat_loc; + unsigned long *unat_loc; + unsigned long *pr_loc; + unsigned long *lc_loc; + unsigned long *fpsr_loc; struct unw_ireg { unsigned long *loc; struct unw_ireg_nat { - int type : 3; /* enum unw_nat_type */ - signed int off; /* NaT word is at loc+nat.off */ + long type : 3; /* enum unw_nat_type */ + signed long off : 61; /* NaT word is at loc+nat.off */ } nat; } r4, r5, r6, r7; - unsigned long *b1, *b2, *b3, *b4, *b5; - struct ia64_fpreg *f2, *f3, *f4, *f5, *fr[16]; + unsigned long *b1_loc, *b2_loc, *b3_loc, *b4_loc, *b5_loc; + struct ia64_fpreg *f2_loc, *f3_loc, *f4_loc, *f5_loc, *fr_loc[16]; }; /* @@ -140,19 +142,56 @@ extern int unw_unwind (struct unw_frame_info *info); */ extern int unw_unwind_to_user (struct unw_frame_info *info); -#define unw_get_ip(info,vp) ({*(vp) = (info)->ip; 0;}) -#define unw_get_sp(info,vp) ({*(vp) = (unsigned long) (info)->sp; 0;}) -#define unw_get_psp(info,vp) ({*(vp) = (unsigned long) (info)->psp; 0;}) -#define unw_get_bsp(info,vp) ({*(vp) = (unsigned long) (info)->bsp; 0;}) -#define unw_get_cfm(info,vp) ({*(vp) = *(info)->cfm; 0;}) -#define unw_set_cfm(info,val) ({*(info)->cfm = (val); 0;}) +#define unw_is_intr_frame(info) (((info)->flags & UNW_FLAG_INTERRUPT_FRAME) != 0) + +static inline unsigned long +unw_get_ip (struct unw_frame_info *info, unsigned long *valp) +{ + *valp = (info)->ip; + return 0; +} + +static inline unsigned long +unw_get_sp (struct unw_frame_info *info, unsigned long *valp) +{ + *valp = (info)->sp; + return 0; +} + +static inline unsigned long +unw_get_psp (struct unw_frame_info *info, unsigned long *valp) +{ + *valp = (info)->psp; + return 0; +} + +static inline unsigned long +unw_get_bsp (struct unw_frame_info *info, unsigned long *valp) +{ + *valp = (info)->bsp; + return 0; +} + +static inline unsigned long +unw_get_cfm (struct unw_frame_info *info, unsigned long *valp) +{ + *valp = *(info)->cfm_loc; + return 0; +} + +static inline unsigned long +unw_set_cfm (struct unw_frame_info *info, unsigned long val) +{ + *(info)->cfm_loc = val; + return 0; +} static inline int unw_get_rp (struct unw_frame_info *info, unsigned long *val) { - if (!info->rp) + if (!info->rp_loc) return -1; - *val = *info->rp; + *val = *info->rp_loc; return 0; } diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h index bedaecc4e..2e128ff48 100644 --- a/include/asm-m68k/pgtable.h +++ b/include/asm-m68k/pgtable.h @@ -399,4 +399,6 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma, #define io_remap_page_range remap_page_range +#include <asm-generic/pgtable.h> + #endif /* _M68K_PGTABLE_H */ diff --git a/include/asm-mips/hardirq.h b/include/asm-mips/hardirq.h index eead2fb87..3896706c7 100644 --- a/include/asm-mips/hardirq.h +++ b/include/asm-mips/hardirq.h @@ -1,5 +1,4 @@ -/* $Id: hardirq.h,v 1.8 2000/03/02 02:37:13 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -38,8 +37,8 @@ typedef struct { #define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) #define hardirq_endlock(cpu) do { } while (0) -#define irq_enter(cpu) (local_irq_count(cpu)++) -#define irq_exit(cpu) (local_irq_count(cpu)--) +#define irq_enter(cpu, irq) (local_irq_count(cpu)++) +#define irq_exit(cpu, irq) (local_irq_count(cpu)--) #define synchronize_irq() barrier(); diff --git a/include/asm-mips/param.h b/include/asm-mips/param.h index 5487778ca..d4e4c7d73 100644 --- a/include/asm-mips/param.h +++ b/include/asm-mips/param.h @@ -64,4 +64,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ +#endif + #endif /* _ASM_PARAM_H */ diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h index c9600661e..4f8c74dcf 100644 --- a/include/asm-mips/pgalloc.h +++ b/include/asm-mips/pgalloc.h @@ -1,5 +1,4 @@ -/* $Id: pgalloc.h,v 1.3 2000/02/23 00:41:38 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -186,31 +185,4 @@ extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) extern int do_check_pgt_cache(int, int); -extern inline void set_pgdir(unsigned long address, pgd_t entry) -{ - struct task_struct * p; - pgd_t *pgd; -#ifdef CONFIG_SMP - int i; -#endif - - read_lock(&tasklist_lock); - for_each_task(p) { - if (!p->mm) - continue; - *pgd_offset(p->mm,address) = entry; - } - read_unlock(&tasklist_lock); -#ifndef CONFIG_SMP - for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; -#else - /* To pgd_alloc/pgd_free, one holds master kernel lock and so does our - callee, so we can modify pgd caches of other CPUs as well. -jj */ - for (i = 0; i < NR_CPUS; i++) - for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; -#endif -} - #endif /* _ASM_PGALLOC_H */ diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 5556de9d9..b1d1f1212 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -731,6 +731,8 @@ extern inline void set_context(unsigned long val) : : "r" (val)); } +#include <asm-generic/pgtable.h> + #endif /* !defined (_LANGUAGE_ASSEMBLY) */ #define io_remap_page_range remap_page_range diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 022bb1215..7e160259c 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -249,21 +249,11 @@ unsigned long get_wchan(struct task_struct *p); * Note that __builtin_return_address(x>=1) is forbidden because GCC * aborts compilation on some CPUs. It's simply not possible to unwind * some CPU's stackframes. - */ -#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) -/* + * * __builtin_return_address works only for non-leaf functions. We avoid the * overhead of a function call by forcing the compiler to save the return * address register on the stack. */ #define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);}) -#else -/* - * __builtin_return_address is not implemented at all. Calling it - * will return senseless values. Return NULL which at least is an obviously - * senseless value. - */ -#define return_address() NULL -#endif #endif /* _ASM_PROCESSOR_H */ diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index b395fe1be..b361eb1f5 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -1,20 +1,22 @@ -/* $Id: ptrace.h,v 1.7 1999/09/28 22:27:17 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Ralf Baechle + * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000 by Ralf Baechle * * Machine dependent structs and defines to help the user use * the ptrace system call. */ -#ifndef __ASM_MIPS_PTRACE_H -#define __ASM_MIPS_PTRACE_H +#ifndef _ASM_PTRACE_H +#define _ASM_PTRACE_H #include <asm/isadep.h> #include <linux/types.h> +/* MIPS specific ptrace option. */ +#define PTRACE_SETOPTIONS + /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ #define FPR_BASE 32 #define PC 64 @@ -52,6 +54,19 @@ struct pt_regs { #endif /* !(_LANGUAGE_ASSEMBLY) */ +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +/* #define PTRACE_GETREGS 12 */ +/* #define PTRACE_SETREGS 13 */ +/* #define PTRACE_GETFPREGS 14 */ +/* #define PTRACE_SETFPREGS 15 */ +/* #define PTRACE_GETFPXREGS 18 */ +/* #define PTRACE_SETFPXREGS 19 */ + +#define PTRACE_SETOPTIONS 21 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + #ifdef _LANGUAGE_ASSEMBLY #include <asm/offset.h> #endif @@ -71,4 +86,4 @@ extern void show_regs(struct pt_regs *); #endif -#endif /* __ASM_MIPS_PTRACE_H */ +#endif /* _ASM_PTRACE_H */ diff --git a/include/asm-mips/resource.h b/include/asm-mips/resource.h index 127729ca2..718e983e6 100644 --- a/include/asm-mips/resource.h +++ b/include/asm-mips/resource.h @@ -26,14 +26,14 @@ #define RLIM_NLIMITS 11 /* Number of limit flavors. */ -#ifdef __KERNEL__ - /* * SuS says limits have to be unsigned. * Which makes a ton more sense anyway. */ #define RLIM_INFINITY 0x7fffffffUL +#ifdef __KERNEL__ + #define INIT_RLIMITS \ { \ { RLIM_INFINITY, RLIM_INFINITY }, \ diff --git a/include/asm-mips64/init.h b/include/asm-mips64/init.h index fdc132807..34c50b586 100644 --- a/include/asm-mips64/init.h +++ b/include/asm-mips64/init.h @@ -15,8 +15,6 @@ __arginit __init; \ __arginit -#define __initlocaldata __initdata - /* For assembly routines */ #define __INIT .section .text.init,"ax" #define __FINIT .previous diff --git a/include/asm-mips64/param.h b/include/asm-mips64/param.h index 5354eeb7d..81481bfed 100644 --- a/include/asm-mips64/param.h +++ b/include/asm-mips64/param.h @@ -29,4 +29,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ +#endif + #endif /* _ASM_PARAM_H */ diff --git a/include/asm-mips64/pgalloc.h b/include/asm-mips64/pgalloc.h index d9a766097..198b0bb3b 100644 --- a/include/asm-mips64/pgalloc.h +++ b/include/asm-mips64/pgalloc.h @@ -1,5 +1,4 @@ -/* $Id: pgalloc.h,v 1.3 2000/02/24 00:13:20 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -203,10 +202,4 @@ extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) extern int do_check_pgt_cache(int, int); -extern inline void set_pgdir(unsigned long address, pgd_t entry) -{ - printk("set_pgdir!\n"); - while(1); -} - #endif /* _ASM_PGALLOC_H */ diff --git a/include/asm-mips64/pgtable.h b/include/asm-mips64/pgtable.h index 5c872f673..4874a59e5 100644 --- a/include/asm-mips64/pgtable.h +++ b/include/asm-mips64/pgtable.h @@ -780,6 +780,8 @@ extern inline void set_context(unsigned long val) : : "r" (val)); } +#include <asm-generic/pgtable.h> + #endif /* !defined (_LANGUAGE_ASSEMBLY) */ #endif /* _ASM_PGTABLE_H */ diff --git a/include/asm-mips64/ptrace.h b/include/asm-mips64/ptrace.h index fcf067d17..773f8a0c0 100644 --- a/include/asm-mips64/ptrace.h +++ b/include/asm-mips64/ptrace.h @@ -1,11 +1,10 @@ -/* $Id: ptrace.h,v 1.3 1999/12/04 03:59:12 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 by Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 by Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #ifndef _ASM_PTRACE_H #define _ASM_PTRACE_H @@ -57,6 +56,19 @@ struct pt_regs { #endif /* !(_LANGUAGE_ASSEMBLY__) */ +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +/* #define PTRACE_GETREGS 12 */ +/* #define PTRACE_SETREGS 13 */ +/* #define PTRACE_GETFPREGS 14 */ +/* #define PTRACE_SETFPREGS 15 */ +/* #define PTRACE_GETFPXREGS 18 */ +/* #define PTRACE_SETFPXREGS 19 */ + +#define PTRACE_SETOPTIONS 21 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + #ifdef _LANGUAGE_ASSEMBLY #include <asm/offset.h> #endif /* (_LANGUAGE_ASSEMBLY__) */ diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h index 0fdd67844..02454f6cf 100644 --- a/include/asm-ppc/byteorder.h +++ b/include/asm-ppc/byteorder.h @@ -38,11 +38,7 @@ extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val) /* alas, egcs sounds like it has a bug in this code that doesn't use the inline asm correctly, and can cause file corruption. Until I hear that it's fixed, I can live without the extra speed. I hope. */ -#if !(__GNUC__ >= 2 && __GNUC_MINOR__ >= 90) #if 0 -# define __arch_swab16(x) ld_le16(&x) -# define __arch_swab32(x) ld_le32(&x) -#else static __inline__ __const__ __u16 ___arch__swab16(__u16 value) { __u16 result; @@ -68,8 +64,6 @@ static __inline__ __const__ __u32 ___arch__swab32(__u32 value) #define __arch__swab16(x) ___arch__swab16(x) #endif /* 0 */ -#endif - /* The same, but returns converted value from the location pointer by addr. */ #define __arch__swab16p(addr) ld_le16(addr) #define __arch__swab32p(addr) ld_le32(addr) diff --git a/include/asm-ppc/init.h b/include/asm-ppc/init.h index a25f6015e..00a1c79cc 100644 --- a/include/asm-ppc/init.h +++ b/include/asm-ppc/init.h @@ -3,7 +3,6 @@ #include <linux/init.h> -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 90 /* egcs */ #define __pmac __attribute__ ((__section__ (".text.pmac"))) #define __pmacdata __attribute__ ((__section__ (".data.pmac"))) #define __pmacfunc(__argpmac) \ @@ -35,24 +34,4 @@ __argopenfirmware __openfirmware; \ __argopenfirmware -#else /* not egcs */ - -#define __pmac -#define __pmacdata -#define __pmacfunc(x) x - -#define __prep -#define __prepdata -#define __prepfunc(x) x - -#define __apus -#define __apusdata -#define __apusfunc(x) x - -#define __openfirmware -#define __openfirmwaredata -#define __openfirmwarefunc(x) x - -#endif /* egcs */ - #endif /* _PPC_INIT_H */ diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index c5a90fba0..27c89e13e 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -488,6 +488,7 @@ extern void kernel_set_cachemode (unsigned long address, unsigned long size, #define io_remap_page_range remap_page_range +#include <asm-generic/pgtable.h> #endif __ASSEMBLY__ #endif /* _PPC_PGTABLE_H */ diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index d6509ea2f..ae4f3b505 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -408,6 +408,8 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma, #define module_map vmalloc #define module_unmap vfree +#include <asm-generic/pgtable.h> + #endif /* !__ASSEMBLY__ */ /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ diff --git a/include/asm-sh/pgalloc-2level.h b/include/asm-sh/pgalloc-2level.h index a106b23a3..a9c9fddc4 100644 --- a/include/asm-sh/pgalloc-2level.h +++ b/include/asm-sh/pgalloc-2level.h @@ -5,15 +5,15 @@ * traditional two-level paging, page table allocation routines: */ -extern __inline__ pmd_t *get_pmd_fast(void) +static __inline__ pmd_t *get_pmd_fast(void) { return (pmd_t *)0; } -extern __inline__ void free_pmd_fast(pmd_t *pmd) { } -extern __inline__ void free_pmd_slow(pmd_t *pmd) { } +static __inline__ void free_pmd_fast(pmd_t *pmd) { } +static __inline__ void free_pmd_slow(pmd_t *pmd) { } -extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) +static __inline__ pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) { if (!pgd) BUG(); diff --git a/include/asm-sh/pgalloc.h b/include/asm-sh/pgalloc.h index 0b728aee3..5984937fa 100644 --- a/include/asm-sh/pgalloc.h +++ b/include/asm-sh/pgalloc.h @@ -3,6 +3,7 @@ #include <asm/processor.h> #include <linux/threads.h> +#include <linux/slab.h> #define pgd_quicklist (current_cpu_data.pgd_quick) #define pmd_quicklist ((unsigned long *)0) @@ -17,18 +18,18 @@ * if any. */ -extern __inline__ pgd_t *get_pgd_slow(void) +static __inline__ pgd_t *get_pgd_slow(void) { - pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL); + unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t)); + pgd_t *ret = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL); + + if (ret) + memset(ret, 0, pgd_size); - if (ret) { - memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); - memcpy(ret + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - } return ret; } -extern __inline__ pgd_t *get_pgd_fast(void) +static __inline__ pgd_t *get_pgd_fast(void) { unsigned long *ret; @@ -41,22 +42,22 @@ extern __inline__ pgd_t *get_pgd_fast(void) return (pgd_t *)ret; } -extern __inline__ void free_pgd_fast(pgd_t *pgd) +static __inline__ void free_pgd_fast(pgd_t *pgd) { *(unsigned long *)pgd = (unsigned long) pgd_quicklist; pgd_quicklist = (unsigned long *) pgd; pgtable_cache_size++; } -extern __inline__ void free_pgd_slow(pgd_t *pgd) +static __inline__ void free_pgd_slow(pgd_t *pgd) { - free_page((unsigned long)pgd); + kfree(pgd); } extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted); -extern __inline__ pte_t *get_pte_fast(void) +static __inline__ pte_t *get_pte_fast(void) { unsigned long *ret; @@ -68,14 +69,14 @@ extern __inline__ pte_t *get_pte_fast(void) return (pte_t *)ret; } -extern __inline__ void free_pte_fast(pte_t *pte) +static __inline__ void free_pte_fast(pte_t *pte) { *(unsigned long *)pte = (unsigned long) pte_quicklist; pte_quicklist = (unsigned long *) pte; pgtable_cache_size++; } -extern __inline__ void free_pte_slow(pte_t *pte) +static __inline__ void free_pte_slow(pte_t *pte) { free_page((unsigned long)pte); } @@ -85,7 +86,7 @@ extern __inline__ void free_pte_slow(pte_t *pte) #define pgd_free(pgd) free_pgd_slow(pgd) #define pgd_alloc() get_pgd_fast() -extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) +static __inline__ pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) { if (!pmd) BUG(); @@ -105,7 +106,7 @@ extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) return (pte_t *) pmd_page(*pmd) + address; } -extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) +static __inline__ pte_t * pte_alloc(pmd_t * pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); @@ -132,7 +133,7 @@ fix: * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -extern inline void pmd_free(pmd_t * pmd) +static __inline__ void pmd_free(pmd_t * pmd) { } @@ -141,22 +142,6 @@ extern inline void pmd_free(pmd_t * pmd) extern int do_check_pgt_cache(int, int); -extern inline void set_pgdir(unsigned long address, pgd_t entry) -{ - struct task_struct * p; - pgd_t *pgd; - - read_lock(&tasklist_lock); - for_each_task(p) { - if (!p->mm) - continue; - *pgd_offset(p->mm,address) = entry; - } - read_unlock(&tasklist_lock); - for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; -} - /* * TLB flushing: * @@ -174,8 +159,9 @@ extern void flush_tlb_mm(struct mm_struct *mm); extern void flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end); extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); -extern inline void flush_tlb_pgtables(struct mm_struct *mm, - unsigned long start, unsigned long end) + +static __inline__ void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) { } diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index f84b7904a..323b7eb7c 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -257,6 +257,8 @@ extern void update_mmu_cache(struct vm_area_struct * vma, #define module_map vmalloc #define module_unmap vfree +#include <asm-generic/pgtable.h> + #endif /* !__ASSEMBLY__ */ /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ diff --git a/include/asm-sparc/audioio.h b/include/asm-sparc/audioio.h index ed50485d2..d0c2ae9b3 100644 --- a/include/asm-sparc/audioio.h +++ b/include/asm-sparc/audioio.h @@ -428,7 +428,6 @@ extern int register_sparcaudio_driver(struct sparcaudio_driver *, int); extern int unregister_sparcaudio_driver(struct sparcaudio_driver *, int); extern void sparcaudio_output_done(struct sparcaudio_driver *, int); extern void sparcaudio_input_done(struct sparcaudio_driver *, int); -extern int sparcaudio_init(void); extern int amd7930_init(void); extern int cs4231_init(void); extern int dbri_init(void); diff --git a/include/asm-sparc/fcntl.h b/include/asm-sparc/fcntl.h index d481e7b27..00e5e5b4c 100644 --- a/include/asm-sparc/fcntl.h +++ b/include/asm-sparc/fcntl.h @@ -1,4 +1,4 @@ -/* $Id: fcntl.h,v 1.14 2000/08/12 20:49:49 jj Exp $ */ +/* $Id: fcntl.h,v 1.15 2000/09/23 02:09:21 davem Exp $ */ #ifndef _SPARC_FCNTL_H #define _SPARC_FCNTL_H diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h index e6373384f..603a51999 100644 --- a/include/asm-sparc/page.h +++ b/include/asm-sparc/page.h @@ -1,4 +1,4 @@ -/* $Id: page.h,v 1.54 2000/08/10 01:04:53 davem Exp $ +/* $Id: page.h,v 1.55 2000/10/30 21:01:41 davem Exp $ * page.h: Various defines and such for MMU operations on the Sparc for * the Linux kernel. * @@ -38,7 +38,6 @@ * this so lets disable it. - Anton */ #if 0 -/* #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) */ /* We need the mb()'s so we don't trigger a compiler bug - Anton */ #define BUG() do { \ mb(); \ diff --git a/include/asm-sparc/param.h b/include/asm-sparc/param.h index 3fef0c05e..fdb5d160d 100644 --- a/include/asm-sparc/param.h +++ b/include/asm-sparc/param.h @@ -1,4 +1,4 @@ -/* $Id: param.h,v 1.3 1995/11/25 02:32:18 davem Exp $ */ +/* $Id: param.h,v 1.4 2000/10/30 21:01:41 davem Exp $ */ #ifndef _ASMSPARC_PARAM_H #define _ASMSPARC_PARAM_H @@ -21,4 +21,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ +#endif + #endif diff --git a/include/asm-sparc/pgalloc.h b/include/asm-sparc/pgalloc.h index 180709c85..167387e5b 100644 --- a/include/asm-sparc/pgalloc.h +++ b/include/asm-sparc/pgalloc.h @@ -1,4 +1,4 @@ -/* $Id: pgalloc.h,v 1.9 2000/08/01 04:53:58 anton Exp $ */ +/* $Id: pgalloc.h,v 1.11 2000/10/16 14:32:49 anton Exp $ */ #ifndef _SPARC_PGALLOC_H #define _SPARC_PGALLOC_H @@ -139,8 +139,4 @@ BTFIXUPDEF_CALL(pgd_t *, pgd_alloc, void) #define pgd_free(pgd) BTFIXUP_CALL(pgd_free)(pgd) #define pgd_alloc() BTFIXUP_CALL(pgd_alloc)() -BTFIXUPDEF_CALL(void, set_pgdir, unsigned long, pgd_t) - -#define set_pgdir(address,entry) BTFIXUP_CALL(set_pgdir)(address,entry) - #endif /* _SPARC64_PGALLOC_H */ diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index 8562fc287..251ff01da 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.102 2000/08/14 00:46:13 anton Exp $ */ +/* $Id: pgtable.h,v 1.105 2000/10/30 21:01:41 davem Exp $ */ #ifndef _SPARC_PGTABLE_H #define _SPARC_PGTABLE_H @@ -88,18 +88,9 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd) #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) #define pte_ERROR(e) __builtin_trap() #define pmd_ERROR(e) __builtin_trap() #define pgd_ERROR(e) __builtin_trap() -#else -#define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -#define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) -#define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) -#endif BTFIXUPDEF_INT(page_none) BTFIXUPDEF_INT(page_shared) @@ -321,8 +312,10 @@ BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int) #define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space) BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *) +BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *) #define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp) +#define pmd_set(pmdp,ptep) BTFIXUP_CALL(pmd_set)(pmdp,ptep) BTFIXUPDEF_INT(pte_modify_mask) @@ -455,6 +448,8 @@ extern unsigned long *sparc_valid_addr_bitmap; extern int io_remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot, int space); +#include <asm-generic/pgtable.h> + #endif /* !(__ASSEMBLY__) */ /* We provide our own get_unmapped_area to cope with VA holes for userland */ diff --git a/include/asm-sparc/resource.h b/include/asm-sparc/resource.h index 24cca3ba1..8237763e5 100644 --- a/include/asm-sparc/resource.h +++ b/include/asm-sparc/resource.h @@ -1,4 +1,4 @@ -/* $Id: resource.h,v 1.11 1999/12/15 17:51:59 jj Exp $ +/* $Id: resource.h,v 1.12 2000/09/23 02:09:21 davem Exp $ * resource.h: Resource definitions. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h index 5f7040345..f6504165d 100644 --- a/include/asm-sparc/smp.h +++ b/include/asm-sparc/smp.h @@ -93,6 +93,12 @@ extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg unsigned long arg3, unsigned long arg4, unsigned long arg5) { smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); } +extern __inline__ int smp_call_function(void (*func)(void *info), void *info, int nonatomic, int wait) +{ + xc1((smpfunc_t)func, (unsigned long)info); + return 0; +} + extern __volatile__ int __cpu_number_map[NR_CPUS]; extern __volatile__ int __cpu_logical_map[NR_CPUS]; extern unsigned long smp_proc_in_lock[NR_CPUS]; diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h index 2461ec29d..1a6cc2bfc 100644 --- a/include/asm-sparc64/atomic.h +++ b/include/asm-sparc64/atomic.h @@ -1,4 +1,4 @@ -/* $Id: atomic.h,v 1.20 2000/03/16 16:44:44 davem Exp $ +/* $Id: atomic.h,v 1.21 2000/10/03 07:28:56 anton Exp $ * atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * diff --git a/include/asm-sparc64/audioio.h b/include/asm-sparc64/audioio.h index fc5458949..984b7c796 100644 --- a/include/asm-sparc64/audioio.h +++ b/include/asm-sparc64/audioio.h @@ -428,7 +428,6 @@ extern int register_sparcaudio_driver(struct sparcaudio_driver *, int); extern int unregister_sparcaudio_driver(struct sparcaudio_driver *, int); extern void sparcaudio_output_done(struct sparcaudio_driver *, int); extern void sparcaudio_input_done(struct sparcaudio_driver *, int); -extern int sparcaudio_init(void); extern int amd7930_init(void); extern int cs4231_init(void); diff --git a/include/asm-sparc64/envctrl.h b/include/asm-sparc64/envctrl.h index 1b5e4da9c..e16de8fb2 100644 --- a/include/asm-sparc64/envctrl.h +++ b/include/asm-sparc64/envctrl.h @@ -1,17 +1,101 @@ -/* $Id: envctrl.h,v 1.1 1998/05/16 17:26:07 ecd Exp $ +/* $Id: envctrl.h,v 1.2 2000/10/17 16:20:36 davem Exp $ * * envctrl.h: Definitions for access to the i2c environment * monitoring on Ultrasparc systems. * * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) + * Copyright (C) 2000 Vinh Truong (vinh.truong@eng.sun.com) + * VT - Add all ioctl commands and environment status definitions + * VT - Add application note */ - #ifndef _SPARC64_ENVCTRL_H #define _SPARC64_ENVCTRL_H 1 #include <linux/ioctl.h> -#define I2CIOCSADR _IOW('p', 0x40, int) -#define I2CIOCGADR _IOR('p', 0x41, int) +/* Application note: + * + * The driver supports 4 operations: open(), close(), ioctl(), read() + * The device name is /dev/envctrl. + * Below is sample usage: + * + * fd = open("/dev/envtrl", O_RDONLY); + * if (ioctl(fd, ENVCTRL_READ_SHUTDOWN_TEMPERATURE, 0) < 0) + * printf("error\n"); + * ret = read(fd, buf, 10); + * close(fd); + * + * Notice in the case of cpu voltage and temperature, the default is + * cpu0. If we need to know the info of cpu1, cpu2, cpu3, we need to + * pass in cpu number in ioctl() last parameter. For example, to + * get the voltage of cpu2: + * + * ioctlbuf[0] = 2; + * if (ioctl(fd, ENVCTRL_READ_CPU_VOLTAGE, ioctlbuf) < 0) + * printf("error\n"); + * ret = read(fd, buf, 10); + * + * All the return values are in ascii. So check read return value + * and do appropriate conversions in your application. + */ + +/* IOCTL commands */ + +/* Note: these commands reflect possible monitor features. + * Some boards choose to support some of the features only. + */ +#define ENVCTRL_RD_CPU_TEMPERATURE _IOR('p', 0x40, int) +#define ENVCTRL_RD_CPU_VOLTAGE _IOR('p', 0x41, int) +#define ENVCTRL_RD_FAN_STATUS _IOR('p', 0x42, int) +#define ENVCTRL_RD_WARNING_TEMPERATURE _IOR('p', 0x43, int) +#define ENVCTRL_RD_SHUTDOWN_TEMPERATURE _IOR('p', 0x44, int) +#define ENVCTRL_RD_VOLTAGE_STATUS _IOR('p', 0x45, int) +#define ENVCTRL_RD_SCSI_TEMPERATURE _IOR('p', 0x46, int) +#define ENVCTRL_RD_ETHERNET_TEMPERATURE _IOR('p', 0x47, int) +#define ENVCTRL_RD_MTHRBD_TEMPERATURE _IOR('p', 0x48, int) + +/* Read return values for a voltage status request. */ +#define ENVCTRL_VOLTAGE_POWERSUPPLY_GOOD 0x01 +#define ENVCTRL_VOLTAGE_BAD 0x02 +#define ENVCTRL_POWERSUPPLY_BAD 0x03 +#define ENVCTRL_VOLTAGE_POWERSUPPLY_BAD 0x04 + +/* Read return values for a fan status request. + * A failure match means either the fan fails or + * the fan is not connected. Some boards have optional + * connectors to connect extra fans. + * + * There are maximum 8 monitor fans. Some are cpu fans + * some are system fans. The mask below only indicates + * fan by order number. + * Below is a sample application: + * + * if (ioctl(fd, ENVCTRL_READ_FAN_STATUS, 0) < 0) { + * printf("ioctl fan failed\n"); + * } + * if (read(fd, rslt, 1) <= 0) { + * printf("error or fan not monitored\n"); + * } else { + * if (rslt[0] == ENVCTRL_ALL_FANS_GOOD) { + * printf("all fans good\n"); + * } else if (rslt[0] == ENVCTRL_ALL_FANS_BAD) { + * printf("all fans bad\n"); + * } else { + * if (rslt[0] & ENVCTRL_FAN0_FAILURE_MASK) { + * printf("fan 0 failed or not connected\n"); + * } + * ...... + */ + +#define ENVCTRL_ALL_FANS_GOOD 0x00 +#define ENVCTRL_FAN0_FAILURE_MASK 0x01 +#define ENVCTRL_FAN1_FAILURE_MASK 0x02 +#define ENVCTRL_FAN2_FAILURE_MASK 0x04 +#define ENVCTRL_FAN3_FAILURE_MASK 0x08 +#define ENVCTRL_FAN4_FAILURE_MASK 0x10 +#define ENVCTRL_FAN5_FAILURE_MASK 0x20 +#define ENVCTRL_FAN6_FAILURE_MASK 0x40 +#define ENVCTRL_FAN7_FAILURE_MASK 0x80 +#define ENVCTRL_ALL_FANS_BAD 0xFF #endif /* !(_SPARC64_ENVCTRL_H) */ diff --git a/include/asm-sparc64/fcntl.h b/include/asm-sparc64/fcntl.h index e485ed45f..5b119bc78 100644 --- a/include/asm-sparc64/fcntl.h +++ b/include/asm-sparc64/fcntl.h @@ -1,4 +1,4 @@ -/* $Id: fcntl.h,v 1.10 2000/08/12 20:49:49 jj Exp $ */ +/* $Id: fcntl.h,v 1.11 2000/09/23 02:09:21 davem Exp $ */ #ifndef _SPARC64_FCNTL_H #define _SPARC64_FCNTL_H diff --git a/include/asm-sparc64/param.h b/include/asm-sparc64/param.h index 51affe3e5..89ed7ea78 100644 --- a/include/asm-sparc64/param.h +++ b/include/asm-sparc64/param.h @@ -1,4 +1,4 @@ -/* $Id: param.h,v 1.1 1996/12/02 00:08:24 davem Exp $ */ +/* $Id: param.h,v 1.2 2000/10/30 21:01:41 davem Exp $ */ #ifndef _ASMSPARC64_PARAM_H #define _ASMSPARC64_PARAM_H @@ -21,4 +21,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ +#endif + #endif /* _ASMSPARC64_PARAM_H */ diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index b81b9cee4..be3dde29c 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -304,7 +304,4 @@ extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) extern int do_check_pgt_cache(int, int); -/* Nothing to do on sparc64 :) */ -#define set_pgdir(address, entry) do { } while(0) - #endif /* _SPARC64_PGALLOC_H */ diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 070fb31db..62c4c4ef4 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.131 2000/08/11 03:00:14 davem Exp $ +/* $Id: pgtable.h,v 1.132 2000/10/19 00:50:16 davem Exp $ * pgtable.h: SpitFire page table operations. * * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -295,6 +295,8 @@ extern unsigned long *sparc64_valid_addr_bitmap; extern int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space); +#include <asm-generic/pgtable.h> + #endif /* !(__ASSEMBLY__) */ /* We provide our own get_unmapped_area to cope with VA holes for userland */ diff --git a/include/asm-sparc64/posix_types.h b/include/asm-sparc64/posix_types.h index e486344ad..9ee6edf87 100644 --- a/include/asm-sparc64/posix_types.h +++ b/include/asm-sparc64/posix_types.h @@ -7,14 +7,8 @@ * assume GCC is being used. */ -#if (__GNUC__ > 2) || (__GNUC_MINOR__ >= 8) -typedef unsigned long int __kernel_size_t; -typedef long int __kernel_ssize_t; -#else -typedef unsigned long long __kernel_size_t; -typedef long long __kernel_ssize_t; -#endif - +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; typedef long __kernel_ptrdiff_t; typedef long __kernel_time_t; typedef long __kernel_clock_t; diff --git a/include/asm-sparc64/resource.h b/include/asm-sparc64/resource.h index 658637fbc..06150c09f 100644 --- a/include/asm-sparc64/resource.h +++ b/include/asm-sparc64/resource.h @@ -1,4 +1,4 @@ -/* $Id: resource.h,v 1.7 1999/12/15 17:52:08 jj Exp $ +/* $Id: resource.h,v 1.8 2000/09/23 02:09:21 davem Exp $ * resource.h: Resource definitions. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h index 04667b185..f24ff8415 100644 --- a/include/asm-sparc64/spitfire.h +++ b/include/asm-sparc64/spitfire.h @@ -1,4 +1,4 @@ -/* $Id: spitfire.h,v 1.9 1998/04/28 08:23:33 davem Exp $ +/* $Id: spitfire.h,v 1.10 2000/10/06 13:10:29 anton Exp $ * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -117,6 +117,7 @@ extern __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long __asm__ __volatile__("stxa %0, [%1] %2" : /* No outputs */ : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG)); + membar("#Sync"); } /* The instruction cache lines are flushed with this, but note that diff --git a/include/asm-sparc64/string.h b/include/asm-sparc64/string.h index 337b61784..330b9c482 100644 --- a/include/asm-sparc64/string.h +++ b/include/asm-sparc64/string.h @@ -1,4 +1,4 @@ -/* $Id: string.h,v 1.17 2000/06/19 06:24:58 davem Exp $ +/* $Id: string.h,v 1.18 2000/10/30 21:01:41 davem Exp $ * string.h: External definitions for optimized assembly string * routines for the Linux Kernel. * @@ -110,18 +110,7 @@ static inline void *__constant_memset(void *s, int c, __kernel_size_t count) #define __HAVE_ARCH_STRLEN extern __kernel_size_t __strlen(const char *); - -#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91) extern __kernel_size_t strlen(const char *); -#else /* !EGCS */ -/* Ugly but it works around a bug in our original sparc64-linux-gcc. */ -#undef strlen -#define strlen(__arg0) \ -({ int __strlen_res = __strlen(__arg0) + 1; \ - __strlen_res -= 1; \ - __strlen_res; \ -}) -#endif /* !EGCS */ #define __HAVE_ARCH_STRNCMP diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h index 52ff6d8a3..99aa24761 100644 --- a/include/linux/auto_fs4.h +++ b/include/linux/auto_fs4.h @@ -1,4 +1,4 @@ -/* -*- c-mode -*- +/* -*- c -*- * linux/include/linux/auto_fs4.h * * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index 359905839..6560f2901 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h @@ -8,6 +8,7 @@ #include <asm/dma.h> #include <linux/cache.h> #include <linux/init.h> +#include <linux/mmzone.h> /* * simple boot-time physical memory area allocator. @@ -43,16 +44,16 @@ extern void * __init __alloc_bootmem (unsigned long size, unsigned long align, u __alloc_bootmem((x), PAGE_SIZE, 0) extern unsigned long __init free_all_bootmem (void); -extern unsigned long __init init_bootmem_node (int nid, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn); -extern void __init reserve_bootmem_node (int nid, unsigned long physaddr, unsigned long size); -extern void __init free_bootmem_node (int nid, unsigned long addr, unsigned long size); -extern unsigned long __init free_all_bootmem_node (int nid); -extern void * __init __alloc_bootmem_node (int nid, unsigned long size, unsigned long align, unsigned long goal); -#define alloc_bootmem_node(nid, x) \ - __alloc_bootmem_node((nid), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) -#define alloc_bootmem_pages_node(nid, x) \ - __alloc_bootmem_node((nid), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) -#define alloc_bootmem_low_pages_node(nid, x) \ - __alloc_bootmem_node((nid), (x), PAGE_SIZE, 0) +extern unsigned long __init init_bootmem_node (pg_data_t *pgdat, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn); +extern void __init reserve_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsigned long size); +extern void __init free_bootmem_node (pg_data_t *pgdat, unsigned long addr, unsigned long size); +extern unsigned long __init free_all_bootmem_node (pg_data_t *pgdat); +extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal); +#define alloc_bootmem_node(pgdat, x) \ + __alloc_bootmem_node((pgdat), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) +#define alloc_bootmem_pages_node(pgdat, x) \ + __alloc_bootmem_node((pgdat), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) +#define alloc_bootmem_low_pages_node(pgdat, x) \ + __alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0) #endif /* _LINUX_BOOTMEM_H */ diff --git a/include/linux/byteorder/big_endian.h b/include/linux/byteorder/big_endian.h index ebd81c013..b84efd74c 100644 --- a/include/linux/byteorder/big_endian.h +++ b/include/linux/byteorder/big_endian.h @@ -14,12 +14,12 @@ #define __constant_ntohl(x) ((__u32)(x)) #define __constant_htons(x) ((__u16)(x)) #define __constant_ntohs(x) ((__u16)(x)) -#define __constant_cpu_to_le64(x) ___swab64((x)) -#define __constant_le64_to_cpu(x) ___swab64((x)) -#define __constant_cpu_to_le32(x) ___swab32((x)) -#define __constant_le32_to_cpu(x) ___swab32((x)) -#define __constant_cpu_to_le16(x) ___swab16((x)) -#define __constant_le16_to_cpu(x) ___swab16((x)) +#define __constant_cpu_to_le64(x) ___constant_swab64((x)) +#define __constant_le64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_le32(x) ___constant_swab32((x)) +#define __constant_le32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_le16(x) ___constant_swab16((x)) +#define __constant_le16_to_cpu(x) ___constant_swab16((x)) #define __constant_cpu_to_be64(x) ((__u64)(x)) #define __constant_be64_to_cpu(x) ((__u64)(x)) #define __constant_cpu_to_be32(x) ((__u32)(x)) diff --git a/include/linux/byteorder/little_endian.h b/include/linux/byteorder/little_endian.h index 5a5412403..143166362 100644 --- a/include/linux/byteorder/little_endian.h +++ b/include/linux/byteorder/little_endian.h @@ -10,22 +10,22 @@ #include <linux/byteorder/swab.h> -#define __constant_htonl(x) ___swab32((x)) -#define __constant_ntohl(x) ___swab32((x)) -#define __constant_htons(x) ___swab16((x)) -#define __constant_ntohs(x) ___swab16((x)) +#define __constant_htonl(x) ___constant_swab32((x)) +#define __constant_ntohl(x) ___constant_swab32((x)) +#define __constant_htons(x) ___constant_swab16((x)) +#define __constant_ntohs(x) ___constant_swab16((x)) #define __constant_cpu_to_le64(x) ((__u64)(x)) #define __constant_le64_to_cpu(x) ((__u64)(x)) #define __constant_cpu_to_le32(x) ((__u32)(x)) #define __constant_le32_to_cpu(x) ((__u32)(x)) #define __constant_cpu_to_le16(x) ((__u16)(x)) #define __constant_le16_to_cpu(x) ((__u16)(x)) -#define __constant_cpu_to_be64(x) ___swab64((x)) -#define __constant_be64_to_cpu(x) ___swab64((x)) -#define __constant_cpu_to_be32(x) ___swab32((x)) -#define __constant_be32_to_cpu(x) ___swab32((x)) -#define __constant_cpu_to_be16(x) ___swab16((x)) -#define __constant_be16_to_cpu(x) ___swab16((x)) +#define __constant_cpu_to_be64(x) ___constant_swab64((x)) +#define __constant_be64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_be32(x) ___constant_swab32((x)) +#define __constant_be32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_be16(x) ___constant_swab16((x)) +#define __constant_be16_to_cpu(x) ___constant_swab16((x)) #define __cpu_to_le64(x) ((__u64)(x)) #define __le64_to_cpu(x) ((__u64)(x)) #define __cpu_to_le32(x) ((__u32)(x)) diff --git a/include/linux/byteorder/pdp_endian.h b/include/linux/byteorder/pdp_endian.h index 90f8c7433..618631cbc 100644 --- a/include/linux/byteorder/pdp_endian.h +++ b/include/linux/byteorder/pdp_endian.h @@ -30,22 +30,22 @@ #include <linux/byteorder/swab.h> #include <linux/byteorder/swabb.h> -#define __constant_htonl(x) ___swahb32((x)) -#define __constant_ntohl(x) ___swahb32((x)) -#define __constant_htons(x) ___swab16((x)) -#define __constant_ntohs(x) ___swab16((x)) +#define __constant_htonl(x) ___constant_swahb32((x)) +#define __constant_ntohl(x) ___constant_swahb32((x)) +#define __constant_htons(x) ___constant_swab16((x)) +#define __constant_ntohs(x) ___constant_swab16((x)) #define __constant_cpu_to_le64(x) I DON'T KNOW #define __constant_le64_to_cpu(x) I DON'T KNOW -#define __constant_cpu_to_le32(x) ___swahw32((x)) -#define __constant_le32_to_cpu(x) ___swahw32((x)) +#define __constant_cpu_to_le32(x) ___constant_swahw32((x)) +#define __constant_le32_to_cpu(x) ___constant_swahw32((x)) #define __constant_cpu_to_le16(x) ((__u16)(x) #define __constant_le16_to_cpu(x) ((__u16)(x) #define __constant_cpu_to_be64(x) I DON'T KNOW #define __constant_be64_to_cpu(x) I DON'T KNOW -#define __constant_cpu_to_be32(x) ___swahb32((x)) -#define __constant_be32_to_cpu(x) ___swahb32((x)) -#define __constant_cpu_to_be16(x) ___swab16((x)) -#define __constant_be16_to_cpu(x) ___swab16((x)) +#define __constant_cpu_to_be32(x) ___constant_swahb32((x)) +#define __constant_be32_to_cpu(x) ___constant_swahb32((x)) +#define __constant_cpu_to_be16(x) ___constant_swab16((x)) +#define __constant_be16_to_cpu(x) ___constant_swab16((x)) #define __cpu_to_le64(x) I DON'T KNOW #define __le64_to_cpu(x) I DON'T KNOW #define __cpu_to_le32(x) ___swahw32((x)) diff --git a/include/linux/byteorder/swab.h b/include/linux/byteorder/swab.h index 23f1be7d7..f75dccef4 100644 --- a/include/linux/byteorder/swab.h +++ b/include/linux/byteorder/swab.h @@ -19,16 +19,48 @@ * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. */ #define ___swab16(x) \ +({ \ + __u16 __x = (x); \ + ((__u16)( \ + (((__u16)(__x) & (__u16)0x00ffU) << 8) | \ + (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \ +}) + +#define ___swab32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \ +}) + +#define ___swab64(x) \ +({ \ + __u64 __x = (x); \ + ((__u64)( \ + (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \ +}) + +#define ___constant_swab16(x) \ ((__u16)( \ (((__u16)(x) & (__u16)0x00ffU) << 8) | \ (((__u16)(x) & (__u16)0xff00U) >> 8) )) -#define ___swab32(x) \ +#define ___constant_swab32(x) \ ((__u32)( \ (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) -#define ___swab64(x) \ +#define ___constant_swab64(x) \ ((__u64)( \ (__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \ (__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \ diff --git a/include/linux/byteorder/swabb.h b/include/linux/byteorder/swabb.h index 782db2e8e..a10ef3086 100644 --- a/include/linux/byteorder/swabb.h +++ b/include/linux/byteorder/swabb.h @@ -25,12 +25,26 @@ * */ - #define ___swahw32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x0000ffffUL) << 16) | \ + (((__u32)(__x) & (__u32)0xffff0000UL) >> 16) )); \ +}) +#define ___swahb32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x00ff00ffUL) << 8) | \ + (((__u32)(__x) & (__u32)0xff00ff00UL) >> 8) )) \ +}) + +#define ___constant_swahw32(x) \ ((__u32)( \ (((__u32)(x) & (__u32)0x0000ffffUL) << 16) | \ (((__u32)(x) & (__u32)0xffff0000UL) >> 16) )) -#define ___swahb32(x) \ +#define ___constant_swahb32(x) \ ((__u32)( \ (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) | \ (((__u32)(x) & (__u32)0xff00ff00UL) >> 8) )) diff --git a/include/linux/coda_linux.h b/include/linux/coda_linux.h index 3374036ce..f5e795919 100644 --- a/include/linux/coda_linux.h +++ b/include/linux/coda_linux.h @@ -40,8 +40,6 @@ int coda_release(struct inode *i, struct file *f); int coda_permission(struct inode *inode, int mask); int coda_revalidate_inode(struct dentry *); int coda_notify_change(struct dentry *, struct iattr *); -int coda_pioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg); /* global variables */ extern int coda_debug; diff --git a/include/linux/console.h b/include/linux/console.h index f8da31cbd..288f83b96 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -50,16 +50,16 @@ struct consw { unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); }; -extern struct consw *conswitchp; +extern const struct consw *conswitchp; -extern struct consw dummy_con; /* dummy console buffer */ -extern struct consw fb_con; /* frame buffer based console */ -extern struct consw vga_con; /* VGA text console */ -extern struct consw newport_con; /* SGI Newport console */ -extern struct consw prom_con; /* SPARC PROM console */ +extern const struct consw dummy_con; /* dummy console buffer */ +extern const struct consw fb_con; /* frame buffer based console */ +extern const struct consw vga_con; /* VGA text console */ +extern const struct consw newport_con; /* SGI Newport console */ +extern const struct consw prom_con; /* SPARC PROM console */ -void take_over_console(struct consw *sw, int first, int last, int deflt); -void give_up_console(struct consw *sw); +void take_over_console(const struct consw *sw, int first, int last, int deflt); +void give_up_console(const struct consw *sw); /* scroll */ #define SM_UP (1) diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index 0f664086a..4dc4750ac 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h @@ -16,7 +16,7 @@ struct vc_data { unsigned int vc_cols; /* [#] Console size */ unsigned int vc_rows; unsigned int vc_size_row; /* Bytes per row */ - struct consw *vc_sw; + const struct consw *vc_sw; unsigned short *vc_screenbuf; /* In-memory character/attribute buffer */ unsigned int vc_screenbuf_size; unsigned char vc_attr; /* Current attributes */ diff --git a/include/linux/divert.h b/include/linux/divert.h new file mode 100644 index 000000000..624bc55ed --- /dev/null +++ b/include/linux/divert.h @@ -0,0 +1,117 @@ +/* + * Frame Diversion, Benoit Locher <Benoit.Locher@skf.com> + * + * Changes: + * 06/09/2000 BL: initial version + * + */ + +#ifndef _LINUX_DIVERT_H +#define _LINUX_DIVERT_H + +#include <asm/types.h> + +#define MAX_DIVERT_PORTS 8 /* Max number of ports to divert (tcp, udp) */ + +/* Divertable protocols */ +#define DIVERT_PROTO_NONE 0x0000 +#define DIVERT_PROTO_IP 0x0001 +#define DIVERT_PROTO_ICMP 0x0002 +#define DIVERT_PROTO_TCP 0x0004 +#define DIVERT_PROTO_UDP 0x0008 + +/* + * This is an Ethernet Frame Diverter option block + */ +struct divert_blk +{ + int divert; /* are we active */ + unsigned int protos; /* protocols */ + u16 tcp_dst[MAX_DIVERT_PORTS]; /* specific tcp dst ports to divert */ + u16 tcp_src[MAX_DIVERT_PORTS]; /* specific tcp src ports to divert */ + u16 udp_dst[MAX_DIVERT_PORTS]; /* specific udp dst ports to divert */ + u16 udp_src[MAX_DIVERT_PORTS]; /* specific udp src ports to divert */ +}; + +/* + * Diversion control block, for configuration with the userspace tool + * divert + */ + +typedef union _divert_cf_arg +{ + s16 int16; + u16 uint16; + s32 int32; + u32 uint32; + s64 int64; + u64 uint64; + void *ptr; +} divert_cf_arg; + + +struct divert_cf +{ + int cmd; /* Command */ + divert_cf_arg arg1, + arg2, + arg3; + int dev_index; /* device index (eth0=0, etc...) */ +}; + + +/* Diversion commands */ +#define DIVCMD_DIVERT 1 /* ENABLE/DISABLE diversion */ +#define DIVCMD_IP 2 /* ENABLE/DISABLE whold IP diversion */ +#define DIVCMD_TCP 3 /* ENABLE/DISABLE whold TCP diversion */ +#define DIVCMD_TCPDST 4 /* ADD/REMOVE TCP DST port for diversion */ +#define DIVCMD_TCPSRC 5 /* ADD/REMOVE TCP SRC port for diversion */ +#define DIVCMD_UDP 6 /* ENABLE/DISABLE whole UDP diversion */ +#define DIVCMD_UDPDST 7 /* ADD/REMOVE UDP DST port for diversion */ +#define DIVCMD_UDPSRC 8 /* ADD/REMOVE UDP SRC port for diversion */ +#define DIVCMD_ICMP 9 /* ENABLE/DISABLE whole ICMP diversion */ +#define DIVCMD_GETSTATUS 10 /* GET the status of the diverter */ +#define DIVCMD_RESET 11 /* Reset the diverter on the specified dev */ +#define DIVCMD_GETVERSION 12 /* Retrieve the diverter code version (char[32]) */ + +/* General syntax of the commands: + * + * DIVCMD_xxxxxx(arg1, arg2, arg3, dev_index) + * + * SIOCSIFDIVERT: + * DIVCMD_DIVERT(DIVARG1_ENABLE|DIVARG1_DISABLE, , ,ifindex) + * DIVCMD_IP(DIVARG1_ENABLE|DIVARG1_DISABLE, , , ifindex) + * DIVCMD_TCP(DIVARG1_ENABLE|DIVARG1_DISABLE, , , ifindex) + * DIVCMD_TCPDST(DIVARG1_ADD|DIVARG1_REMOVE, port, , ifindex) + * DIVCMD_TCPSRC(DIVARG1_ADD|DIVARG1_REMOVE, port, , ifindex) + * DIVCMD_UDP(DIVARG1_ENABLE|DIVARG1_DISABLE, , , ifindex) + * DIVCMD_UDPDST(DIVARG1_ADD|DIVARG1_REMOVE, port, , ifindex) + * DIVCMD_UDPSRC(DIVARG1_ADD|DIVARG1_REMOVE, port, , ifindex) + * DIVCMD_ICMP(DIVARG1_ENABLE|DIVARG1_DISABLE, , , ifindex) + * DIVCMD_RESET(, , , ifindex) + * + * SIOGIFDIVERT: + * DIVCMD_GETSTATUS(divert_blk, , , ifindex) + * DIVCMD_GETVERSION(string[3]) + */ + + +/* Possible values for arg1 */ +#define DIVARG1_ENABLE 0 /* ENABLE something */ +#define DIVARG1_DISABLE 1 /* DISABLE something */ +#define DIVARG1_ADD 2 /* ADD something */ +#define DIVARG1_REMOVE 3 /* REMOVE something */ + + +#ifdef __KERNEL__ + +/* diverter functions */ +#include <linux/skbuff.h> +int alloc_divert_blk(struct net_device *); +void free_divert_blk(struct net_device *); +int divert_ioctl(unsigned int cmd, struct divert_cf *arg); +void divert_frame(struct sk_buff *skb); + +#endif __KERNEL__ + +#endif /* _LINUX_DIVERT_H */ diff --git a/include/linux/elf.h b/include/linux/elf.h index 45e9f1007..3fe04c45e 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -165,6 +165,7 @@ typedef __u64 Elf64_Word; #define AT_EGID 14 /* effective gid */ #define AT_PLATFORM 15 /* string identifying CPU for optimizations */ #define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ +#define AT_CLKTCK 17 /* frequency at which times() increments */ typedef struct dynamic{ Elf32_Sword d_tag; diff --git a/include/linux/fs.h b/include/linux/fs.h index eb2241226..72effef4a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -517,8 +517,7 @@ typedef struct files_struct *fl_owner_t; struct file_lock { struct file_lock *fl_next; /* singly linked list for this inode */ struct list_head fl_link; /* doubly linked list of all locks */ - struct list_head fl_block; /* circular list of blocked processes */ - struct list_head fl_list; /* block list member */ + struct list_head fl_block; /* circular list of blocked processes */ fl_owner_t fl_owner; unsigned int fl_pid; wait_queue_head_t fl_wait; diff --git a/include/linux/ide.h b/include/linux/ide.h index e00d44760..23866ce79 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -212,6 +212,9 @@ typedef unsigned char byte; /* used everywhere */ (drive)->quirk_list = hwif->quirkproc(drive); \ } +#define IDE_DEBUG(lineno) \ + printk("%s,%s,line=%d\n", __FILE__, __FUNCTION__, (lineno)) + /* * Check for an interrupt and acknowledge the interrupt status */ diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 61e5f5c6b..9c746e873 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -58,6 +58,10 @@ #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ #define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ #define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */ +#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ +#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport + * over Ethernet + */ /* * Non DIX types. Won't clash for 1500 types. diff --git a/include/linux/in.h b/include/linux/in.h index 37db22a9a..1d5f14ad6 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -66,6 +66,7 @@ struct in_addr { #define IP_RECVTTL 12 #define IP_RECVTOS 13 #define IP_MTU 14 +#define IP_FREEBIND 15 /* BSD compatibility */ #define IP_RECVRETOPTS IP_RETOPTS diff --git a/include/linux/init.h b/include/linux/init.h index 6300d86da..6ef5b4c78 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -31,8 +31,9 @@ * static int init_variable __initdata = 0; * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; * - * For initialized data not at file scope, i.e. within a function, - * you should use __initlocaldata instead, due to a bug in GCC 2.7. + * Don't forget to initialize data not at file scope, i.e. within a function, + * as gcc otherwise puts the data into the bss section and not into the init + * section. */ #ifndef MODULE @@ -100,8 +101,6 @@ extern struct kernel_param __setup_start, __setup_end; #define __FINIT #define __INITDATA -/* Not sure what version aliases were introduced in, but certainly in 2.91.66. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91) /* These macros create a dummy inline: gcc 2.9x does not count alias as usage, hence the `unused function' warning when __init functions are declared static. We use the dummy __*_module_inline functions @@ -117,21 +116,11 @@ typedef void (*__cleanup_module_func_t)(void); void cleanup_module(void) __attribute__((alias(#x))); \ extern inline __cleanup_module_func_t __cleanup_module_inline(void) \ { return x; } -#else -#define module_init(x) int init_module(void) { return x(); } -#define module_exit(x) void cleanup_module(void) { x(); } -#endif #define __setup(str,func) /* nothing */ #endif -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) -#define __initlocaldata __initdata -#else -#define __initlocaldata -#endif - #ifdef CONFIG_HOTPLUG #define __devinit #define __devinitdata diff --git a/include/linux/isapnp.h b/include/linux/isapnp.h index 0985c29fb..f44001df9 100644 --- a/include/linux/isapnp.h +++ b/include/linux/isapnp.h @@ -132,17 +132,33 @@ struct isapnp_resources { #define ISAPNP_CARD_DEVS 8 #define ISAPNP_CARD_ID(_va, _vb, _vc, _device) \ - vendor: ISAPNP_VENDOR(_va, _vb, _vc), device: ISAPNP_DEVICE(_device) + card_vendor: ISAPNP_VENDOR(_va, _vb, _vc), card_device: ISAPNP_DEVICE(_device) #define ISAPNP_CARD_END \ - vendor: 0, device: 0 + card_vendor: 0, card_device: 0 #define ISAPNP_DEVICE_ID(_va, _vb, _vc, _function) \ { vendor: ISAPNP_VENDOR(_va, _vb, _vc), function: ISAPNP_FUNCTION(_function) } +/* export used IDs outside module */ +#define ISAPNP_CARD_TABLE(name) \ + MODULE_GENERIC_TABLE(isapnp_card, name) + struct isapnp_card_id { - unsigned short vendor, device; + unsigned long driver_data; /* data private to the driver */ + unsigned short card_vendor, card_device; struct { unsigned short vendor, function; } devs[ISAPNP_CARD_DEVS]; /* logical devices */ +}; + +#define ISAPNP_DEVICE_SINGLE(_cva, _cvb, _cvc, _cdevice, _dva, _dvb, _dvc, _dfunction) \ + card_vendor: ISAPNP_VENDOR(_cva, _cvb, _cvc), card_device: ISAPNP_DEVICE(_cdevice), \ + vendor: ISAPNP_VENDOR(_dva, _dvb, _dvc), function: ISAPNP_FUNCTION(_dfunction) +#define ISAPNP_DEVICE_SINGLE_END \ + card_vendor: 0, card_device: 0 + +struct isapnp_device_id { + unsigned short card_vendor, card_device; + unsigned short vendor, function; unsigned long driver_data; /* data private to the driver */ }; @@ -179,10 +195,14 @@ struct pci_dev *isapnp_find_dev(struct pci_bus *card, int isapnp_probe_cards(const struct isapnp_card_id *ids, int (*probe)(struct pci_bus *card, const struct isapnp_card_id *id)); +int isapnp_probe_devs(const struct isapnp_device_id *ids, + int (*probe)(struct pci_dev *dev, + const struct isapnp_device_id *id)); /* misc */ void isapnp_resource_change(struct resource *resource, unsigned long start, unsigned long size); +int isapnp_activate_dev(struct pci_dev *dev, const char *name); /* init/main.c */ int isapnp_init(void); @@ -221,9 +241,13 @@ extern inline struct pci_dev *isapnp_find_dev(struct pci_bus *card, extern inline int isapnp_probe_cards(const struct isapnp_card_id *ids, int (*probe)(struct pci_bus *card, const struct isapnp_card_id *id)) { return -ENODEV; } +extern inline int isapnp_probe_devs(const struct isapnp_device_id *ids, + int (*probe)(struct pci_dev *dev, + const struct isapnp_device_id *id)) { return -ENODEV; } extern inline void isapnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) { ; } +extern inline int isapnp_activate_dev(struct pci_dev *dev, const char *name) { return -ENODEV; } #endif /* CONFIG_ISAPNP */ diff --git a/include/linux/linkage.h b/include/linux/linkage.h index aaf6edf02..23b9ae463 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -9,7 +9,7 @@ #define CPP_ASMLINKAGE #endif -#if defined __i386__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 7) +#if defined __i386__ #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) #elif defined __ia64__ #define asmlinkage CPP_ASMLINKAGE __attribute__((syscall_linkage)) diff --git a/include/linux/mm.h b/include/linux/mm.h index 69d4d2490..59355eb8a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -95,6 +95,7 @@ struct vm_area_struct { #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */ #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */ +#define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */ #define VM_STACK_FLAGS 0x00000177 @@ -380,7 +381,7 @@ extern void FASTCALL(free_pages(unsigned long addr, unsigned long order)); #define free_page(addr) free_pages((addr),0) extern void show_free_areas(void); -extern void show_free_areas_node(int nid); +extern void show_free_areas_node(pg_data_t *pgdat); extern void clear_page_tables(struct mm_struct *, unsigned long, int); @@ -527,11 +528,6 @@ extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned lon #define pgcache_under_min() (atomic_read(&page_cache_size) * 100 < \ page_cache.min_percent * num_physpages) -#define vmlist_access_lock(mm) spin_lock(&mm->page_table_lock) -#define vmlist_access_unlock(mm) spin_unlock(&mm->page_table_lock) -#define vmlist_modify_lock(mm) vmlist_access_lock(mm) -#define vmlist_modify_unlock(mm) vmlist_access_unlock(mm) - #endif /* __KERNEL__ */ #endif diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 4a8280d7d..c14decdfc 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -101,15 +101,15 @@ extern pg_data_t *pgdat_list; * prototypes for the discontig memory code. */ struct page; -extern void show_free_areas_core(int); +extern void show_free_areas_core(pg_data_t *pgdat); extern void free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap, unsigned long *zones_size, unsigned long paddr, unsigned long *zholes_size, struct page *pmap); -#ifndef CONFIG_DISCONTIGMEM - extern pg_data_t contig_page_data; +#ifndef CONFIG_DISCONTIGMEM + #define NODE_DATA(nid) (&contig_page_data) #define NODE_MEM_MAP(nid) mem_map diff --git a/include/linux/module.h b/include/linux/module.h index 5a52811a8..26f383a63 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -206,9 +206,16 @@ __attribute__((section(".modinfo"))) = \ * The following is a list of known device types (arg 1), * and the C types which are to be passed as arg 2. * pci - struct pci_device_id - List of PCI ids supported by this module + * isapnp - struct isapnp_device_id - List of ISA PnP ids supported by this module + * usb - struct usb_device_id - List of USB ids supported by this module */ -#define MODULE_DEVICE_TABLE(type,name) \ -const struct type##_device_id * __module_##type##_device_table = name +#define MODULE_GENERIC_TABLE(gtype,name) \ +static const unsigned long __module_##gtype##_size \ + __attribute__ ((unused)) = sizeof(struct gtype##_id); \ +static const struct gtype##_id * __module_##gtype##_table \ + __attribute__ ((unused)) = name +#define MODULE_DEVICE_TABLE(type,name) \ + MODULE_GENERIC_TABLE(type##_device,name) /* not put to .modinfo section to avoid section type conflicts */ /* The attributes of a section are set the first time the section is @@ -239,6 +246,7 @@ static const char __module_using_checksums[] __attribute__((section(".modinfo")) #define MODULE_SUPPORTED_DEVICE(name) #define MODULE_PARM(var,type) #define MODULE_PARM_DESC(var,desc) +#define MODULE_GENERIC_TABLE(gtype,name) #define MODULE_DEVICE_TABLE(type,name) #ifndef __GENKSYMS__ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 95c0e130b..32677edae 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -39,6 +39,8 @@ #include <net/profile.h> #endif +struct divert_blk; + #define NET_XMIT_SUCCESS 0 #define NET_XMIT_DROP 1 /* skb dropped */ #define NET_XMIT_CN 2 /* congestion notification */ @@ -47,6 +49,14 @@ (TC use only - dev_queue_xmit returns this as NET_XMIT_SUCCESS) */ +/* Backlog congestion levels */ +#define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ +#define NET_RX_CN_LOW 1 /* storm alert, just in case */ +#define NET_RX_CN_MOD 2 /* Storm on its way! */ +#define NET_RX_CN_HIGH 5 /* The storm is here */ +#define NET_RX_DROP -1 /* packet dropped */ +#define NET_RX_BAD -2 /* packet dropped due to kernel error */ + #define net_xmit_errno(e) ((e) != NET_XMIT_CN ? -ENOBUFS : 0) #endif @@ -382,6 +392,10 @@ struct net_device rwlock_t fastpath_lock; struct dst_entry *fastpath[NETDEV_FASTROUTE_HMASK+1]; #endif +#ifdef CONFIG_NET_DIVERT + /* this will get initialized at each interface type init routine */ + struct divert_blk *divert; +#endif /* CONFIG_NET_DIVERT */ }; @@ -440,6 +454,8 @@ static inline int unregister_gifconf(unsigned int family) struct softnet_data { int throttle; + int cng_level; + int avg_blog; struct sk_buff_head input_pkt_queue; struct net_device *output_queue; struct sk_buff *completion_queue; @@ -526,7 +542,7 @@ static inline void dev_kfree_skb_any(struct sk_buff *skb) extern void net_call_rx_atomic(void (*fn)(void)); #define HAVE_NETIF_RX 1 -extern void netif_rx(struct sk_buff *skb); +extern int netif_rx(struct sk_buff *skb); extern int dev_ioctl(unsigned int cmd, void *); extern int dev_change_flags(struct net_device *, unsigned); extern void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev); @@ -628,6 +644,7 @@ extern int netdev_register_fc(struct net_device *dev, void (*stimul)(struct net extern void netdev_unregister_fc(int bit); extern int netdev_max_backlog; extern unsigned long netdev_fc_xoff; +extern atomic_t netdev_dropping; extern int netdev_set_master(struct net_device *dev, struct net_device *master); #ifdef CONFIG_NET_FASTROUTE extern int netdev_fastroute; diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 59075b070..41e7d92cc 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -151,8 +151,6 @@ extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, int (*done)(struct netlink_callback*)); -extern void netlink_proto_init(struct net_proto *pro); - #endif /* __KERNEL__ */ #endif /* __LINUX_NETLINK_H */ diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 89054f8fe..9d2082f44 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -67,10 +67,6 @@ extern inline unsigned long _page_hashfn(struct address_space * mapping, unsigne #define page_hash(mapping,index) (page_hash_table+_page_hashfn(mapping,index)) -extern struct page * __find_get_page (struct address_space *mapping, - unsigned long index, struct page **hash); -#define find_get_page(mapping, index) \ - __find_get_page(mapping, index, page_hash(mapping, index)) extern struct page * __find_lock_page (struct address_space * mapping, unsigned long index, struct page **hash); extern void lock_page(struct page *page); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index d045308eb..994e0889f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -415,6 +415,12 @@ #define PCI_DEVICE_ID_WINBOND2_89C940 0x0940 #define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a +#define PCI_VENDOR_ID_EFAR 0x1055 +#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130 +#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 +#define PCI_DEVICE_ID_EFAR_SLC90E66_2 0x9462 +#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463 + #define PCI_VENDOR_ID_MOTOROLA 0x1057 #define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507 #define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001 @@ -467,6 +473,14 @@ #define PCI_DEVICE_ID_APPLE_HYDRA 0x000e #define PCI_DEVICE_ID_APPLE_UNINORTH 0x0020 +#define PCI_VENDOR_ID_YAMAHA 0x1073 +#define PCI_DEVICE_ID_YAMAHA_724 0x0004 +#define PCI_DEVICE_ID_YAMAHA_724F 0x000d +#define PCI_DEVICE_ID_YAMAHA_740 0x000a +#define PCI_DEVICE_ID_YAMAHA_740C 0x000c +#define PCI_DEVICE_ID_YAMAHA_744 0x0010 +#define PCI_DEVICE_ID_YAMAHA_754 0x0012 + #define PCI_VENDOR_ID_NEXGEN 0x1074 #define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78 @@ -825,6 +839,9 @@ #define PCI_DEVICE_ID_SERVERWORKS_CIOB30 0x0010 #define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011 #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 #define PCI_VENDOR_ID_SBE 0x1176 #define PCI_DEVICE_ID_SBE_WANXL100 0x0301 diff --git a/include/linux/sched.h b/include/linux/sched.h index bb4537f24..9385c9ea8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -254,7 +254,7 @@ struct user_struct { /* Hash table maintenance information */ struct user_struct *next, **pprev; - unsigned int uid; + uid_t uid; }; #define get_current_user() ({ \ @@ -410,6 +410,7 @@ struct task_struct { #define PT_PTRACED 0x00000001 #define PT_TRACESYS 0x00000002 #define PT_DTRACE 0x00000004 /* delayed trace (used on m68k, i386) */ +#define PT_TRACESYSGOOD 0x00000008 /* * Limit the stack by to some sane default: root can always diff --git a/include/linux/sockios.h b/include/linux/sockios.h index fe38a2d40..e9fd9e275 100644 --- a/include/linux/sockios.h +++ b/include/linux/sockios.h @@ -72,6 +72,9 @@ #define SIOCGIFTXQLEN 0x8942 /* Get the tx queue length */ #define SIOCSIFTXQLEN 0x8943 /* Set the tx queue length */ +#define SIOCGIFDIVERT 0x8944 /* Frame diversion support */ +#define SIOCSIFDIVERT 0x8945 /* Set frame diversion options */ + /* ARP cache control calls. */ /* 0x8950 - 0x8952 * obsolete calls, don't re-use */ diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 242be9730..d66474b60 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -43,6 +43,7 @@ struct rpc_cred { * Client authentication handle */ #define RPC_CREDCACHE_NR 8 +#define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1) struct rpc_auth { struct rpc_cred * au_credcache[RPC_CREDCACHE_NR]; unsigned long au_expire; /* cache expiry interval */ diff --git a/include/linux/swap.h b/include/linux/swap.h index 05317e725..87364f298 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -126,6 +126,10 @@ extern struct page * lookup_swap_cache(swp_entry_t); extern struct page * read_swap_cache_async(swp_entry_t, int); #define read_swap_cache(entry) read_swap_cache_async(entry, 1); +/* linux/mm/oom_kill.c */ +extern int out_of_memory(void); +extern void oom_kill(void); + /* * Make these inline later once they are working properly. */ diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index c15bd0e55..b5155a2b6 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -187,7 +187,11 @@ enum NET_CORE_MSG_BURST=9, NET_CORE_OPTMEM_MAX=10, NET_CORE_HOT_LIST_LENGTH=11, - NET_CORE_DIVERT_VERSION=12 + NET_CORE_DIVERT_VERSION=12, + NET_CORE_NO_CONG_THRESH=13, + NET_CORE_NO_CONG=14, + NET_CORE_LO_CONG=15, + NET_CORE_MOD_CONG=16 }; /* /proc/sys/net/ethernet */ @@ -270,6 +274,7 @@ enum NET_TCP_RMEM=85, NET_TCP_APP_WIN=86, NET_TCP_ADV_WIN_SCALE=87, + NET_IPV4_NONLOCAL_BIND=88, }; enum { @@ -631,16 +636,6 @@ extern ctl_handler sysctl_string; extern ctl_handler sysctl_intvec; extern ctl_handler sysctl_jiffies; -extern int do_string ( - void *oldval, size_t *oldlenp, void *newval, size_t newlen, - int rdwr, char *data, size_t max); -extern int do_int ( - void *oldval, size_t *oldlenp, void *newval, size_t newlen, - int rdwr, int *data); -extern int do_struct ( - void *oldval, size_t *oldlenp, void *newval, size_t newlen, - int rdwr, void *data, size_t len); - /* * Register a set of sysctl names by calling register_sysctl_table diff --git a/include/linux/usb.h b/include/linux/usb.h index bc8d32db4..428866672 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -303,6 +303,50 @@ struct usb_string_descriptor { struct usb_device; +/* + * Device table entry for "new style" table-driven USB drivers. + * User mode code can read these tables to choose which modules to load. + * Declare the table as __devinitdata, and as a MODULE_DEVICE_TABLE. + * + * With a device table provide bind() instead of probe(). Then the + * third bind() parameter will point to a matching entry from this + * table. (Null value reserved.) + * + * Terminate the driver's table with an all-zeroes entry. + * Init the fields you care about; zeroes are not used in comparisons. + */ +struct usb_device_id { + /* + * vendor/product codes are checked, if vendor is nonzero + * Range is for device revision (bcdDevice), inclusive; + * zero values here mean range isn't considered + */ + __u16 idVendor; + __u16 idProduct; + __u16 bcdDevice_lo, bcdDevice_hi; + + /* + * if device class != 0, these can be match criteria; + * but only if this bDeviceClass value is nonzero + */ + __u8 bDeviceClass; + __u8 bDeviceSubClass; + __u8 bDeviceProtocol; + + /* + * if interface class != 0, these can be match criteria; + * but only if this bInterfaceClass value is nonzero + */ + __u8 bInterfaceClass; + __u8 bInterfaceSubClass; + __u8 bInterfaceProtocol; + + /* + * for driver's use; not involved in driver matching. + */ + unsigned long driver_info; +}; + struct usb_driver { const char *name; @@ -316,27 +360,25 @@ struct usb_driver { struct semaphore serialize; + /* ioctl -- userspace apps can talk to drivers through usbdevfs */ int (*ioctl)(struct usb_device *dev, unsigned int code, void *buf); -}; - -/* - * Pointer to a device endpoint interrupt function -greg - * Parameters: - * int status - This needs to be defined. Right now each HCD - * passes different transfer status bits back. Don't use it - * until we come up with a common meaning. - * void *buffer - This is a pointer to the data used in this - * USB transfer. - * int length - This is the number of bytes transferred in or out - * of the buffer by this transfer. (-1 = unknown/unsupported) - * void *dev_id - This is a user defined pointer set when the IRQ - * is requested that is passed back. - * - * Special Cases: - * if (status == USB_ST_REMOVED), don't trust buffer or len. - */ -typedef int (*usb_device_irq)(int, void *, int, void *); + /* support for "new-style" USB hotplugging + * binding policy can be driven from user mode too + */ + const struct usb_device_id *id_table; + void *(*bind)( + struct usb_device *dev, /* the device */ + unsigned intf, /* what interface */ + const struct usb_device_id *id /* from id_table */ + ); + + /* suspend before the bus suspends; + * disconnect or resume when the bus resumes */ + // void (*suspend)(struct usb_device *dev); + // void (*resume)(struct usb_device *dev); +}; + /*----------------------------------------------------------------------------* * New USB Structures * *----------------------------------------------------------------------------*/ @@ -459,22 +501,17 @@ int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, devr int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout); /*-------------------------------------------------------------------* - * COMPATIBILITY STUFF * + * SYNCHRONOUS CALL SUPPORT * *-------------------------------------------------------------------*/ + typedef struct { wait_queue_head_t *wakeup; - usb_device_irq handler; void* stuff; /* more to follow */ } api_wrapper_data; -struct irq_wrapper_data { - void *context; - usb_device_irq handler; -}; - /* -------------------------------------------------------------------------- */ struct usb_operations { diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 66451acdb..80feae4c7 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -35,7 +35,6 @@ void (*kd_mksound)(unsigned int hz, unsigned int ticks); /* console.c */ struct console_font_op; -struct consw; int vc_allocate(unsigned int console); int vc_cons_allocated(unsigned int console); diff --git a/include/linux/wrapper.h b/include/linux/wrapper.h index edf8ef153..36dd17fe4 100644 --- a/include/linux/wrapper.h +++ b/include/linux/wrapper.h @@ -1,36 +1,14 @@ #ifndef _WRAPPER_H_ #define _WRAPPER_H_ -#define wait_handle struct wait_queue -#define file_handle struct file -#define inode_handle struct inode -#define select_table_handle select_table -#define vm_area_handle struct vm_area_struct -#define connect_wrapper(x) 0 -#define current_got_fatal_signal() (signal_pending(current)) -#define current_set_timeout(val) current->timeout = val +#define vma_set_inode(v,i) ((v)->vm_inode = (i)) +#define vma_get_flags(v) ((v)->vm_flags) +#define vma_get_pgoff(v) ((v)->vm_pgoff) +#define vma_get_start(v) ((v)->vm_start) +#define vma_get_end(v) ((v)->vm_end) +#define vma_get_page_prot(v) ((v)->vm_page_prot) -#define module_interruptible_sleep_on interruptible_sleep_on -#define module_wake_up wake_up -#define module_select_wait select_wait -#define module_register_chrdev register_chrdev -#define module_unregister_chrdev unregister_chrdev -#define module_register_blkdev register_blkdev -#define module_unregister_blkdev unregister_blkdev +#define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags)) +#define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags)) -#define inode_get_rdev(i) i->i_rdev - -#define file_get_flags(f) f->f_flags - -#define vma_set_inode(v,i) v->vm_inode = i -#define vma_get_flags(v) v->vm_flags -#define vma_get_pgoff(v) v->vm_pgoff -#define vma_get_start(v) v->vm_start -#define vma_get_end(v) v->vm_end -#define vma_get_page_prot(v) v->vm_page_prot - -#define mem_map_reserve(p) set_bit(PG_reserved, &p->flags) -#define mem_map_unreserve(p) clear_bit(PG_reserved, &p->flags) -#define mem_map_inc_count(p) atomic_inc(&(p->count)) -#define mem_map_dec_count(p) atomic_dec(&(p->count)) -#endif +#endif /* _WRAPPER_H_ */ diff --git a/include/linux/zorro.h b/include/linux/zorro.h index 9e7c07889..aabaea588 100644 --- a/include/linux/zorro.h +++ b/include/linux/zorro.h @@ -1,7 +1,7 @@ /* * linux/zorro.h -- Amiga AutoConfig (Zorro) Bus Definitions * - * Copyright (C) 1995-2000 Geert Uytterhoeven + * Copyright (C) 1995--2000 Geert Uytterhoeven * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive @@ -14,8 +14,6 @@ #ifndef __ASSEMBLY__ /* - * Known Zorro Boards - * * Each Zorro board has a 32-bit ID of the form * * mmmmmmmmmmmmmmmmppppppppeeeeeeee @@ -41,551 +39,8 @@ typedef __u32 zorro_id; #define ZORRO_WILDCARD (0xffffffff) /* not official */ - -#define ZORRO_MANUF_PACIFIC_PERIPHERALS 0x00D3 -#define ZORRO_PROD_PACIFIC_PERIPHERALS_SE_2000_A500 ZORRO_ID(PACIFIC_PERIPHERALS, 0x00, 0) -#define ZORRO_PROD_PACIFIC_PERIPHERALS_SCSI ZORRO_ID(PACIFIC_PERIPHERALS, 0x0A, 0) - -#define ZORRO_MANUF_MACROSYSTEMS_USA_2 0x0100 -#define ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE ZORRO_ID(MACROSYSTEMS_USA_2, 0x13, 0) - -#define ZORRO_MANUF_KUPKE_1 0x00DD -#define ZORRO_PROD_KUPKE_GOLEM_RAM_BOX_2MB ZORRO_ID(KUPKE_1, 0x00, 0) - -#define ZORRO_MANUF_MEMPHIS 0x0100 -#define ZORRO_PROD_MEMPHIS_STORMBRINGER ZORRO_ID(MEMPHIS, 0x00, 0) - -#define ZORRO_MANUF_3_STATE 0x0200 -#define ZORRO_PROD_3_STATE_MEGAMIX_2000 ZORRO_ID(3_STATE, 0x02, 0) - -#define ZORRO_MANUF_COMMODORE_BRAUNSCHWEIG 0x0201 -#define ZORRO_PROD_CBM_A2088_A2286 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x01, 0) -#define ZORRO_PROD_CBM_A2286 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x02, 0) -#define ZORRO_PROD_CBM_A4091_1 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x54, 0) -#define ZORRO_PROD_CBM_A2386SX_1 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x67, 0) - -#define ZORRO_MANUF_COMMODORE_WEST_CHESTER_1 0x0202 -#define ZORRO_PROD_CBM_A2090A ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x01, 0) -#define ZORRO_PROD_CBM_A590_A2091_1 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x02, 0) -#define ZORRO_PROD_CBM_A590_A2091_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x03, 0) -#define ZORRO_PROD_CBM_A2090B ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x04, 0) -#define ZORRO_PROD_CBM_A2060 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x09, 0) -#define ZORRO_PROD_CBM_A590_A2052_A2058_A2091 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x0A, 0) -#define ZORRO_PROD_CBM_A560_RAM ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x20, 0) -#define ZORRO_PROD_CBM_A2232_PROTOTYPE ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x45, 0) -#define ZORRO_PROD_CBM_A2232 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x46, 0) -#define ZORRO_PROD_CBM_A2620 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x50, 0) -#define ZORRO_PROD_CBM_A2630 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x51, 0) -#define ZORRO_PROD_CBM_A4091_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x54, 0) -#define ZORRO_PROD_CBM_A2065_1 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x5A, 0) -#define ZORRO_PROD_CBM_ROMULATOR ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x60, 0) -#define ZORRO_PROD_CBM_A3000_TEST_FIXTURE ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x61, 0) -#define ZORRO_PROD_CBM_A2386SX_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x67, 0) -#define ZORRO_PROD_CBM_A2065_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x70, 0) - -#define ZORRO_MANUF_COMMODORE_WEST_CHESTER_2 0x0203 -#define ZORRO_PROD_CBM_A2090A_CM ZORRO_ID(COMMODORE_WEST_CHESTER_2, 0x03, 0) - -#define ZORRO_MANUF_PROGRESSIVE_PERIPHERALS_AND_SYSTEMS_2 0x02F4 -#define ZORRO_PROD_PPS_EXP8000 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS_2, 0x02, 0) - -#define ZORRO_MANUF_KOLFF_COMPUTER_SUPPLIES 0x02FF -#define ZORRO_PROD_KCS_POWER_PC_BOARD ZORRO_ID(KOLFF_COMPUTER_SUPPLIES, 0x00, 0) - -#define ZORRO_MANUF_CARDCO_1 0x03EC -#define ZORRO_PROD_CARDCO_KRONOS_2000_1 ZORRO_ID(CARDCO_1, 0x04, 0) -#define ZORRO_PROD_CARDCO_A1000_1 ZORRO_ID(CARDCO_1, 0x0C, 0) -#define ZORRO_PROD_CARDCO_ESCORT ZORRO_ID(CARDCO_1, 0x0E, 0) -#define ZORRO_PROD_CARDCO_A2410 ZORRO_ID(CARDCO_1, 0xF5, 0) - -#define ZORRO_MANUF_A_SQUARED 0x03ED -#define ZORRO_PROD_A_SQUARED_LIVE_2000 ZORRO_ID(A_SQUARED, 0x01, 0) - -#define ZORRO_MANUF_COMSPEC_COMMUNICATIONS 0x03EE -#define ZORRO_PROD_COMSPEC_COMMUNICATIONS_AX2000 ZORRO_ID(COMSPEC_COMMUNICATIONS, 0x01, 0) - -#define ZORRO_MANUF_ANAKIN_RESEARCH 0x03F1 -#define ZORRO_PROD_ANAKIN_RESEARCH_EASYL ZORRO_ID(ANAKIN_RESEARCH, 0x01, 0) - -#define ZORRO_MANUF_MICROBOTICS 0x03F2 -#define ZORRO_PROD_MICROBOTICS_STARBOARD_II ZORRO_ID(MICROBOTICS, 0x00, 0) -#define ZORRO_PROD_MICROBOTICS_STARDRIVE ZORRO_ID(MICROBOTICS, 0x02, 0) -#define ZORRO_PROD_MICROBOTICS_8_UP_A ZORRO_ID(MICROBOTICS, 0x03, 0) -#define ZORRO_PROD_MICROBOTICS_8_UP_Z ZORRO_ID(MICROBOTICS, 0x04, 0) -#define ZORRO_PROD_MICROBOTICS_DELTA_RAM ZORRO_ID(MICROBOTICS, 0x20, 0) -#define ZORRO_PROD_MICROBOTICS_8_STAR_RAM ZORRO_ID(MICROBOTICS, 0x40, 0) -#define ZORRO_PROD_MICROBOTICS_8_STAR ZORRO_ID(MICROBOTICS, 0x41, 0) -#define ZORRO_PROD_MICROBOTICS_VXL_RAM_32 ZORRO_ID(MICROBOTICS, 0x44, 0) -#define ZORRO_PROD_MICROBOTICS_VXL_68030 ZORRO_ID(MICROBOTICS, 0x45, 0) -#define ZORRO_PROD_MICROBOTICS_DELTA ZORRO_ID(MICROBOTICS, 0x60, 0) -#define ZORRO_PROD_MICROBOTICS_MBX_1200_1200Z_RAM ZORRO_ID(MICROBOTICS, 0x81, 0) -#define ZORRO_PROD_MICROBOTICS_HARDFRAME_2000_1 ZORRO_ID(MICROBOTICS, 0x96, 0) -#define ZORRO_PROD_MICROBOTICS_HARDFRAME_2000_2 ZORRO_ID(MICROBOTICS, 0x9E, 0) -#define ZORRO_PROD_MICROBOTICS_MBX_1200_1200Z ZORRO_ID(MICROBOTICS, 0xC1, 0) - -#define ZORRO_MANUF_ACCESS_ASSOCIATES_ALEGRA 0x03F4 - -#define ZORRO_MANUF_EXPANSION_TECHNOLOGIES 0x03F6 - -#define ZORRO_MANUF_ASDG 0x03FF -#define ZORRO_PROD_ASDG_MEMORY_1 ZORRO_ID(ASDG, 0x01, 0) -#define ZORRO_PROD_ASDG_MEMORY_2 ZORRO_ID(ASDG, 0x02, 0) -#define ZORRO_PROD_ASDG_EB920_LAN_ROVER ZORRO_ID(ASDG, 0xFE, 0) -#define ZORRO_PROD_ASDG_GPIB_DUALIEEE488_TWIN_X ZORRO_ID(ASDG, 0xFF, 0) - -#define ZORRO_MANUF_IMTRONICS_1 0x0404 -#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_1 ZORRO_ID(IMTRONICS_1, 0x39, 0) -#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_2 ZORRO_ID(IMTRONICS_1, 0x57, 0) - -#define ZORRO_MANUF_CBM_UNIVERSITY_OF_LOWELL 0x0406 -#define ZORRO_PROD_CBM_A2410 ZORRO_ID(CBM_UNIVERSITY_OF_LOWELL, 0x00, 0) - -#define ZORRO_MANUF_AMERISTAR 0x041D -#define ZORRO_PROD_AMERISTAR_A2065 ZORRO_ID(AMERISTAR, 0x01, 0) -#define ZORRO_PROD_AMERISTAR_A560 ZORRO_ID(AMERISTAR, 0x09, 0) -#define ZORRO_PROD_AMERISTAR_A4066 ZORRO_ID(AMERISTAR, 0x0A, 0) - -#define ZORRO_MANUF_SUPRA 0x0420 -#define ZORRO_PROD_SUPRA_SUPRADRIVE_4x4 ZORRO_ID(SUPRA, 0x01, 0) -#define ZORRO_PROD_SUPRA_1000_RAM ZORRO_ID(SUPRA, 0x02, 0) -#define ZORRO_PROD_SUPRA_2000_DMA ZORRO_ID(SUPRA, 0x03, 0) -#define ZORRO_PROD_SUPRA_500 ZORRO_ID(SUPRA, 0x05, 0) -#define ZORRO_PROD_SUPRA_500_SCSI ZORRO_ID(SUPRA, 0x08, 0) -#define ZORRO_PROD_SUPRA_500XP_2000_RAM ZORRO_ID(SUPRA, 0x09, 0) -#define ZORRO_PROD_SUPRA_500RX_2000_RAM ZORRO_ID(SUPRA, 0x0A, 0) -#define ZORRO_PROD_SUPRA_2400ZI ZORRO_ID(SUPRA, 0x0B, 0) -#define ZORRO_PROD_SUPRA_500XP_SUPRADRIVE_WORDSYNC ZORRO_ID(SUPRA, 0x0C, 0) -#define ZORRO_PROD_SUPRA_SUPRADRIVE_WORDSYNC_II ZORRO_ID(SUPRA, 0x0D, 0) -#define ZORRO_PROD_SUPRA_2400ZIPLUS ZORRO_ID(SUPRA, 0x10, 0) - -#define ZORRO_MANUF_COMPUTER_SYSTEMS_ASSOCIATES 0x0422 -#define ZORRO_PROD_CSA_MAGNUM ZORRO_ID(COMPUTER_SYSTEMS_ASSOCIATES, 0x11, 0) -#define ZORRO_PROD_CSA_12_GAUGE ZORRO_ID(COMPUTER_SYSTEMS_ASSOCIATES, 0x15, 0) - -#define ZORRO_MANUF_MARC_MICHAEL_GROTH 0x0439 - -#define ZORRO_MANUF_M_TECH 0x0502 -#define ZORRO_PROD_MTEC_AT500_1 ZORRO_ID(M_TECH, 0x03, 0) - -#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_1 0x06E1 -#define ZORRO_PROD_GVP_IMPACT_SERIES_I ZORRO_ID(GREAT_VALLEY_PRODUCTS_1, 0x08, 0) - -#define ZORRO_MANUF_BYTEBOX 0x07DA -#define ZORRO_PROD_BYTEBOX_A500 ZORRO_ID(BYTEBOX, 0x00, 0) - -#define ZORRO_MANUF_DKB_POWER_COMPUTING 0x07DC -#define ZORRO_PROD_DKB_POWER_COMPUTING_SECUREKEY ZORRO_ID(DKB_POWER_COMPUTING, 0x09, 0) -#define ZORRO_PROD_DKB_POWER_COMPUTING_DKM_3128 ZORRO_ID(DKB_POWER_COMPUTING, 0x0E, 0) -#define ZORRO_PROD_DKB_POWER_COMPUTING_RAPID_FIRE ZORRO_ID(DKB_POWER_COMPUTING, 0x0F, 0) -#define ZORRO_PROD_DKB_POWER_COMPUTING_DKM_1202 ZORRO_ID(DKB_POWER_COMPUTING, 0x10, 0) -#define ZORRO_PROD_DKB_POWER_COMPUTING_COBRA_VIPER_II_68EC030 ZORRO_ID(DKB_POWER_COMPUTING, 0x12, 0) -#define ZORRO_PROD_DKB_POWER_COMPUTING_WILDFIRE_060_1 ZORRO_ID(DKB_POWER_COMPUTING, 0x17, 0) -#define ZORRO_PROD_DKB_POWER_COMPUTING_WILDFIRE_060_2 ZORRO_ID(DKB_POWER_COMPUTING, 0xFF, 0) - -#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_2 0x07E1 -#define ZORRO_PROD_GVP_IMPACT_SERIES_I_4K ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x01, 0) -#define ZORRO_PROD_GVP_IMPACT_SERIES_I_16K_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x02, 0) -#define ZORRO_PROD_GVP_IMPACT_SERIES_I_16K_3 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x03, 0) -#define ZORRO_PROD_GVP_IMPACT_3001_IDE_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x08, 0) -#define ZORRO_PROD_GVP_IMPACT_3001_RAM ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x09, 0) -#define ZORRO_PROD_GVP_IMPACT_SERIES_II_RAM_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0A, 0) -#define ZORRO_PROD_GVP_EPC_BASE ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0) -#define ZORRO_PROD_GVP_GFORCE_040_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x20) -#define ZORRO_PROD_GVP_GFORCE_040_SCSI_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x30) -#define ZORRO_PROD_GVP_A1291 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x40) -#define ZORRO_PROD_GVP_COMBO_030_R4 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x60) -#define ZORRO_PROD_GVP_COMBO_030_R4_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x70) -#define ZORRO_PROD_GVP_PHONEPAK ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x78) -#define ZORRO_PROD_GVP_IO_EXTENDER ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x98) -#define ZORRO_PROD_GVP_GFORCE_030 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xa0) -#define ZORRO_PROD_GVP_GFORCE_030_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xb0) -#define ZORRO_PROD_GVP_A530 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xc0) -#define ZORRO_PROD_GVP_A530_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xd0) -#define ZORRO_PROD_GVP_COMBO_030_R3 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xe0) -#define ZORRO_PROD_GVP_COMBO_030_R3_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xf0) -#define ZORRO_PROD_GVP_SERIES_II ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xf8) -#define ZORRO_PROD_GVP_IMPACT_3001_IDE_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0D, 0) -/*#define ZORRO_PROD_GVP_A2000_030 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0D, 0)*/ -/*#define ZORRO_PROD_GVP_GFORCE_040_SCSI_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0D, 0)*/ -#define ZORRO_PROD_GVP_GFORCE_040_060 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x16, 0) -#define ZORRO_PROD_GVP_IMPACT_VISION_24 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x20, 0) -#define ZORRO_PROD_GVP_GFORCE_040_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0xFF, 0) - -#define ZORRO_MANUF_CALIFORNIA_ACCESS_SYNERGY 0x07E5 -#define ZORRO_PROD_CALIFORNIA_ACCESS_SYNERGY_MALIBU ZORRO_ID(CALIFORNIA_ACCESS_SYNERGY, 0x01, 0) - -#define ZORRO_MANUF_XETEC 0x07E6 -#define ZORRO_PROD_XETEC_FASTCARD ZORRO_ID(XETEC, 0x01, 0) -#define ZORRO_PROD_XETEC_FASTCARD_RAM ZORRO_ID(XETEC, 0x02, 0) -#define ZORRO_PROD_XETEC_FASTCARD_PLUS ZORRO_ID(XETEC, 0x03, 0) - -#define ZORRO_MANUF_PROGRESSIVE_PERIPHERALS_AND_SYSTEMS 0x07EA -#define ZORRO_PROD_PPS_MERCURY ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x00, 0) -#define ZORRO_PROD_PPS_A3000_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x01, 0) -#define ZORRO_PROD_PPS_A2000_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x69, 0) -#define ZORRO_PROD_PPS_ZEUS ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x96, 0) -#define ZORRO_PROD_PPS_A500_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0xBB, 0) - -#define ZORRO_MANUF_XEBEC 0x07EC - -#define ZORRO_MANUF_SPIRIT_TECHNOLOGY 0x07F2 -#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INSIDER_IN1000 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x01, 0) -#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INSIDER_IN500 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x02, 0) -#define ZORRO_PROD_SPIRIT_TECHNOLOGY_SIN500 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x03, 0) -#define ZORRO_PROD_SPIRIT_TECHNOLOGY_HDA_506 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x04, 0) -#define ZORRO_PROD_SPIRIT_TECHNOLOGY_AX_S ZORRO_ID(SPIRIT_TECHNOLOGY, 0x05, 0) -#define ZORRO_PROD_SPIRIT_TECHNOLOGY_OCTABYTE ZORRO_ID(SPIRIT_TECHNOLOGY, 0x06, 0) -#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INMATE ZORRO_ID(SPIRIT_TECHNOLOGY, 0x08, 0) - -#define ZORRO_MANUF_SPIRIT_TECHNOLOGY_2 0x07F3 - -#define ZORRO_MANUF_BSC_ALFADATA_1 0x07FE -#define ZORRO_PROD_BSC_ALF_3_1 ZORRO_ID(BSC_ALFADATA_1, 0x03, 0) - -#define ZORRO_MANUF_BSC_ALFADATA_2 0x0801 -#define ZORRO_PROD_BSC_ALF_2_1 ZORRO_ID(BSC_ALFADATA_2, 0x01, 0) -#define ZORRO_PROD_BSC_ALF_2_2 ZORRO_ID(BSC_ALFADATA_2, 0x02, 0) -#define ZORRO_PROD_BSC_ALF_3_2 ZORRO_ID(BSC_ALFADATA_2, 0x03, 0) - -#define ZORRO_MANUF_CARDCO_2 0x0802 -#define ZORRO_PROD_CARDCO_KRONOS_2000_2 ZORRO_ID(CARDCO_2, 0x04, 0) -#define ZORRO_PROD_CARDCO_A1000_2 ZORRO_ID(CARDCO_2, 0x0C, 0) - -#define ZORRO_MANUF_JOCHHEIM 0x0804 -#define ZORRO_PROD_JOCHHEIM_RAM ZORRO_ID(JOCHHEIM, 0x01, 0) - -#define ZORRO_MANUF_CHECKPOINT_TECHNOLOGIES 0x0807 -#define ZORRO_PROD_CHECKPOINT_TECHNOLOGIES_SERIAL_SOLUTION ZORRO_ID(CHECKPOINT_TECHNOLOGIES, 0x00, 0) - -#define ZORRO_MANUF_EDOTRONIK 0x0810 -#define ZORRO_PROD_EDOTRONIK_IEEE_488 ZORRO_ID(EDOTRONIK, 0x01, 0) -#define ZORRO_PROD_EDOTRONIK_8032 ZORRO_ID(EDOTRONIK, 0x02, 0) -#define ZORRO_PROD_EDOTRONIK_MULTISERIAL ZORRO_ID(EDOTRONIK, 0x03, 0) -#define ZORRO_PROD_EDOTRONIK_VIDEODIGITIZER ZORRO_ID(EDOTRONIK, 0x04, 0) -#define ZORRO_PROD_EDOTRONIK_PARALLEL_IO ZORRO_ID(EDOTRONIK, 0x05, 0) -#define ZORRO_PROD_EDOTRONIK_PIC_PROTOYPING ZORRO_ID(EDOTRONIK, 0x06, 0) -#define ZORRO_PROD_EDOTRONIK_ADC ZORRO_ID(EDOTRONIK, 0x07, 0) -#define ZORRO_PROD_EDOTRONIK_VME ZORRO_ID(EDOTRONIK, 0x08, 0) -#define ZORRO_PROD_EDOTRONIK_DSP96000 ZORRO_ID(EDOTRONIK, 0x09, 0) - -#define ZORRO_MANUF_NES_INC 0x0813 -#define ZORRO_PROD_NES_INC_RAM ZORRO_ID(NES_INC, 0x00, 0) - -#define ZORRO_MANUF_ICD 0x0817 -#define ZORRO_PROD_ICD_ADVANTAGE_2000_SCSI ZORRO_ID(ICD, 0x01, 0) -#define ZORRO_PROD_ICD_ADVANTAGE_IDE ZORRO_ID(ICD, 0x03, 0) -#define ZORRO_PROD_ICD_ADVANTAGE_2080_RAM ZORRO_ID(ICD, 0x04, 0) - -#define ZORRO_MANUF_KUPKE_2 0x0819 -#define ZORRO_PROD_KUPKE_OMTI ZORRO_ID(KUPKE_2, 0x01, 0) -#define ZORRO_PROD_KUPKE_SCSI_II ZORRO_ID(KUPKE_2, 0x02, 0) -#define ZORRO_PROD_KUPKE_GOLEM_BOX ZORRO_ID(KUPKE_2, 0x03, 0) -#define ZORRO_PROD_KUPKE_030_882 ZORRO_ID(KUPKE_2, 0x04, 0) -#define ZORRO_PROD_KUPKE_SCSI_AT ZORRO_ID(KUPKE_2, 0x05, 0) - -#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_3 0x081D -#define ZORRO_PROD_GVP_A2000_RAM8 ZORRO_ID(GREAT_VALLEY_PRODUCTS_3, 0x09, 0) -#define ZORRO_PROD_GVP_IMPACT_SERIES_II_RAM_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_3, 0x0A, 0) - -#define ZORRO_MANUF_INTERWORKS_NETWORK 0x081E - -#define ZORRO_MANUF_HARDITAL_SYNTHESIS 0x0820 -#define ZORRO_PROD_HARDITAL_SYNTHESIS_TQM_68030_68882 ZORRO_ID(HARDITAL_SYNTHESIS, 0x14, 0) - -#define ZORRO_MANUF_APPLIED_ENGINEERING 0x0828 -#define ZORRO_PROD_APPLIED_ENGINEERING_DL2000 ZORRO_ID(APPLIED_ENGINEERING, 0x10, 0) -#define ZORRO_PROD_APPLIED_ENGINEERING_RAM_WORKS ZORRO_ID(APPLIED_ENGINEERING, 0xE0, 0) - -#define ZORRO_MANUF_BSC_ALFADATA_3 0x082C -#define ZORRO_PROD_BSC_OKTAGON_2008 ZORRO_ID(BSC_ALFADATA_3, 0x05, 0) -#define ZORRO_PROD_BSC_TANDEM_AT_2008_508 ZORRO_ID(BSC_ALFADATA_3, 0x06, 0) -#define ZORRO_PROD_BSC_ALFA_RAM_1200 ZORRO_ID(BSC_ALFADATA_3, 0x07, 0) -#define ZORRO_PROD_BSC_OKTAGON_2008_RAM ZORRO_ID(BSC_ALFADATA_3, 0x08, 0) -#define ZORRO_PROD_BSC_MULTIFACE_I ZORRO_ID(BSC_ALFADATA_3, 0x10, 0) -#define ZORRO_PROD_BSC_MULTIFACE_II ZORRO_ID(BSC_ALFADATA_3, 0x11, 0) -#define ZORRO_PROD_BSC_MULTIFACE_III ZORRO_ID(BSC_ALFADATA_3, 0x12, 0) -#define ZORRO_PROD_BSC_FRAMEMASTER_II ZORRO_ID(BSC_ALFADATA_3, 0x20, 0) -#define ZORRO_PROD_BSC_GRAFFITI_RAM ZORRO_ID(BSC_ALFADATA_3, 0x21, 0) -#define ZORRO_PROD_BSC_GRAFFITI_REG ZORRO_ID(BSC_ALFADATA_3, 0x22, 0) -#define ZORRO_PROD_BSC_ISDN_MASTERCARD ZORRO_ID(BSC_ALFADATA_3, 0x40, 0) -#define ZORRO_PROD_BSC_ISDN_MASTERCARD_II ZORRO_ID(BSC_ALFADATA_3, 0x41, 0) - -#define ZORRO_MANUF_PHOENIX 0x0835 -#define ZORRO_PROD_PHOENIX_ST506 ZORRO_ID(PHOENIX, 0x21, 0) -#define ZORRO_PROD_PHOENIX_SCSI ZORRO_ID(PHOENIX, 0x22, 0) -#define ZORRO_PROD_PHOENIX_RAM ZORRO_ID(PHOENIX, 0xBE, 0) - -#define ZORRO_MANUF_ADVANCED_STORAGE_SYSTEMS 0x0836 -#define ZORRO_PROD_ADVANCED_STORAGE_SYSTEMS_NEXUS ZORRO_ID(ADVANCED_STORAGE_SYSTEMS, 0x01, 0) -#define ZORRO_PROD_ADVANCED_STORAGE_SYSTEMS_NEXUS_RAM ZORRO_ID(ADVANCED_STORAGE_SYSTEMS, 0x08, 0) - -#define ZORRO_MANUF_IMPULSE 0x0838 -#define ZORRO_PROD_IMPULSE_FIRECRACKER_24 ZORRO_ID(IMPULSE, 0x00, 0) - -#define ZORRO_MANUF_IVS 0x0840 -#define ZORRO_PROD_IVS_GRANDSLAM_PIC_2 ZORRO_ID(IVS, 0x02, 0) -#define ZORRO_PROD_IVS_GRANDSLAM_PIC_1 ZORRO_ID(IVS, 0x04, 0) -#define ZORRO_PROD_IVS_OVERDRIVE ZORRO_ID(IVS, 0x10, 0) -#define ZORRO_PROD_IVS_TRUMPCARD_CLASSIC ZORRO_ID(IVS, 0x30, 0) -#define ZORRO_PROD_IVS_TRUMPCARD_PRO_GRANDSLAM ZORRO_ID(IVS, 0x34, 0) -#define ZORRO_PROD_IVS_META_4 ZORRO_ID(IVS, 0x40, 0) -#define ZORRO_PROD_IVS_WAVETOOLS ZORRO_ID(IVS, 0xBF, 0) -#define ZORRO_PROD_IVS_VECTOR_1 ZORRO_ID(IVS, 0xF3, 0) -#define ZORRO_PROD_IVS_VECTOR_2 ZORRO_ID(IVS, 0xF4, 0) - -#define ZORRO_MANUF_VECTOR_1 0x0841 -#define ZORRO_PROD_VECTOR_CONNECTION_1 ZORRO_ID(VECTOR_1, 0xE3, 0) - -#define ZORRO_MANUF_XPERT_PRODEV 0x0845 -#define ZORRO_PROD_XPERT_PRODEV_VISIONA_RAM ZORRO_ID(XPERT_PRODEV, 0x01, 0) -#define ZORRO_PROD_XPERT_PRODEV_VISIONA_REG ZORRO_ID(XPERT_PRODEV, 0x02, 0) -#define ZORRO_PROD_XPERT_PRODEV_MERLIN_RAM ZORRO_ID(XPERT_PRODEV, 0x03, 0) -#define ZORRO_PROD_XPERT_PRODEV_MERLIN_REG_1 ZORRO_ID(XPERT_PRODEV, 0x04, 0) -#define ZORRO_PROD_XPERT_PRODEV_MERLIN_REG_2 ZORRO_ID(XPERT_PRODEV, 0xC9, 0) - -#define ZORRO_MANUF_HYDRA_SYSTEMS 0x0849 -#define ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET ZORRO_ID(HYDRA_SYSTEMS, 0x01, 0) - -#define ZORRO_MANUF_SUNRIZE_INDUSTRIES 0x084F -#define ZORRO_PROD_SUNRIZE_INDUSTRIES_AD1012 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x01, 0) -#define ZORRO_PROD_SUNRIZE_INDUSTRIES_AD516 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x02, 0) -#define ZORRO_PROD_SUNRIZE_INDUSTRIES_DD512 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x03, 0) - -#define ZORRO_MANUF_TRICERATOPS 0x0850 -#define ZORRO_PROD_TRICERATOPS_MULTI_IO ZORRO_ID(TRICERATOPS, 0x01, 0) - -#define ZORRO_MANUF_APPLIED_MAGIC 0x0851 -#define ZORRO_PROD_APPLIED_MAGIC_DMI_RESOLVER ZORRO_ID(APPLIED_MAGIC, 0x01, 0) -#define ZORRO_PROD_APPLIED_MAGIC_DIGITAL_BROADCASTER ZORRO_ID(APPLIED_MAGIC, 0x06, 0) - -#define ZORRO_MANUF_GFX_BASE 0x085E -#define ZORRO_PROD_GFX_BASE_GDA_1_VRAM ZORRO_ID(GFX_BASE, 0x00, 0) -#define ZORRO_PROD_GFX_BASE_GDA_1 ZORRO_ID(GFX_BASE, 0x01, 0) - -#define ZORRO_MANUF_ROCTEC 0x0860 -#define ZORRO_PROD_ROCTEC_RH_800C ZORRO_ID(ROCTEC, 0x01, 0) -#define ZORRO_PROD_ROCTEC_RH_800C_RAM ZORRO_ID(ROCTEC, 0x01, 0) - -#define ZORRO_MANUF_KATO 0x0861 -#define ZORRO_PROD_KATO_MELODY ZORRO_ID(KATO, 0x80, 0) -/* ID clash!! */ -#define ZORRO_MANUF_HELFRICH_1 0x0861 -#define ZORRO_PROD_HELFRICH_RAINBOW_II ZORRO_ID(HELFRICH_1, 0x20, 0) -#define ZORRO_PROD_HELFRICH_RAINBOW_III ZORRO_ID(HELFRICH_1, 0x21, 0) - -#define ZORRO_MANUF_ATLANTIS 0x0862 - -#define ZORRO_MANUF_PROTAR 0x0864 - -#define ZORRO_MANUF_ACS 0x0865 - -#define ZORRO_MANUF_SOFTWARE_RESULTS_ENTERPRISES 0x0866 -#define ZORRO_PROD_SOFTWARE_RESULTS_ENTERPRISES_GOLDEN_GATE_2_BUS_PLUS ZORRO_ID(SOFTWARE_RESULTS_ENTERPRISES, 0x01, 0) - -#define ZORRO_MANUF_MASOBOSHI 0x086D -#define ZORRO_PROD_MASOBOSHI_MASTER_CARD_SC201 ZORRO_ID(MASOBOSHI, 0x03, 0) -#define ZORRO_PROD_MASOBOSHI_MASTER_CARD_MC702 ZORRO_ID(MASOBOSHI, 0x04, 0) -#define ZORRO_PROD_MASOBOSHI_MVD_819 ZORRO_ID(MASOBOSHI, 0x07, 0) - -#define ZORRO_MANUF_MAINHATTAN_DATA 0x086F -#define ZORRO_PROD_MAINHATTAN_DATA_IDE ZORRO_ID(MAINHATTAN_DATA, 0x01, 0) - -#define ZORRO_MANUF_VILLAGE_TRONIC 0x0877 -#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_RAM ZORRO_ID(VILLAGE_TRONIC, 0x01, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_REG ZORRO_ID(VILLAGE_TRONIC, 0x02, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_16M_PROTOTYPE ZORRO_ID(VILLAGE_TRONIC, 0x03, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM ZORRO_ID(VILLAGE_TRONIC, 0x0B, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG ZORRO_ID(VILLAGE_TRONIC, 0x0C, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_SEGMENTED_MODE ZORRO_ID(VILLAGE_TRONIC, 0x0D, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG ZORRO_ID(VILLAGE_TRONIC, 0x17, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 ZORRO_ID(VILLAGE_TRONIC, 0x18, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE ZORRO_ID(VILLAGE_TRONIC, 0xC9, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2 ZORRO_ID(VILLAGE_TRONIC, 0xCA, 0) - -#define ZORRO_MANUF_UTILITIES_UNLIMITED 0x087B -#define ZORRO_PROD_UTILITIES_UNLIMITED_EMPLANT_DELUXE ZORRO_ID(UTILITIES_UNLIMITED, 0x15, 0) -#define ZORRO_PROD_UTILITIES_UNLIMITED_EMPLANT_DELUXE2 ZORRO_ID(UTILITIES_UNLIMITED, 0x20, 0) - -#define ZORRO_MANUF_AMITRIX 0x0880 -#define ZORRO_PROD_AMITRIX_MULTI_IO ZORRO_ID(AMITRIX, 0x01, 0) -#define ZORRO_PROD_AMITRIX_CD_RAM ZORRO_ID(AMITRIX, 0x02, 0) - -#define ZORRO_MANUF_ARMAX 0x0885 -#define ZORRO_PROD_ARMAX_OMNIBUS ZORRO_ID(ARMAX, 0x00, 0) - -#define ZORRO_MANUF_ZEUS 0x088D -#define ZORRO_PROD_ZEUS_SPIDER ZORRO_ID(ZEUS, 0x04, 0) - -#define ZORRO_MANUF_NEWTEK 0x088F -#define ZORRO_PROD_NEWTEK_VIDEOTOASTER ZORRO_ID(NEWTEK, 0x00, 0) - -#define ZORRO_MANUF_M_TECH_GERMANY 0x0890 -#define ZORRO_PROD_MTEC_AT500_2 ZORRO_ID(M_TECH_GERMANY, 0x01, 0) -#define ZORRO_PROD_MTEC_68030 ZORRO_ID(M_TECH_GERMANY, 0x03, 0) -#define ZORRO_PROD_MTEC_68020I ZORRO_ID(M_TECH_GERMANY, 0x06, 0) -#define ZORRO_PROD_MTEC_A1200_T68030_RTC ZORRO_ID(M_TECH_GERMANY, 0x20, 0) -#define ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530 ZORRO_ID(M_TECH_GERMANY, 0x21, 0) -#define ZORRO_PROD_MTEC_8_MB_RAM ZORRO_ID(M_TECH_GERMANY, 0x22, 0) -#define ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE ZORRO_ID(M_TECH_GERMANY, 0x24, 0) - -#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_4 0x0891 -#define ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM ZORRO_ID(GREAT_VALLEY_PRODUCTS_4, 0x01, 0) -#define ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG ZORRO_ID(GREAT_VALLEY_PRODUCTS_4, 0x02, 0) - -#define ZORRO_MANUF_APOLLO_1 0x0892 -#define ZORRO_PROD_APOLLO_A1200 ZORRO_ID(APOLLO_1, 0x01, 0) - -#define ZORRO_MANUF_HELFRICH_2 0x0893 -#define ZORRO_PROD_HELFRICH_PICCOLO_RAM ZORRO_ID(HELFRICH_2, 0x05, 0) -#define ZORRO_PROD_HELFRICH_PICCOLO_REG ZORRO_ID(HELFRICH_2, 0x06, 0) -#define ZORRO_PROD_HELFRICH_PEGGY_PLUS_MPEG ZORRO_ID(HELFRICH_2, 0x07, 0) -#define ZORRO_PROD_HELFRICH_VIDEOCRUNCHER ZORRO_ID(HELFRICH_2, 0x08, 0) -#define ZORRO_PROD_HELFRICH_SD64_RAM ZORRO_ID(HELFRICH_2, 0x0A, 0) -#define ZORRO_PROD_HELFRICH_SD64_REG ZORRO_ID(HELFRICH_2, 0x0B, 0) - -#define ZORRO_MANUF_MACROSYSTEMS_USA 0x089B -#define ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx ZORRO_ID(MACROSYSTEMS_USA, 0x13, 0) - -#define ZORRO_MANUF_ELBOX_COMPUTER 0x089E -#define ZORRO_PROD_ELBOX_COMPUTER_1200_4 ZORRO_ID(ELBOX_COMPUTER, 0x06, 0) - -#define ZORRO_MANUF_HARMS_PROFESSIONAL 0x0A00 -#define ZORRO_PROD_HARMS_PROFESSIONAL_030_PLUS ZORRO_ID(HARMS_PROFESSIONAL, 0x10, 0) -#define ZORRO_PROD_HARMS_PROFESSIONAL_3500 ZORRO_ID(HARMS_PROFESSIONAL, 0xD0, 0) - -#define ZORRO_MANUF_MICRONIK 0x0A50 -#define ZORRO_PROD_MICRONIK_RCA_120 ZORRO_ID(MICRONIK, 0x0A, 0) - -#define ZORRO_MANUF_MICRONIK2 0x0F0F -#define ZORRO_PROD_MICRONIK2_Z3I ZORRO_ID(MICRONIK2, 0x01, 0) - -#define ZORRO_MANUF_MEGAMICRO 0x1000 -#define ZORRO_PROD_MEGAMICRO_SCRAM_500 ZORRO_ID(MEGAMICRO, 0x03, 0) -#define ZORRO_PROD_MEGAMICRO_SCRAM_500_RAM ZORRO_ID(MEGAMICRO, 0x04, 0) - -#define ZORRO_MANUF_IMTRONICS_2 0x1028 -#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_3 ZORRO_ID(IMTRONICS_2, 0x39, 0) -#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_4 ZORRO_ID(IMTRONICS_2, 0x57, 0) - -/* unofficial ID */ -#define ZORRO_MANUF_INDIVIDUAL_COMPUTERS 0x1212 -#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x00, 0) -#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x2A, 0) - -#define ZORRO_MANUF_KUPKE_3 0x1248 -#define ZORRO_PROD_KUPKE_GOLEM_HD_3000 ZORRO_ID(KUPKE_3, 0x01, 0) - -#define ZORRO_MANUF_ITH 0x1388 -#define ZORRO_PROD_ITH_ISDN_MASTER_II ZORRO_ID(ITH, 0x01, 0) - -#define ZORRO_MANUF_VMC 0x1389 -#define ZORRO_PROD_VMC_ISDN_BLASTER_Z2 ZORRO_ID(VMC, 0x01, 0) -#define ZORRO_PROD_VMC_HYPERCOM_4 ZORRO_ID(VMC, 0x02, 0) - -#define ZORRO_MANUF_INFORMATION 0x157C -#define ZORRO_PROD_INFORMATION_ISDN_ENGINE_I ZORRO_ID(INFORMATION, 0x64, 0) - -#define ZORRO_MANUF_VORTEX 0x2017 -#define ZORRO_PROD_VORTEX_GOLDEN_GATE_80386SX ZORRO_ID(VORTEX, 0x07, 0) -#define ZORRO_PROD_VORTEX_GOLDEN_GATE_RAM ZORRO_ID(VORTEX, 0x08, 0) -#define ZORRO_PROD_VORTEX_GOLDEN_GATE_80486 ZORRO_ID(VORTEX, 0x09, 0) - -#define ZORRO_MANUF_EXPANSION_SYSTEMS 0x2062 -#define ZORRO_PROD_EXPANSION_SYSTEMS_DATAFLYER_4000SX ZORRO_ID(EXPANSION_SYSTEMS, 0x01, 0) -#define ZORRO_PROD_EXPANSION_SYSTEMS_DATAFLYER_4000SX_RAM ZORRO_ID(EXPANSION_SYSTEMS, 0x02, 0) - -#define ZORRO_MANUF_READYSOFT 0x2100 -#define ZORRO_PROD_READYSOFT_AMAX_II_IV ZORRO_ID(READYSOFT, 0x01, 0) - -#define ZORRO_MANUF_PHASE5 0x2140 -#define ZORRO_PROD_PHASE5_BLIZZARD_RAM ZORRO_ID(PHASE5, 0x01, 0) -#define ZORRO_PROD_PHASE5_BLIZZARD ZORRO_ID(PHASE5, 0x02, 0) -#define ZORRO_PROD_PHASE5_BLIZZARD_1220_IV ZORRO_ID(PHASE5, 0x06, 0) -#define ZORRO_PROD_PHASE5_FASTLANE_Z3_RAM ZORRO_ID(PHASE5, 0x0A, 0) -#define ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060 ZORRO_ID(PHASE5, 0x0B, 0) -#define ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM ZORRO_ID(PHASE5, 0x0C, 0) -#define ZORRO_PROD_PHASE5_BLIZZARD_1230 ZORRO_ID(PHASE5, 0x0D, 0) -#define ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260 ZORRO_ID(PHASE5, 0x11, 0) -#define ZORRO_PROD_PHASE5_BLIZZARD_2060 ZORRO_ID(PHASE5, 0x18, 0) -#define ZORRO_PROD_PHASE5_CYBERSTORM_MK_II ZORRO_ID(PHASE5, 0x19, 0) -#define ZORRO_PROD_PHASE5_CYBERVISION64 ZORRO_ID(PHASE5, 0x22, 0) -#define ZORRO_PROD_PHASE5_CYBERVISION64_3D_PROTOTYPE ZORRO_ID(PHASE5, 0x32, 0) -#define ZORRO_PROD_PHASE5_CYBERVISION64_3D ZORRO_ID(PHASE5, 0x43, 0) -#define ZORRO_PROD_PHASE5_CYBERSTORM_MK_III ZORRO_ID(PHASE5, 0x64, 0) -#define ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS ZORRO_ID(PHASE5, 0x6e, 0) - -#define ZORRO_MANUF_DPS 0x2169 -#define ZORRO_PROD_DPS_PERSONAL_ANIMATION_RECORDER ZORRO_ID(DPS, 0x01, 0) - -#define ZORRO_MANUF_APOLLO_2 0x2200 -#define ZORRO_PROD_APOLLO_A620_68020_1 ZORRO_ID(APOLLO_2, 0x00, 0) -#define ZORRO_PROD_APOLLO_A620_68020_2 ZORRO_ID(APOLLO_2, 0x01, 0) - -#define ZORRO_MANUF_APOLLO_3 0x2222 -#define ZORRO_PROD_APOLLO_AT_APOLLO ZORRO_ID(APOLLO_3, 0x22, 0) -#define ZORRO_PROD_APOLLO_1230_1240_1260_2030_4040_4060 ZORRO_ID(APOLLO_3, 0x23, 0) - -#define ZORRO_MANUF_PETSOFF_LP 0x38A5 -#define ZORRO_PROD_PETSOFF_LP_DELFINA ZORRO_ID(PETSOFF_LP, 0x00, 0) -#define ZORRO_PROD_PETSOFF_LP_DELFINA_LITE ZORRO_ID(PETSOFF_LP, 0x01, 0) - -#define ZORRO_MANUF_UWE_GERLACH 0x3FF7 -#define ZORRO_PROD_UWE_GERLACH_RAM_ROM ZORRO_ID(UWE_GERLACH, 0xd4, 0) - -#define ZORRO_MANUF_ACT 0x4231 -#define ZORRO_PROD_ACT_PRELUDE ZORRO_ID(ACT, 0x01, 0) - -#define ZORRO_MANUF_MACROSYSTEMS_GERMANY 0x4754 -#define ZORRO_PROD_MACROSYSTEMS_MAESTRO ZORRO_ID(MACROSYSTEMS_GERMANY, 0x03, 0) -#define ZORRO_PROD_MACROSYSTEMS_VLAB ZORRO_ID(MACROSYSTEMS_GERMANY, 0x04, 0) -#define ZORRO_PROD_MACROSYSTEMS_MAESTRO_PRO ZORRO_ID(MACROSYSTEMS_GERMANY, 0x05, 0) -#define ZORRO_PROD_MACROSYSTEMS_RETINA ZORRO_ID(MACROSYSTEMS_GERMANY, 0x06, 0) -#define ZORRO_PROD_MACROSYSTEMS_MULTI_EVOLUTION ZORRO_ID(MACROSYSTEMS_GERMANY, 0x08, 0) -#define ZORRO_PROD_MACROSYSTEMS_TOCCATA ZORRO_ID(MACROSYSTEMS_GERMANY, 0x0C, 0) -#define ZORRO_PROD_MACROSYSTEMS_RETINA_Z3 ZORRO_ID(MACROSYSTEMS_GERMANY, 0x10, 0) -#define ZORRO_PROD_MACROSYSTEMS_VLAB_MOTION ZORRO_ID(MACROSYSTEMS_GERMANY, 0x12, 0) -#define ZORRO_PROD_MACROSYSTEMS_ALTAIS ZORRO_ID(MACROSYSTEMS_GERMANY, 0x13, 0) -#define ZORRO_PROD_MACROSYSTEMS_FALCON_040 ZORRO_ID(MACROSYSTEMS_GERMANY, 0xFD, 0) - -#define ZORRO_MANUF_COMBITEC 0x6766 - -#define ZORRO_MANUF_SKI_PERIPHERALS 0x8000 -#define ZORRO_PROD_SKI_PERIPHERALS_MAST_FIREBALL ZORRO_ID(SKI_PERIPHERALS, 0x08, 0) -#define ZORRO_PROD_SKI_PERIPHERALS_SCSI_DUAL_SERIAL ZORRO_ID(SKI_PERIPHERALS, 0x80, 0) - -#define ZORRO_MANUF_REIS_WARE_2 0xA9AD -#define ZORRO_PROD_REIS_WARE_SCAN_KING ZORRO_ID(REIS_WARE_2, 0x11, 0) - -#define ZORRO_MANUF_CAMERON 0xAA01 -#define ZORRO_PROD_CAMERON_PERSONAL_A4 ZORRO_ID(CAMERON, 0x10, 0) - -#define ZORRO_MANUF_REIS_WARE 0xAA11 -#define ZORRO_PROD_REIS_WARE_HANDYSCANNER ZORRO_ID(REIS_WARE, 0x11, 0) - -#define ZORRO_MANUF_PHOENIX_2 0xB5A8 -#define ZORRO_PROD_PHOENIX_ST506_2 ZORRO_ID(PHOENIX_2, 0x21, 0) -#define ZORRO_PROD_PHOENIX_SCSI_2 ZORRO_ID(PHOENIX_2, 0x22, 0) -#define ZORRO_PROD_PHOENIX_RAM_2 ZORRO_ID(PHOENIX_2, 0xBE, 0) - -#define ZORRO_MANUF_COMBITEC_2 0xC008 -#define ZORRO_PROD_COMBITEC_HD ZORRO_ID(COMBITEC_2, 0x2A, 0) -#define ZORRO_PROD_COMBITEC_SRAM ZORRO_ID(COMBITEC_2, 0x2B, 0) - - - /* - * Test and illegal Manufacturer IDs. - */ - -#define ZORRO_MANUF_HACKER 0x07DB -#define ZORRO_PROD_GENERAL_PROTOTYPE ZORRO_ID(HACKER, 0x00, 0) -#define ZORRO_PROD_HACKER_SCSI ZORRO_ID(HACKER, 0x01, 0) -#define ZORRO_PROD_RESOURCE_MANAGEMENT_FORCE_QUICKNET_QN2000 ZORRO_ID(HACKER, 0x02, 0) -#define ZORRO_PROD_VECTOR_CONNECTION_2 ZORRO_ID(HACKER, 0xE0, 0) -#define ZORRO_PROD_VECTOR_CONNECTION_3 ZORRO_ID(HACKER, 0xE1, 0) -#define ZORRO_PROD_VECTOR_CONNECTION_4 ZORRO_ID(HACKER, 0xE2, 0) -#define ZORRO_PROD_VECTOR_CONNECTION_5 ZORRO_ID(HACKER, 0xE3, 0) +/* Include the ID list */ +#include <linux/zorro_ids.h> /* @@ -704,7 +159,7 @@ struct zorro_dev { zorro_id id; u16 slotaddr; u16 slotsize; - char name[48]; + char name[64]; struct resource resource; }; @@ -717,6 +172,7 @@ extern struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO]; */ extern void zorro_init(void); +extern void zorro_name_device(struct zorro_dev *dev); extern struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from); diff --git a/include/linux/zorro_ids.h b/include/linux/zorro_ids.h new file mode 100644 index 000000000..0a09d97bc --- /dev/null +++ b/include/linux/zorro_ids.h @@ -0,0 +1,551 @@ +/* + * Zorro board IDs + * + * Please keep sorted. + */ + + +#define ZORRO_MANUF_PACIFIC_PERIPHERALS 0x00D3 +#define ZORRO_PROD_PACIFIC_PERIPHERALS_SE_2000_A500 ZORRO_ID(PACIFIC_PERIPHERALS, 0x00, 0) +#define ZORRO_PROD_PACIFIC_PERIPHERALS_SCSI ZORRO_ID(PACIFIC_PERIPHERALS, 0x0A, 0) + +#define ZORRO_MANUF_MACROSYSTEMS_USA_2 0x0100 +#define ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE ZORRO_ID(MACROSYSTEMS_USA_2, 0x13, 0) + +#define ZORRO_MANUF_KUPKE_1 0x00DD +#define ZORRO_PROD_KUPKE_GOLEM_RAM_BOX_2MB ZORRO_ID(KUPKE_1, 0x00, 0) + +#define ZORRO_MANUF_MEMPHIS 0x0100 +#define ZORRO_PROD_MEMPHIS_STORMBRINGER ZORRO_ID(MEMPHIS, 0x00, 0) + +#define ZORRO_MANUF_3_STATE 0x0200 +#define ZORRO_PROD_3_STATE_MEGAMIX_2000 ZORRO_ID(3_STATE, 0x02, 0) + +#define ZORRO_MANUF_COMMODORE_BRAUNSCHWEIG 0x0201 +#define ZORRO_PROD_CBM_A2088_A2286 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x01, 0) +#define ZORRO_PROD_CBM_A2286 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x02, 0) +#define ZORRO_PROD_CBM_A4091_1 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x54, 0) +#define ZORRO_PROD_CBM_A2386SX_1 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x67, 0) + +#define ZORRO_MANUF_COMMODORE_WEST_CHESTER_1 0x0202 +#define ZORRO_PROD_CBM_A2090A ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x01, 0) +#define ZORRO_PROD_CBM_A590_A2091_1 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x02, 0) +#define ZORRO_PROD_CBM_A590_A2091_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x03, 0) +#define ZORRO_PROD_CBM_A2090B ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x04, 0) +#define ZORRO_PROD_CBM_A2060 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x09, 0) +#define ZORRO_PROD_CBM_A590_A2052_A2058_A2091 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x0A, 0) +#define ZORRO_PROD_CBM_A560_RAM ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x20, 0) +#define ZORRO_PROD_CBM_A2232_PROTOTYPE ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x45, 0) +#define ZORRO_PROD_CBM_A2232 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x46, 0) +#define ZORRO_PROD_CBM_A2620 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x50, 0) +#define ZORRO_PROD_CBM_A2630 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x51, 0) +#define ZORRO_PROD_CBM_A4091_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x54, 0) +#define ZORRO_PROD_CBM_A2065_1 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x5A, 0) +#define ZORRO_PROD_CBM_ROMULATOR ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x60, 0) +#define ZORRO_PROD_CBM_A3000_TEST_FIXTURE ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x61, 0) +#define ZORRO_PROD_CBM_A2386SX_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x67, 0) +#define ZORRO_PROD_CBM_A2065_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x70, 0) + +#define ZORRO_MANUF_COMMODORE_WEST_CHESTER_2 0x0203 +#define ZORRO_PROD_CBM_A2090A_CM ZORRO_ID(COMMODORE_WEST_CHESTER_2, 0x03, 0) + +#define ZORRO_MANUF_PROGRESSIVE_PERIPHERALS_AND_SYSTEMS_2 0x02F4 +#define ZORRO_PROD_PPS_EXP8000 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS_2, 0x02, 0) + +#define ZORRO_MANUF_KOLFF_COMPUTER_SUPPLIES 0x02FF +#define ZORRO_PROD_KCS_POWER_PC_BOARD ZORRO_ID(KOLFF_COMPUTER_SUPPLIES, 0x00, 0) + +#define ZORRO_MANUF_CARDCO_1 0x03EC +#define ZORRO_PROD_CARDCO_KRONOS_2000_1 ZORRO_ID(CARDCO_1, 0x04, 0) +#define ZORRO_PROD_CARDCO_A1000_1 ZORRO_ID(CARDCO_1, 0x0C, 0) +#define ZORRO_PROD_CARDCO_ESCORT ZORRO_ID(CARDCO_1, 0x0E, 0) +#define ZORRO_PROD_CARDCO_A2410 ZORRO_ID(CARDCO_1, 0xF5, 0) + +#define ZORRO_MANUF_A_SQUARED 0x03ED +#define ZORRO_PROD_A_SQUARED_LIVE_2000 ZORRO_ID(A_SQUARED, 0x01, 0) + +#define ZORRO_MANUF_COMSPEC_COMMUNICATIONS 0x03EE +#define ZORRO_PROD_COMSPEC_COMMUNICATIONS_AX2000 ZORRO_ID(COMSPEC_COMMUNICATIONS, 0x01, 0) + +#define ZORRO_MANUF_ANAKIN_RESEARCH 0x03F1 +#define ZORRO_PROD_ANAKIN_RESEARCH_EASYL ZORRO_ID(ANAKIN_RESEARCH, 0x01, 0) + +#define ZORRO_MANUF_MICROBOTICS 0x03F2 +#define ZORRO_PROD_MICROBOTICS_STARBOARD_II ZORRO_ID(MICROBOTICS, 0x00, 0) +#define ZORRO_PROD_MICROBOTICS_STARDRIVE ZORRO_ID(MICROBOTICS, 0x02, 0) +#define ZORRO_PROD_MICROBOTICS_8_UP_A ZORRO_ID(MICROBOTICS, 0x03, 0) +#define ZORRO_PROD_MICROBOTICS_8_UP_Z ZORRO_ID(MICROBOTICS, 0x04, 0) +#define ZORRO_PROD_MICROBOTICS_DELTA_RAM ZORRO_ID(MICROBOTICS, 0x20, 0) +#define ZORRO_PROD_MICROBOTICS_8_STAR_RAM ZORRO_ID(MICROBOTICS, 0x40, 0) +#define ZORRO_PROD_MICROBOTICS_8_STAR ZORRO_ID(MICROBOTICS, 0x41, 0) +#define ZORRO_PROD_MICROBOTICS_VXL_RAM_32 ZORRO_ID(MICROBOTICS, 0x44, 0) +#define ZORRO_PROD_MICROBOTICS_VXL_68030 ZORRO_ID(MICROBOTICS, 0x45, 0) +#define ZORRO_PROD_MICROBOTICS_DELTA ZORRO_ID(MICROBOTICS, 0x60, 0) +#define ZORRO_PROD_MICROBOTICS_MBX_1200_1200Z_RAM ZORRO_ID(MICROBOTICS, 0x81, 0) +#define ZORRO_PROD_MICROBOTICS_HARDFRAME_2000_1 ZORRO_ID(MICROBOTICS, 0x96, 0) +#define ZORRO_PROD_MICROBOTICS_HARDFRAME_2000_2 ZORRO_ID(MICROBOTICS, 0x9E, 0) +#define ZORRO_PROD_MICROBOTICS_MBX_1200_1200Z ZORRO_ID(MICROBOTICS, 0xC1, 0) + +#define ZORRO_MANUF_ACCESS_ASSOCIATES_ALEGRA 0x03F4 + +#define ZORRO_MANUF_EXPANSION_TECHNOLOGIES 0x03F6 + +#define ZORRO_MANUF_ASDG 0x03FF +#define ZORRO_PROD_ASDG_MEMORY_1 ZORRO_ID(ASDG, 0x01, 0) +#define ZORRO_PROD_ASDG_MEMORY_2 ZORRO_ID(ASDG, 0x02, 0) +#define ZORRO_PROD_ASDG_EB920_LAN_ROVER ZORRO_ID(ASDG, 0xFE, 0) +#define ZORRO_PROD_ASDG_GPIB_DUALIEEE488_TWIN_X ZORRO_ID(ASDG, 0xFF, 0) + +#define ZORRO_MANUF_IMTRONICS_1 0x0404 +#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_1 ZORRO_ID(IMTRONICS_1, 0x39, 0) +#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_2 ZORRO_ID(IMTRONICS_1, 0x57, 0) + +#define ZORRO_MANUF_CBM_UNIVERSITY_OF_LOWELL 0x0406 +#define ZORRO_PROD_CBM_A2410 ZORRO_ID(CBM_UNIVERSITY_OF_LOWELL, 0x00, 0) + +#define ZORRO_MANUF_AMERISTAR 0x041D +#define ZORRO_PROD_AMERISTAR_A2065 ZORRO_ID(AMERISTAR, 0x01, 0) +#define ZORRO_PROD_AMERISTAR_A560 ZORRO_ID(AMERISTAR, 0x09, 0) +#define ZORRO_PROD_AMERISTAR_A4066 ZORRO_ID(AMERISTAR, 0x0A, 0) + +#define ZORRO_MANUF_SUPRA 0x0420 +#define ZORRO_PROD_SUPRA_SUPRADRIVE_4x4 ZORRO_ID(SUPRA, 0x01, 0) +#define ZORRO_PROD_SUPRA_1000_RAM ZORRO_ID(SUPRA, 0x02, 0) +#define ZORRO_PROD_SUPRA_2000_DMA ZORRO_ID(SUPRA, 0x03, 0) +#define ZORRO_PROD_SUPRA_500 ZORRO_ID(SUPRA, 0x05, 0) +#define ZORRO_PROD_SUPRA_500_SCSI ZORRO_ID(SUPRA, 0x08, 0) +#define ZORRO_PROD_SUPRA_500XP_2000_RAM ZORRO_ID(SUPRA, 0x09, 0) +#define ZORRO_PROD_SUPRA_500RX_2000_RAM ZORRO_ID(SUPRA, 0x0A, 0) +#define ZORRO_PROD_SUPRA_2400ZI ZORRO_ID(SUPRA, 0x0B, 0) +#define ZORRO_PROD_SUPRA_500XP_SUPRADRIVE_WORDSYNC ZORRO_ID(SUPRA, 0x0C, 0) +#define ZORRO_PROD_SUPRA_SUPRADRIVE_WORDSYNC_II ZORRO_ID(SUPRA, 0x0D, 0) +#define ZORRO_PROD_SUPRA_2400ZIPLUS ZORRO_ID(SUPRA, 0x10, 0) + +#define ZORRO_MANUF_COMPUTER_SYSTEMS_ASSOCIATES 0x0422 +#define ZORRO_PROD_CSA_MAGNUM ZORRO_ID(COMPUTER_SYSTEMS_ASSOCIATES, 0x11, 0) +#define ZORRO_PROD_CSA_12_GAUGE ZORRO_ID(COMPUTER_SYSTEMS_ASSOCIATES, 0x15, 0) + +#define ZORRO_MANUF_MARC_MICHAEL_GROTH 0x0439 + +#define ZORRO_MANUF_M_TECH 0x0502 +#define ZORRO_PROD_MTEC_AT500_1 ZORRO_ID(M_TECH, 0x03, 0) + +#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_1 0x06E1 +#define ZORRO_PROD_GVP_IMPACT_SERIES_I ZORRO_ID(GREAT_VALLEY_PRODUCTS_1, 0x08, 0) + +#define ZORRO_MANUF_BYTEBOX 0x07DA +#define ZORRO_PROD_BYTEBOX_A500 ZORRO_ID(BYTEBOX, 0x00, 0) + +#define ZORRO_MANUF_DKB_POWER_COMPUTING 0x07DC +#define ZORRO_PROD_DKB_POWER_COMPUTING_SECUREKEY ZORRO_ID(DKB_POWER_COMPUTING, 0x09, 0) +#define ZORRO_PROD_DKB_POWER_COMPUTING_DKM_3128 ZORRO_ID(DKB_POWER_COMPUTING, 0x0E, 0) +#define ZORRO_PROD_DKB_POWER_COMPUTING_RAPID_FIRE ZORRO_ID(DKB_POWER_COMPUTING, 0x0F, 0) +#define ZORRO_PROD_DKB_POWER_COMPUTING_DKM_1202 ZORRO_ID(DKB_POWER_COMPUTING, 0x10, 0) +#define ZORRO_PROD_DKB_POWER_COMPUTING_COBRA_VIPER_II_68EC030 ZORRO_ID(DKB_POWER_COMPUTING, 0x12, 0) +#define ZORRO_PROD_DKB_POWER_COMPUTING_WILDFIRE_060_1 ZORRO_ID(DKB_POWER_COMPUTING, 0x17, 0) +#define ZORRO_PROD_DKB_POWER_COMPUTING_WILDFIRE_060_2 ZORRO_ID(DKB_POWER_COMPUTING, 0xFF, 0) + +#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_2 0x07E1 +#define ZORRO_PROD_GVP_IMPACT_SERIES_I_4K ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x01, 0) +#define ZORRO_PROD_GVP_IMPACT_SERIES_I_16K_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x02, 0) +#define ZORRO_PROD_GVP_IMPACT_SERIES_I_16K_3 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x03, 0) +#define ZORRO_PROD_GVP_IMPACT_3001_IDE_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x08, 0) +#define ZORRO_PROD_GVP_IMPACT_3001_RAM ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x09, 0) +#define ZORRO_PROD_GVP_IMPACT_SERIES_II_RAM_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0A, 0) +#define ZORRO_PROD_GVP_EPC_BASE ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0) +#define ZORRO_PROD_GVP_GFORCE_040_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x20) +#define ZORRO_PROD_GVP_GFORCE_040_SCSI_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x30) +#define ZORRO_PROD_GVP_A1291 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x40) +#define ZORRO_PROD_GVP_COMBO_030_R4 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x60) +#define ZORRO_PROD_GVP_COMBO_030_R4_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x70) +#define ZORRO_PROD_GVP_PHONEPAK ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x78) +#define ZORRO_PROD_GVP_IO_EXTENDER ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x98) +#define ZORRO_PROD_GVP_GFORCE_030 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xa0) +#define ZORRO_PROD_GVP_GFORCE_030_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xb0) +#define ZORRO_PROD_GVP_A530 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xc0) +#define ZORRO_PROD_GVP_A530_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xd0) +#define ZORRO_PROD_GVP_COMBO_030_R3 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xe0) +#define ZORRO_PROD_GVP_COMBO_030_R3_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xf0) +#define ZORRO_PROD_GVP_SERIES_II ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xf8) +#define ZORRO_PROD_GVP_IMPACT_3001_IDE_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0D, 0) +/*#define ZORRO_PROD_GVP_A2000_030 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0D, 0)*/ +/*#define ZORRO_PROD_GVP_GFORCE_040_SCSI_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0D, 0)*/ +#define ZORRO_PROD_GVP_GFORCE_040_060 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x16, 0) +#define ZORRO_PROD_GVP_IMPACT_VISION_24 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x20, 0) +#define ZORRO_PROD_GVP_GFORCE_040_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0xFF, 0) + +#define ZORRO_MANUF_CALIFORNIA_ACCESS_SYNERGY 0x07E5 +#define ZORRO_PROD_CALIFORNIA_ACCESS_SYNERGY_MALIBU ZORRO_ID(CALIFORNIA_ACCESS_SYNERGY, 0x01, 0) + +#define ZORRO_MANUF_XETEC 0x07E6 +#define ZORRO_PROD_XETEC_FASTCARD ZORRO_ID(XETEC, 0x01, 0) +#define ZORRO_PROD_XETEC_FASTCARD_RAM ZORRO_ID(XETEC, 0x02, 0) +#define ZORRO_PROD_XETEC_FASTCARD_PLUS ZORRO_ID(XETEC, 0x03, 0) + +#define ZORRO_MANUF_PROGRESSIVE_PERIPHERALS_AND_SYSTEMS 0x07EA +#define ZORRO_PROD_PPS_MERCURY ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x00, 0) +#define ZORRO_PROD_PPS_A3000_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x01, 0) +#define ZORRO_PROD_PPS_A2000_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x69, 0) +#define ZORRO_PROD_PPS_ZEUS ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x96, 0) +#define ZORRO_PROD_PPS_A500_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0xBB, 0) + +#define ZORRO_MANUF_XEBEC 0x07EC + +#define ZORRO_MANUF_SPIRIT_TECHNOLOGY 0x07F2 +#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INSIDER_IN1000 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x01, 0) +#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INSIDER_IN500 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x02, 0) +#define ZORRO_PROD_SPIRIT_TECHNOLOGY_SIN500 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x03, 0) +#define ZORRO_PROD_SPIRIT_TECHNOLOGY_HDA_506 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x04, 0) +#define ZORRO_PROD_SPIRIT_TECHNOLOGY_AX_S ZORRO_ID(SPIRIT_TECHNOLOGY, 0x05, 0) +#define ZORRO_PROD_SPIRIT_TECHNOLOGY_OCTABYTE ZORRO_ID(SPIRIT_TECHNOLOGY, 0x06, 0) +#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INMATE ZORRO_ID(SPIRIT_TECHNOLOGY, 0x08, 0) + +#define ZORRO_MANUF_SPIRIT_TECHNOLOGY_2 0x07F3 + +#define ZORRO_MANUF_BSC_ALFADATA_1 0x07FE +#define ZORRO_PROD_BSC_ALF_3_1 ZORRO_ID(BSC_ALFADATA_1, 0x03, 0) + +#define ZORRO_MANUF_BSC_ALFADATA_2 0x0801 +#define ZORRO_PROD_BSC_ALF_2_1 ZORRO_ID(BSC_ALFADATA_2, 0x01, 0) +#define ZORRO_PROD_BSC_ALF_2_2 ZORRO_ID(BSC_ALFADATA_2, 0x02, 0) +#define ZORRO_PROD_BSC_ALF_3_2 ZORRO_ID(BSC_ALFADATA_2, 0x03, 0) + +#define ZORRO_MANUF_CARDCO_2 0x0802 +#define ZORRO_PROD_CARDCO_KRONOS_2000_2 ZORRO_ID(CARDCO_2, 0x04, 0) +#define ZORRO_PROD_CARDCO_A1000_2 ZORRO_ID(CARDCO_2, 0x0C, 0) + +#define ZORRO_MANUF_JOCHHEIM 0x0804 +#define ZORRO_PROD_JOCHHEIM_RAM ZORRO_ID(JOCHHEIM, 0x01, 0) + +#define ZORRO_MANUF_CHECKPOINT_TECHNOLOGIES 0x0807 +#define ZORRO_PROD_CHECKPOINT_TECHNOLOGIES_SERIAL_SOLUTION ZORRO_ID(CHECKPOINT_TECHNOLOGIES, 0x00, 0) + +#define ZORRO_MANUF_EDOTRONIK 0x0810 +#define ZORRO_PROD_EDOTRONIK_IEEE_488 ZORRO_ID(EDOTRONIK, 0x01, 0) +#define ZORRO_PROD_EDOTRONIK_8032 ZORRO_ID(EDOTRONIK, 0x02, 0) +#define ZORRO_PROD_EDOTRONIK_MULTISERIAL ZORRO_ID(EDOTRONIK, 0x03, 0) +#define ZORRO_PROD_EDOTRONIK_VIDEODIGITIZER ZORRO_ID(EDOTRONIK, 0x04, 0) +#define ZORRO_PROD_EDOTRONIK_PARALLEL_IO ZORRO_ID(EDOTRONIK, 0x05, 0) +#define ZORRO_PROD_EDOTRONIK_PIC_PROTOYPING ZORRO_ID(EDOTRONIK, 0x06, 0) +#define ZORRO_PROD_EDOTRONIK_ADC ZORRO_ID(EDOTRONIK, 0x07, 0) +#define ZORRO_PROD_EDOTRONIK_VME ZORRO_ID(EDOTRONIK, 0x08, 0) +#define ZORRO_PROD_EDOTRONIK_DSP96000 ZORRO_ID(EDOTRONIK, 0x09, 0) + +#define ZORRO_MANUF_NES_INC 0x0813 +#define ZORRO_PROD_NES_INC_RAM ZORRO_ID(NES_INC, 0x00, 0) + +#define ZORRO_MANUF_ICD 0x0817 +#define ZORRO_PROD_ICD_ADVANTAGE_2000_SCSI ZORRO_ID(ICD, 0x01, 0) +#define ZORRO_PROD_ICD_ADVANTAGE_IDE ZORRO_ID(ICD, 0x03, 0) +#define ZORRO_PROD_ICD_ADVANTAGE_2080_RAM ZORRO_ID(ICD, 0x04, 0) + +#define ZORRO_MANUF_KUPKE_2 0x0819 +#define ZORRO_PROD_KUPKE_OMTI ZORRO_ID(KUPKE_2, 0x01, 0) +#define ZORRO_PROD_KUPKE_SCSI_II ZORRO_ID(KUPKE_2, 0x02, 0) +#define ZORRO_PROD_KUPKE_GOLEM_BOX ZORRO_ID(KUPKE_2, 0x03, 0) +#define ZORRO_PROD_KUPKE_030_882 ZORRO_ID(KUPKE_2, 0x04, 0) +#define ZORRO_PROD_KUPKE_SCSI_AT ZORRO_ID(KUPKE_2, 0x05, 0) + +#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_3 0x081D +#define ZORRO_PROD_GVP_A2000_RAM8 ZORRO_ID(GREAT_VALLEY_PRODUCTS_3, 0x09, 0) +#define ZORRO_PROD_GVP_IMPACT_SERIES_II_RAM_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_3, 0x0A, 0) + +#define ZORRO_MANUF_INTERWORKS_NETWORK 0x081E + +#define ZORRO_MANUF_HARDITAL_SYNTHESIS 0x0820 +#define ZORRO_PROD_HARDITAL_SYNTHESIS_TQM_68030_68882 ZORRO_ID(HARDITAL_SYNTHESIS, 0x14, 0) + +#define ZORRO_MANUF_APPLIED_ENGINEERING 0x0828 +#define ZORRO_PROD_APPLIED_ENGINEERING_DL2000 ZORRO_ID(APPLIED_ENGINEERING, 0x10, 0) +#define ZORRO_PROD_APPLIED_ENGINEERING_RAM_WORKS ZORRO_ID(APPLIED_ENGINEERING, 0xE0, 0) + +#define ZORRO_MANUF_BSC_ALFADATA_3 0x082C +#define ZORRO_PROD_BSC_OKTAGON_2008 ZORRO_ID(BSC_ALFADATA_3, 0x05, 0) +#define ZORRO_PROD_BSC_TANDEM_AT_2008_508 ZORRO_ID(BSC_ALFADATA_3, 0x06, 0) +#define ZORRO_PROD_BSC_ALFA_RAM_1200 ZORRO_ID(BSC_ALFADATA_3, 0x07, 0) +#define ZORRO_PROD_BSC_OKTAGON_2008_RAM ZORRO_ID(BSC_ALFADATA_3, 0x08, 0) +#define ZORRO_PROD_BSC_MULTIFACE_I ZORRO_ID(BSC_ALFADATA_3, 0x10, 0) +#define ZORRO_PROD_BSC_MULTIFACE_II ZORRO_ID(BSC_ALFADATA_3, 0x11, 0) +#define ZORRO_PROD_BSC_MULTIFACE_III ZORRO_ID(BSC_ALFADATA_3, 0x12, 0) +#define ZORRO_PROD_BSC_FRAMEMASTER_II ZORRO_ID(BSC_ALFADATA_3, 0x20, 0) +#define ZORRO_PROD_BSC_GRAFFITI_RAM ZORRO_ID(BSC_ALFADATA_3, 0x21, 0) +#define ZORRO_PROD_BSC_GRAFFITI_REG ZORRO_ID(BSC_ALFADATA_3, 0x22, 0) +#define ZORRO_PROD_BSC_ISDN_MASTERCARD ZORRO_ID(BSC_ALFADATA_3, 0x40, 0) +#define ZORRO_PROD_BSC_ISDN_MASTERCARD_II ZORRO_ID(BSC_ALFADATA_3, 0x41, 0) + +#define ZORRO_MANUF_PHOENIX 0x0835 +#define ZORRO_PROD_PHOENIX_ST506 ZORRO_ID(PHOENIX, 0x21, 0) +#define ZORRO_PROD_PHOENIX_SCSI ZORRO_ID(PHOENIX, 0x22, 0) +#define ZORRO_PROD_PHOENIX_RAM ZORRO_ID(PHOENIX, 0xBE, 0) + +#define ZORRO_MANUF_ADVANCED_STORAGE_SYSTEMS 0x0836 +#define ZORRO_PROD_ADVANCED_STORAGE_SYSTEMS_NEXUS ZORRO_ID(ADVANCED_STORAGE_SYSTEMS, 0x01, 0) +#define ZORRO_PROD_ADVANCED_STORAGE_SYSTEMS_NEXUS_RAM ZORRO_ID(ADVANCED_STORAGE_SYSTEMS, 0x08, 0) + +#define ZORRO_MANUF_IMPULSE 0x0838 +#define ZORRO_PROD_IMPULSE_FIRECRACKER_24 ZORRO_ID(IMPULSE, 0x00, 0) + +#define ZORRO_MANUF_IVS 0x0840 +#define ZORRO_PROD_IVS_GRANDSLAM_PIC_2 ZORRO_ID(IVS, 0x02, 0) +#define ZORRO_PROD_IVS_GRANDSLAM_PIC_1 ZORRO_ID(IVS, 0x04, 0) +#define ZORRO_PROD_IVS_OVERDRIVE ZORRO_ID(IVS, 0x10, 0) +#define ZORRO_PROD_IVS_TRUMPCARD_CLASSIC ZORRO_ID(IVS, 0x30, 0) +#define ZORRO_PROD_IVS_TRUMPCARD_PRO_GRANDSLAM ZORRO_ID(IVS, 0x34, 0) +#define ZORRO_PROD_IVS_META_4 ZORRO_ID(IVS, 0x40, 0) +#define ZORRO_PROD_IVS_WAVETOOLS ZORRO_ID(IVS, 0xBF, 0) +#define ZORRO_PROD_IVS_VECTOR_1 ZORRO_ID(IVS, 0xF3, 0) +#define ZORRO_PROD_IVS_VECTOR_2 ZORRO_ID(IVS, 0xF4, 0) + +#define ZORRO_MANUF_VECTOR_1 0x0841 +#define ZORRO_PROD_VECTOR_CONNECTION_1 ZORRO_ID(VECTOR_1, 0xE3, 0) + +#define ZORRO_MANUF_XPERT_PRODEV 0x0845 +#define ZORRO_PROD_XPERT_PRODEV_VISIONA_RAM ZORRO_ID(XPERT_PRODEV, 0x01, 0) +#define ZORRO_PROD_XPERT_PRODEV_VISIONA_REG ZORRO_ID(XPERT_PRODEV, 0x02, 0) +#define ZORRO_PROD_XPERT_PRODEV_MERLIN_RAM ZORRO_ID(XPERT_PRODEV, 0x03, 0) +#define ZORRO_PROD_XPERT_PRODEV_MERLIN_REG_1 ZORRO_ID(XPERT_PRODEV, 0x04, 0) +#define ZORRO_PROD_XPERT_PRODEV_MERLIN_REG_2 ZORRO_ID(XPERT_PRODEV, 0xC9, 0) + +#define ZORRO_MANUF_HYDRA_SYSTEMS 0x0849 +#define ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET ZORRO_ID(HYDRA_SYSTEMS, 0x01, 0) + +#define ZORRO_MANUF_SUNRIZE_INDUSTRIES 0x084F +#define ZORRO_PROD_SUNRIZE_INDUSTRIES_AD1012 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x01, 0) +#define ZORRO_PROD_SUNRIZE_INDUSTRIES_AD516 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x02, 0) +#define ZORRO_PROD_SUNRIZE_INDUSTRIES_DD512 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x03, 0) + +#define ZORRO_MANUF_TRICERATOPS 0x0850 +#define ZORRO_PROD_TRICERATOPS_MULTI_IO ZORRO_ID(TRICERATOPS, 0x01, 0) + +#define ZORRO_MANUF_APPLIED_MAGIC 0x0851 +#define ZORRO_PROD_APPLIED_MAGIC_DMI_RESOLVER ZORRO_ID(APPLIED_MAGIC, 0x01, 0) +#define ZORRO_PROD_APPLIED_MAGIC_DIGITAL_BROADCASTER ZORRO_ID(APPLIED_MAGIC, 0x06, 0) + +#define ZORRO_MANUF_GFX_BASE 0x085E +#define ZORRO_PROD_GFX_BASE_GDA_1_VRAM ZORRO_ID(GFX_BASE, 0x00, 0) +#define ZORRO_PROD_GFX_BASE_GDA_1 ZORRO_ID(GFX_BASE, 0x01, 0) + +#define ZORRO_MANUF_ROCTEC 0x0860 +#define ZORRO_PROD_ROCTEC_RH_800C ZORRO_ID(ROCTEC, 0x01, 0) +#define ZORRO_PROD_ROCTEC_RH_800C_RAM ZORRO_ID(ROCTEC, 0x01, 0) + +#define ZORRO_MANUF_KATO 0x0861 +#define ZORRO_PROD_KATO_MELODY ZORRO_ID(KATO, 0x80, 0) +/* ID clash!! */ +#define ZORRO_MANUF_HELFRICH_1 0x0861 +#define ZORRO_PROD_HELFRICH_RAINBOW_II ZORRO_ID(HELFRICH_1, 0x20, 0) +#define ZORRO_PROD_HELFRICH_RAINBOW_III ZORRO_ID(HELFRICH_1, 0x21, 0) + +#define ZORRO_MANUF_ATLANTIS 0x0862 + +#define ZORRO_MANUF_PROTAR 0x0864 + +#define ZORRO_MANUF_ACS 0x0865 + +#define ZORRO_MANUF_SOFTWARE_RESULTS_ENTERPRISES 0x0866 +#define ZORRO_PROD_SOFTWARE_RESULTS_ENTERPRISES_GOLDEN_GATE_2_BUS_PLUS ZORRO_ID(SOFTWARE_RESULTS_ENTERPRISES, 0x01, 0) + +#define ZORRO_MANUF_MASOBOSHI 0x086D +#define ZORRO_PROD_MASOBOSHI_MASTER_CARD_SC201 ZORRO_ID(MASOBOSHI, 0x03, 0) +#define ZORRO_PROD_MASOBOSHI_MASTER_CARD_MC702 ZORRO_ID(MASOBOSHI, 0x04, 0) +#define ZORRO_PROD_MASOBOSHI_MVD_819 ZORRO_ID(MASOBOSHI, 0x07, 0) + +#define ZORRO_MANUF_MAINHATTAN_DATA 0x086F +#define ZORRO_PROD_MAINHATTAN_DATA_IDE ZORRO_ID(MAINHATTAN_DATA, 0x01, 0) + +#define ZORRO_MANUF_VILLAGE_TRONIC 0x0877 +#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_RAM ZORRO_ID(VILLAGE_TRONIC, 0x01, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_REG ZORRO_ID(VILLAGE_TRONIC, 0x02, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_16M_PROTOTYPE ZORRO_ID(VILLAGE_TRONIC, 0x03, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM ZORRO_ID(VILLAGE_TRONIC, 0x0B, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG ZORRO_ID(VILLAGE_TRONIC, 0x0C, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_SEGMENTED_MODE ZORRO_ID(VILLAGE_TRONIC, 0x0D, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG ZORRO_ID(VILLAGE_TRONIC, 0x17, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 ZORRO_ID(VILLAGE_TRONIC, 0x18, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE ZORRO_ID(VILLAGE_TRONIC, 0xC9, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2 ZORRO_ID(VILLAGE_TRONIC, 0xCA, 0) + +#define ZORRO_MANUF_UTILITIES_UNLIMITED 0x087B +#define ZORRO_PROD_UTILITIES_UNLIMITED_EMPLANT_DELUXE ZORRO_ID(UTILITIES_UNLIMITED, 0x15, 0) +#define ZORRO_PROD_UTILITIES_UNLIMITED_EMPLANT_DELUXE2 ZORRO_ID(UTILITIES_UNLIMITED, 0x20, 0) + +#define ZORRO_MANUF_AMITRIX 0x0880 +#define ZORRO_PROD_AMITRIX_MULTI_IO ZORRO_ID(AMITRIX, 0x01, 0) +#define ZORRO_PROD_AMITRIX_CD_RAM ZORRO_ID(AMITRIX, 0x02, 0) + +#define ZORRO_MANUF_ARMAX 0x0885 +#define ZORRO_PROD_ARMAX_OMNIBUS ZORRO_ID(ARMAX, 0x00, 0) + +#define ZORRO_MANUF_ZEUS 0x088D +#define ZORRO_PROD_ZEUS_SPIDER ZORRO_ID(ZEUS, 0x04, 0) + +#define ZORRO_MANUF_NEWTEK 0x088F +#define ZORRO_PROD_NEWTEK_VIDEOTOASTER ZORRO_ID(NEWTEK, 0x00, 0) + +#define ZORRO_MANUF_M_TECH_GERMANY 0x0890 +#define ZORRO_PROD_MTEC_AT500_2 ZORRO_ID(M_TECH_GERMANY, 0x01, 0) +#define ZORRO_PROD_MTEC_68030 ZORRO_ID(M_TECH_GERMANY, 0x03, 0) +#define ZORRO_PROD_MTEC_68020I ZORRO_ID(M_TECH_GERMANY, 0x06, 0) +#define ZORRO_PROD_MTEC_A1200_T68030_RTC ZORRO_ID(M_TECH_GERMANY, 0x20, 0) +#define ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530 ZORRO_ID(M_TECH_GERMANY, 0x21, 0) +#define ZORRO_PROD_MTEC_8_MB_RAM ZORRO_ID(M_TECH_GERMANY, 0x22, 0) +#define ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE ZORRO_ID(M_TECH_GERMANY, 0x24, 0) + +#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_4 0x0891 +#define ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM ZORRO_ID(GREAT_VALLEY_PRODUCTS_4, 0x01, 0) +#define ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG ZORRO_ID(GREAT_VALLEY_PRODUCTS_4, 0x02, 0) + +#define ZORRO_MANUF_APOLLO_1 0x0892 +#define ZORRO_PROD_APOLLO_A1200 ZORRO_ID(APOLLO_1, 0x01, 0) + +#define ZORRO_MANUF_HELFRICH_2 0x0893 +#define ZORRO_PROD_HELFRICH_PICCOLO_RAM ZORRO_ID(HELFRICH_2, 0x05, 0) +#define ZORRO_PROD_HELFRICH_PICCOLO_REG ZORRO_ID(HELFRICH_2, 0x06, 0) +#define ZORRO_PROD_HELFRICH_PEGGY_PLUS_MPEG ZORRO_ID(HELFRICH_2, 0x07, 0) +#define ZORRO_PROD_HELFRICH_VIDEOCRUNCHER ZORRO_ID(HELFRICH_2, 0x08, 0) +#define ZORRO_PROD_HELFRICH_SD64_RAM ZORRO_ID(HELFRICH_2, 0x0A, 0) +#define ZORRO_PROD_HELFRICH_SD64_REG ZORRO_ID(HELFRICH_2, 0x0B, 0) + +#define ZORRO_MANUF_MACROSYSTEMS_USA 0x089B +#define ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx ZORRO_ID(MACROSYSTEMS_USA, 0x13, 0) + +#define ZORRO_MANUF_ELBOX_COMPUTER 0x089E +#define ZORRO_PROD_ELBOX_COMPUTER_1200_4 ZORRO_ID(ELBOX_COMPUTER, 0x06, 0) + +#define ZORRO_MANUF_HARMS_PROFESSIONAL 0x0A00 +#define ZORRO_PROD_HARMS_PROFESSIONAL_030_PLUS ZORRO_ID(HARMS_PROFESSIONAL, 0x10, 0) +#define ZORRO_PROD_HARMS_PROFESSIONAL_3500 ZORRO_ID(HARMS_PROFESSIONAL, 0xD0, 0) + +#define ZORRO_MANUF_MICRONIK 0x0A50 +#define ZORRO_PROD_MICRONIK_RCA_120 ZORRO_ID(MICRONIK, 0x0A, 0) + +#define ZORRO_MANUF_MICRONIK2 0x0F0F +#define ZORRO_PROD_MICRONIK2_Z3I ZORRO_ID(MICRONIK2, 0x01, 0) + +#define ZORRO_MANUF_MEGAMICRO 0x1000 +#define ZORRO_PROD_MEGAMICRO_SCRAM_500 ZORRO_ID(MEGAMICRO, 0x03, 0) +#define ZORRO_PROD_MEGAMICRO_SCRAM_500_RAM ZORRO_ID(MEGAMICRO, 0x04, 0) + +#define ZORRO_MANUF_IMTRONICS_2 0x1028 +#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_3 ZORRO_ID(IMTRONICS_2, 0x39, 0) +#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_4 ZORRO_ID(IMTRONICS_2, 0x57, 0) + +/* unofficial ID */ +#define ZORRO_MANUF_INDIVIDUAL_COMPUTERS 0x1212 +#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x00, 0) +#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x2A, 0) + +#define ZORRO_MANUF_KUPKE_3 0x1248 +#define ZORRO_PROD_KUPKE_GOLEM_HD_3000 ZORRO_ID(KUPKE_3, 0x01, 0) + +#define ZORRO_MANUF_ITH 0x1388 +#define ZORRO_PROD_ITH_ISDN_MASTER_II ZORRO_ID(ITH, 0x01, 0) + +#define ZORRO_MANUF_VMC 0x1389 +#define ZORRO_PROD_VMC_ISDN_BLASTER_Z2 ZORRO_ID(VMC, 0x01, 0) +#define ZORRO_PROD_VMC_HYPERCOM_4 ZORRO_ID(VMC, 0x02, 0) + +#define ZORRO_MANUF_INFORMATION 0x157C +#define ZORRO_PROD_INFORMATION_ISDN_ENGINE_I ZORRO_ID(INFORMATION, 0x64, 0) + +#define ZORRO_MANUF_VORTEX 0x2017 +#define ZORRO_PROD_VORTEX_GOLDEN_GATE_80386SX ZORRO_ID(VORTEX, 0x07, 0) +#define ZORRO_PROD_VORTEX_GOLDEN_GATE_RAM ZORRO_ID(VORTEX, 0x08, 0) +#define ZORRO_PROD_VORTEX_GOLDEN_GATE_80486 ZORRO_ID(VORTEX, 0x09, 0) + +#define ZORRO_MANUF_EXPANSION_SYSTEMS 0x2062 +#define ZORRO_PROD_EXPANSION_SYSTEMS_DATAFLYER_4000SX ZORRO_ID(EXPANSION_SYSTEMS, 0x01, 0) +#define ZORRO_PROD_EXPANSION_SYSTEMS_DATAFLYER_4000SX_RAM ZORRO_ID(EXPANSION_SYSTEMS, 0x02, 0) + +#define ZORRO_MANUF_READYSOFT 0x2100 +#define ZORRO_PROD_READYSOFT_AMAX_II_IV ZORRO_ID(READYSOFT, 0x01, 0) + +#define ZORRO_MANUF_PHASE5 0x2140 +#define ZORRO_PROD_PHASE5_BLIZZARD_RAM ZORRO_ID(PHASE5, 0x01, 0) +#define ZORRO_PROD_PHASE5_BLIZZARD ZORRO_ID(PHASE5, 0x02, 0) +#define ZORRO_PROD_PHASE5_BLIZZARD_1220_IV ZORRO_ID(PHASE5, 0x06, 0) +#define ZORRO_PROD_PHASE5_FASTLANE_Z3_RAM ZORRO_ID(PHASE5, 0x0A, 0) +#define ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060 ZORRO_ID(PHASE5, 0x0B, 0) +#define ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM ZORRO_ID(PHASE5, 0x0C, 0) +#define ZORRO_PROD_PHASE5_BLIZZARD_1230 ZORRO_ID(PHASE5, 0x0D, 0) +#define ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260 ZORRO_ID(PHASE5, 0x11, 0) +#define ZORRO_PROD_PHASE5_BLIZZARD_2060 ZORRO_ID(PHASE5, 0x18, 0) +#define ZORRO_PROD_PHASE5_CYBERSTORM_MK_II ZORRO_ID(PHASE5, 0x19, 0) +#define ZORRO_PROD_PHASE5_CYBERVISION64 ZORRO_ID(PHASE5, 0x22, 0) +#define ZORRO_PROD_PHASE5_CYBERVISION64_3D_PROTOTYPE ZORRO_ID(PHASE5, 0x32, 0) +#define ZORRO_PROD_PHASE5_CYBERVISION64_3D ZORRO_ID(PHASE5, 0x43, 0) +#define ZORRO_PROD_PHASE5_CYBERSTORM_MK_III ZORRO_ID(PHASE5, 0x64, 0) +#define ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS ZORRO_ID(PHASE5, 0x6e, 0) + +#define ZORRO_MANUF_DPS 0x2169 +#define ZORRO_PROD_DPS_PERSONAL_ANIMATION_RECORDER ZORRO_ID(DPS, 0x01, 0) + +#define ZORRO_MANUF_APOLLO_2 0x2200 +#define ZORRO_PROD_APOLLO_A620_68020_1 ZORRO_ID(APOLLO_2, 0x00, 0) +#define ZORRO_PROD_APOLLO_A620_68020_2 ZORRO_ID(APOLLO_2, 0x01, 0) + +#define ZORRO_MANUF_APOLLO_3 0x2222 +#define ZORRO_PROD_APOLLO_AT_APOLLO ZORRO_ID(APOLLO_3, 0x22, 0) +#define ZORRO_PROD_APOLLO_1230_1240_1260_2030_4040_4060 ZORRO_ID(APOLLO_3, 0x23, 0) + +#define ZORRO_MANUF_PETSOFF_LP 0x38A5 +#define ZORRO_PROD_PETSOFF_LP_DELFINA ZORRO_ID(PETSOFF_LP, 0x00, 0) +#define ZORRO_PROD_PETSOFF_LP_DELFINA_LITE ZORRO_ID(PETSOFF_LP, 0x01, 0) + +#define ZORRO_MANUF_UWE_GERLACH 0x3FF7 +#define ZORRO_PROD_UWE_GERLACH_RAM_ROM ZORRO_ID(UWE_GERLACH, 0xd4, 0) + +#define ZORRO_MANUF_ACT 0x4231 +#define ZORRO_PROD_ACT_PRELUDE ZORRO_ID(ACT, 0x01, 0) + +#define ZORRO_MANUF_MACROSYSTEMS_GERMANY 0x4754 +#define ZORRO_PROD_MACROSYSTEMS_MAESTRO ZORRO_ID(MACROSYSTEMS_GERMANY, 0x03, 0) +#define ZORRO_PROD_MACROSYSTEMS_VLAB ZORRO_ID(MACROSYSTEMS_GERMANY, 0x04, 0) +#define ZORRO_PROD_MACROSYSTEMS_MAESTRO_PRO ZORRO_ID(MACROSYSTEMS_GERMANY, 0x05, 0) +#define ZORRO_PROD_MACROSYSTEMS_RETINA ZORRO_ID(MACROSYSTEMS_GERMANY, 0x06, 0) +#define ZORRO_PROD_MACROSYSTEMS_MULTI_EVOLUTION ZORRO_ID(MACROSYSTEMS_GERMANY, 0x08, 0) +#define ZORRO_PROD_MACROSYSTEMS_TOCCATA ZORRO_ID(MACROSYSTEMS_GERMANY, 0x0C, 0) +#define ZORRO_PROD_MACROSYSTEMS_RETINA_Z3 ZORRO_ID(MACROSYSTEMS_GERMANY, 0x10, 0) +#define ZORRO_PROD_MACROSYSTEMS_VLAB_MOTION ZORRO_ID(MACROSYSTEMS_GERMANY, 0x12, 0) +#define ZORRO_PROD_MACROSYSTEMS_ALTAIS ZORRO_ID(MACROSYSTEMS_GERMANY, 0x13, 0) +#define ZORRO_PROD_MACROSYSTEMS_FALCON_040 ZORRO_ID(MACROSYSTEMS_GERMANY, 0xFD, 0) + +#define ZORRO_MANUF_COMBITEC 0x6766 + +#define ZORRO_MANUF_SKI_PERIPHERALS 0x8000 +#define ZORRO_PROD_SKI_PERIPHERALS_MAST_FIREBALL ZORRO_ID(SKI_PERIPHERALS, 0x08, 0) +#define ZORRO_PROD_SKI_PERIPHERALS_SCSI_DUAL_SERIAL ZORRO_ID(SKI_PERIPHERALS, 0x80, 0) + +#define ZORRO_MANUF_REIS_WARE_2 0xA9AD +#define ZORRO_PROD_REIS_WARE_SCAN_KING ZORRO_ID(REIS_WARE_2, 0x11, 0) + +#define ZORRO_MANUF_CAMERON 0xAA01 +#define ZORRO_PROD_CAMERON_PERSONAL_A4 ZORRO_ID(CAMERON, 0x10, 0) + +#define ZORRO_MANUF_REIS_WARE 0xAA11 +#define ZORRO_PROD_REIS_WARE_HANDYSCANNER ZORRO_ID(REIS_WARE, 0x11, 0) + +#define ZORRO_MANUF_PHOENIX_2 0xB5A8 +#define ZORRO_PROD_PHOENIX_ST506_2 ZORRO_ID(PHOENIX_2, 0x21, 0) +#define ZORRO_PROD_PHOENIX_SCSI_2 ZORRO_ID(PHOENIX_2, 0x22, 0) +#define ZORRO_PROD_PHOENIX_RAM_2 ZORRO_ID(PHOENIX_2, 0xBE, 0) + +#define ZORRO_MANUF_COMBITEC_2 0xC008 +#define ZORRO_PROD_COMBITEC_HD ZORRO_ID(COMBITEC_2, 0x2A, 0) +#define ZORRO_PROD_COMBITEC_SRAM ZORRO_ID(COMBITEC_2, 0x2B, 0) + + + /* + * Test and illegal Manufacturer IDs. + */ + +#define ZORRO_MANUF_HACKER 0x07DB +#define ZORRO_PROD_GENERAL_PROTOTYPE ZORRO_ID(HACKER, 0x00, 0) +#define ZORRO_PROD_HACKER_SCSI ZORRO_ID(HACKER, 0x01, 0) +#define ZORRO_PROD_RESOURCE_MANAGEMENT_FORCE_QUICKNET_QN2000 ZORRO_ID(HACKER, 0x02, 0) +#define ZORRO_PROD_VECTOR_CONNECTION_2 ZORRO_ID(HACKER, 0xE0, 0) +#define ZORRO_PROD_VECTOR_CONNECTION_3 ZORRO_ID(HACKER, 0xE1, 0) +#define ZORRO_PROD_VECTOR_CONNECTION_4 ZORRO_ID(HACKER, 0xE2, 0) +#define ZORRO_PROD_VECTOR_CONNECTION_5 ZORRO_ID(HACKER, 0xE3, 0) diff --git a/include/net/atalkcall.h b/include/net/atalkcall.h deleted file mode 100644 index 726e33cd9..000000000 --- a/include/net/atalkcall.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void atalk_proto_init(struct net_proto *pro); diff --git a/include/net/ax25.h b/include/net/ax25.h index f0c547d0b..50d4aa889 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -253,8 +253,6 @@ extern void ax25_ds_heartbeat_expiry(ax25_cb *); extern void ax25_ds_t3timer_expiry(ax25_cb *); extern void ax25_ds_idletimer_expiry(ax25_cb *); -#include <net/ax25call.h> - /* ax25_iface.c */ extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *)); extern void ax25_protocol_release(unsigned int); diff --git a/include/net/ax25call.h b/include/net/ax25call.h deleted file mode 100644 index 68b8a70c0..000000000 --- a/include/net/ax25call.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void ax25_proto_init(struct net_proto *pro); diff --git a/include/net/decnet_call.h b/include/net/decnet_call.h deleted file mode 100644 index 90a30561e..000000000 --- a/include/net/decnet_call.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void decnet_proto_init(struct net_proto *pro); diff --git a/include/net/ipx.h b/include/net/ipx.h index 667098922..84e7cdb1d 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -41,8 +41,6 @@ struct ipxhdr ipx_address ipx_source __attribute__ ((packed)); }; -#include <net/ipxcall.h> - typedef struct ipx_interface { /* IPX address */ __u32 if_netnum; diff --git a/include/net/ipxcall.h b/include/net/ipxcall.h deleted file mode 100644 index eb5bd2bd2..000000000 --- a/include/net/ipxcall.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void ipx_proto_init(struct net_proto *pro); diff --git a/include/net/lapbcall.h b/include/net/lapbcall.h deleted file mode 100644 index 825e7f2c7..000000000 --- a/include/net/lapbcall.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void lapb_proto_init(struct net_proto *pro); diff --git a/include/net/llccall.h b/include/net/llccall.h deleted file mode 100644 index 07013ba31..000000000 --- a/include/net/llccall.h +++ /dev/null @@ -1,3 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void llc_init(struct net_proto *pro); - diff --git a/include/net/netbeuicall.h b/include/net/netbeuicall.h deleted file mode 100644 index 5176f82bf..000000000 --- a/include/net/netbeuicall.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void netbeui_proto_init(struct net_proto *pro); diff --git a/include/net/netrom.h b/include/net/netrom.h index 11aefe5fa..21c9f8b86 100644 --- a/include/net/netrom.h +++ b/include/net/netrom.h @@ -121,8 +121,6 @@ extern void nr_destroy_socket(struct sock *); extern int nr_rx_ip(struct sk_buff *, struct net_device *); extern int nr_init(struct net_device *); -#include <net/nrcall.h> - /* nr_in.c */ extern int nr_process_rx_frame(struct sock *, struct sk_buff *); diff --git a/include/net/nrcall.h b/include/net/nrcall.h deleted file mode 100644 index 09ee699d8..000000000 --- a/include/net/nrcall.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void nr_proto_init(struct net_proto *pro); diff --git a/include/net/p8022call.h b/include/net/p8022call.h deleted file mode 100644 index 14f0c2cee..000000000 --- a/include/net/p8022call.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of Space.c simpler */ -extern void p8022_proto_init(struct net_proto *); diff --git a/include/net/psnapcall.h b/include/net/psnapcall.h deleted file mode 100644 index 9da5763c5..000000000 --- a/include/net/psnapcall.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of Space.c simpler */ -extern void snap_proto_init(struct net_proto *); diff --git a/include/net/rose.h b/include/net/rose.h index da19fb64f..f1f893e27 100644 --- a/include/net/rose.h +++ b/include/net/rose.h @@ -163,8 +163,6 @@ extern void rose_destroy_socket(struct sock *); extern int rose_rx_ip(struct sk_buff *, struct net_device *); extern int rose_init(struct net_device *); -#include <net/rosecall.h> - /* rose_in.c */ extern int rose_process_rx_frame(struct sock *, struct sk_buff *); diff --git a/include/net/rosecall.h b/include/net/rosecall.h deleted file mode 100644 index 5bbe69cce..000000000 --- a/include/net/rosecall.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void rose_proto_init(struct net_proto *pro); diff --git a/include/net/sock.h b/include/net/sock.h index e3527b2f3..75aae4d1b 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -202,7 +202,8 @@ struct inet_opt unsigned char hdrincl; /* Include headers ? */ __u8 mc_ttl; /* Multicasting TTL */ __u8 mc_loop; /* Loopback */ - __u8 recverr; + unsigned recverr : 1, + freebind : 1; __u8 pmtudisc; int mc_index; /* Multicast device index */ __u32 mc_addr; diff --git a/include/net/spxcall.h b/include/net/spxcall.h deleted file mode 100644 index 0461fbbe1..000000000 --- a/include/net/spxcall.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void spx_proto_init(struct net_proto *pro); diff --git a/include/net/tcp.h b/include/net/tcp.h index 3fdb1e97a..dd8e74ca1 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -42,21 +42,9 @@ struct tcp_ehash_bucket { struct sock *chain; } __attribute__((__aligned__(8))); -extern int tcp_ehash_size; -extern struct tcp_ehash_bucket *tcp_ehash; - /* This is for listening sockets, thus all sockets which possess wildcards. */ #define TCP_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */ -/* tcp_ipv4.c: These need to be shared by v4 and v6 because the lookup - * and hashing code needs to work with different AF's yet - * the port space is shared. - */ -extern struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE]; -extern rwlock_t tcp_lhash_lock; -extern atomic_t tcp_lhash_users; -extern wait_queue_head_t tcp_lhash_wait; - /* There are a few simple rules, which allow for local port reuse by * an application. In essence: * @@ -101,9 +89,53 @@ struct tcp_bind_hashbucket { struct tcp_bind_bucket *chain; }; -extern struct tcp_bind_hashbucket *tcp_bhash; -extern int tcp_bhash_size; -extern spinlock_t tcp_portalloc_lock; +extern struct tcp_hashinfo { + /* This is for sockets with full identity only. Sockets here will + * always be without wildcards and will have the following invariant: + * + * TCP_ESTABLISHED <= sk->state < TCP_CLOSE + * + * First half of the table is for sockets not in TIME_WAIT, second half + * is for TIME_WAIT sockets only. + */ + struct tcp_ehash_bucket *__tcp_ehash; + + /* Ok, let's try this, I give up, we do need a local binding + * TCP hash as well as the others for fast bind/connect. + */ + struct tcp_bind_hashbucket *__tcp_bhash; + + int __tcp_bhash_size; + int __tcp_ehash_size; + + /* All sockets in TCP_LISTEN state will be in here. This is the only + * table where wildcard'd TCP sockets can exist. Hash function here + * is just local port number. + */ + struct sock *__tcp_listening_hash[TCP_LHTABLE_SIZE]; + + /* All the above members are written once at bootup and + * never written again _or_ are predominantly read-access. + * + * Now align to a new cache line as all the following members + * are often dirty. + */ + rwlock_t __tcp_lhash_lock + __attribute__((__aligned__(SMP_CACHE_BYTES))); + atomic_t __tcp_lhash_users; + wait_queue_head_t __tcp_lhash_wait; + spinlock_t __tcp_portalloc_lock; +} tcp_hashinfo; + +#define tcp_ehash (tcp_hashinfo.__tcp_ehash) +#define tcp_bhash (tcp_hashinfo.__tcp_bhash) +#define tcp_ehash_size (tcp_hashinfo.__tcp_ehash_size) +#define tcp_bhash_size (tcp_hashinfo.__tcp_bhash_size) +#define tcp_listening_hash (tcp_hashinfo.__tcp_listening_hash) +#define tcp_lhash_lock (tcp_hashinfo.__tcp_lhash_lock) +#define tcp_lhash_users (tcp_hashinfo.__tcp_lhash_users) +#define tcp_lhash_wait (tcp_hashinfo.__tcp_lhash_wait) +#define tcp_portalloc_lock (tcp_hashinfo.__tcp_portalloc_lock) extern kmem_cache_t *tcp_bucket_cachep; extern struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head, diff --git a/include/net/x25.h b/include/net/x25.h index fb8346f81..fc3d83ee4 100644 --- a/include/net/x25.h +++ b/include/net/x25.h @@ -154,8 +154,6 @@ extern void x25_destroy_socket(struct sock *); extern int x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int); extern void x25_kill_by_neigh(struct x25_neigh *); -#include <net/x25call.h> - /* x25_dev.c */ extern void x25_send_frame(struct sk_buff *, struct x25_neigh *); extern int x25_lapb_receive_frame(struct sk_buff *, struct net_device *, struct packet_type *); diff --git a/include/net/x25call.h b/include/net/x25call.h deleted file mode 100644 index 7c478a1d9..000000000 --- a/include/net/x25call.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Separate to keep compilation of protocols.c simpler */ -extern void x25_proto_init(struct net_proto *pro); diff --git a/include/pcmcia/version.h b/include/pcmcia/version.h index 70f3d8a48..eb88263fc 100644 --- a/include/pcmcia/version.h +++ b/include/pcmcia/version.h @@ -1,4 +1,4 @@ -/* version.h 1.92 2000/07/21 18:26:56 (David Hinds) */ +/* version.h 1.94 2000/10/03 17:55:48 (David Hinds) */ -#define CS_RELEASE "3.1.20" -#define CS_RELEASE_CODE 0x3115 +#define CS_RELEASE "3.1.22" +#define CS_RELEASE_CODE 0x3116 diff --git a/init/main.c b/init/main.c index 67730c994..1505510e7 100644 --- a/init/main.c +++ b/init/main.c @@ -73,8 +73,8 @@ extern void nubus_init(void); * To avoid associated bogus bug reports, we flatly refuse to compile * with a gcc that is known to be too old from the very beginning. */ -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -#error sorry, your GCC is too old. It builds incorrect kernels. +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91) +#error Sorry, your GCC is too old. It builds incorrect kernels. #endif extern char _stext, _etext; @@ -41,7 +41,7 @@ * get the semaphore and if this process wants to reduce some * semaphore value we simply wake it up without doing the * operation. So it has to try to get it later. Thus e.g. the - * running process may reaquire the semaphore during the current + * running process may reacquire the semaphore during the current * time slice. If it only waits for zero or increases the semaphore, * we do the operation in advance and wake it up. * 2) It did not wake up all zero waiting processes. We try to do diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 2a8882dbc..b8eb6b4f0 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -246,7 +246,6 @@ EXPORT_SYMBOL(generic_read_dir); EXPORT_SYMBOL(__pollwait); EXPORT_SYMBOL(poll_freewait); EXPORT_SYMBOL(ROOT_DEV); -EXPORT_SYMBOL(__find_get_page); EXPORT_SYMBOL(__find_lock_page); EXPORT_SYMBOL(grab_cache_page); EXPORT_SYMBOL(read_cache_page); diff --git a/kernel/module.c b/kernel/module.c index 5e5fbfe1b..15efa305c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -28,22 +28,13 @@ extern const struct exception_table_entry __stop___ex_table[]; static struct module kernel_module = { - sizeof(struct module), /* size_of_struct */ - NULL, /* next */ - "", /* name */ - 0, /* size */ - {ATOMIC_INIT(1)}, /* usecount */ - MOD_RUNNING, /* flags */ - 0, /* nsyms -- to filled in in init_modules */ - 0, /* ndeps */ - __start___ksymtab, /* syms */ - NULL, /* deps */ - NULL, /* refs */ - NULL, /* init */ - NULL, /* cleanup */ - __start___ex_table, /* ex_table_start */ - __stop___ex_table, /* ex_table_end */ - /* Rest are NULL */ + size_of_struct: sizeof(struct module), + name: "", + uc: {ATOMIC_INIT(1)}, + flags: MOD_RUNNING, + syms: __start___ksymtab, + ex_table_start: __start___ex_table, + ex_table_end: __stop___ex_table }; struct module *module_list = &kernel_module; diff --git a/kernel/panic.c b/kernel/panic.c index d6e37fbf7..ac246f745 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -22,7 +22,7 @@ extern void unblank_console(void); int panic_timeout; -struct notifier_block *panic_notifier_list = NULL; +struct notifier_block *panic_notifier_list; static int __init panic_setup(char *str) { diff --git a/kernel/printk.c b/kernel/printk.c index ff6c727ab..72e27f35a 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -45,7 +45,7 @@ int default_console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; spinlock_t console_lock = SPIN_LOCK_UNLOCKED; -struct console *console_drivers = NULL; +struct console *console_drivers; static char log_buf[LOG_BUF_LEN]; static unsigned long log_start; static unsigned long logged_chars; diff --git a/kernel/sched.c b/kernel/sched.c index 361b72491..927bf47e7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -223,16 +223,20 @@ static void reschedule_idle(struct task_struct * p) best_cpu = p->processor; if (can_schedule(p, best_cpu)) { tsk = idle_task(best_cpu); - if (cpu_curr(best_cpu) == tsk) - goto send_now_idle; - - /* - * Maybe this process has enough priority to preempt - * its preferred CPU. (this is a shortcut): - */ - tsk = cpu_curr(best_cpu); - if (preemption_goodness(tsk, p, best_cpu) > 0) - goto preempt_now; + if (cpu_curr(best_cpu) == tsk) { + int need_resched; +send_now_idle: + /* + * If need_resched == -1 then we can skip sending + * the IPI altogether, tsk->need_resched is + * actively watched by the idle thread. + */ + need_resched = tsk->need_resched; + tsk->need_resched = 1; + if ((best_cpu != this_cpu) && !need_resched) + smp_send_reschedule(best_cpu); + return; + } } /* @@ -276,31 +280,13 @@ static void reschedule_idle(struct task_struct * p) if (tsk) { if (oldest_idle != -1ULL) goto send_now_idle; - goto preempt_now; + tsk->need_resched = 1; + if (tsk->processor != this_cpu) + smp_send_reschedule(tsk->processor); } - return; -send_now_idle: - /* - * If need_resched == -1 then we can skip sending the IPI - * altogether, tsk->need_resched is actively watched by the - * idle thread. - */ - if ((tsk->processor != current->processor) && !tsk->need_resched) - smp_send_reschedule(tsk->processor); - tsk->need_resched = 1; - return; -preempt_now: - tsk->need_resched = 1; - /* - * the APIC stuff can go outside of the lock because - * it uses no task information, only CPU#. - */ - if (tsk->processor != this_cpu) - smp_send_reschedule(tsk->processor); - return; #else /* UP */ int this_cpu = smp_processor_id(); struct task_struct *tsk; @@ -444,37 +430,53 @@ signed long schedule_timeout(signed long timeout) static inline void __schedule_tail(struct task_struct *prev) { #ifdef CONFIG_SMP - int yield; - unsigned long flags; + int policy; /* - * fast path falls through. We have to take the runqueue lock - * unconditionally to make sure that the test of prev->state - * and setting has_cpu is atomic wrt. interrupts. It's not - * a big problem in the common case because we recently took - * the runqueue lock so it's likely to be in this processor's - * cache. + * fast path falls through. We have to clear has_cpu before + * checking prev->state to avoid a wakeup race - thus we + * also have to protect against the task exiting early. */ - spin_lock_irqsave(&runqueue_lock, flags); - yield = prev->policy & SCHED_YIELD; - prev->policy &= ~SCHED_YIELD; + task_lock(prev); + policy = prev->policy; + prev->policy = policy & ~SCHED_YIELD; prev->has_cpu = 0; + wmb(); if (prev->state == TASK_RUNNING) - goto running_again; + goto needs_resched; + out_unlock: - spin_unlock_irqrestore(&runqueue_lock, flags); + task_unlock(prev); return; /* * Slow path - we 'push' the previous process and * reschedule_idle() will attempt to find a new * processor for it. (but it might preempt the - * current process as well.) + * current process as well.) We must take the runqueue + * lock and re-check prev->state to be correct. It might + * still happen that this process has a preemption + * 'in progress' already - but this is not a problem and + * might happen in other circumstances as well. */ -running_again: - if ((prev != idle_task(smp_processor_id())) && !yield) - reschedule_idle(prev); - goto out_unlock; +needs_resched: + { + unsigned long flags; + + /* + * Avoid taking the runqueue lock in cases where + * no preemption-check is necessery: + */ + if ((prev == idle_task(smp_processor_id())) || + (policy & SCHED_YIELD)) + goto out_unlock; + + spin_lock_irqsave(&runqueue_lock, flags); + if (prev->state == TASK_RUNNING) + reschedule_idle(prev); + spin_unlock_irqrestore(&runqueue_lock, flags); + goto out_unlock; + } #else prev->policy &= ~SCHED_YIELD; #endif /* CONFIG_SMP */ @@ -588,19 +590,13 @@ still_running_back: #ifdef CONFIG_SMP /* - * maintain the per-process 'average timeslice' value. + * maintain the per-process 'last schedule' value. * (this has to be recalculated even if we reschedule to * the same process) Currently this is only used on SMP, * and it's approximate, so we do not have to maintain * it while holding the runqueue spinlock. */ - { - cycles_t t, this_slice; - - t = get_cycles(); - this_slice = t - sched_data->last_schedule; - sched_data->last_schedule = t; - } + sched_data->last_schedule = get_cycles(); /* * We drop the scheduler lock early (it's a global spinlock), @@ -705,7 +701,7 @@ static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, unsigned long flags; int best_cpu, irq; - if (!q) + if (!q || !waitqueue_active(q)) goto out; best_cpu = smp_processor_id(); @@ -759,16 +755,13 @@ static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, } } } - if (best_exclusive) - best_exclusive->state = TASK_RUNNING; - wq_write_unlock_irqrestore(&q->lock, flags); - if (best_exclusive) { if (sync) wake_up_process_synchronous(best_exclusive); else wake_up_process(best_exclusive); } + wq_write_unlock_irqrestore(&q->lock, flags); out: return; } @@ -1029,12 +1022,35 @@ out_unlock: asmlinkage long sys_sched_yield(void) { /* - * This process can only be rescheduled by us, - * so this is safe without any locking. + * Trick. sched_yield() first counts the number of truly + * 'pending' runnable processes, then returns if it's + * only the current processes. (This test does not have + * to be atomic.) In threaded applications this optimization + * gets triggered quite often. */ - if (current->policy == SCHED_OTHER) - current->policy |= SCHED_YIELD; - current->need_resched = 1; + + int nr_pending = nr_running; + +#if CONFIG_SMP + int i; + + // Substract non-idle processes running on other CPUs. + for (i = 0; i < smp_num_cpus; i++) + if (aligned_data[i].schedule_data.curr != idle_task(i)) + nr_pending--; +#else + // on UP this process is on the runqueue as well + nr_pending--; +#endif + if (nr_pending) { + /* + * This process can only be rescheduled by us, + * so this is safe without any locking. + */ + if (current->policy == SCHED_OTHER) + current->policy |= SCHED_YIELD; + current->need_resched = 1; + } return 0; } diff --git a/kernel/signal.c b/kernel/signal.c index 4e6a4d909..c6ec0cb7b 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -459,7 +459,7 @@ static int send_signal(int sig, struct siginfo *info, struct sigpending *signals * NOTE! we rely on the previous spin_lock to * lock interrupts for us! We can only be called with * "sigmask_lock" held, and the local interrupt must - * have been disabled when that got aquired! + * have been disabled when that got acquired! * * No need to set need_resched since signal event passing * goes through ->blocked diff --git a/kernel/sys.c b/kernel/sys.c index 87ee4770c..ded9c6328 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -47,7 +47,7 @@ int C_A_D = 1; * and the like. */ -static struct notifier_block *reboot_notifier_list = NULL; +static struct notifier_block *reboot_notifier_list; rwlock_t notifier_lock = RW_LOCK_UNLOCKED; /** diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c320027fa..70da2a029 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1217,78 +1217,6 @@ int sysctl_jiffies(ctl_table *table, int *name, int nlen, return 1; } -int do_string ( - void *oldval, size_t *oldlenp, void *newval, size_t newlen, - int rdwr, char *data, size_t max) -{ - int l = strlen(data) + 1; - if (newval && !rdwr) - return -EPERM; - if (newval && newlen >= max) - return -EINVAL; - if (oldval) { - int old_l; - if(get_user(old_l, oldlenp)) - return -EFAULT; - if (l > old_l) - return -ENOMEM; - if(put_user(l, oldlenp) || copy_to_user(oldval, data, l)) - return -EFAULT; - } - if (newval) { - if(copy_from_user(data, newval, newlen)) - return -EFAULT; - data[newlen] = 0; - } - return 0; -} - -int do_int ( - void *oldval, size_t *oldlenp, void *newval, size_t newlen, - int rdwr, int *data) -{ - if (newval && !rdwr) - return -EPERM; - if (newval && newlen != sizeof(int)) - return -EINVAL; - if (oldval) { - int old_l; - if(get_user(old_l, oldlenp)) - return -EFAULT; - if (old_l < sizeof(int)) - return -ENOMEM; - if(put_user(sizeof(int), oldlenp)||copy_to_user(oldval, data, sizeof(int))) - return -EFAULT; - } - if (newval) - if(copy_from_user(data, newval, sizeof(int))) - return -EFAULT; - return 0; -} - -int do_struct ( - void *oldval, size_t *oldlenp, void *newval, size_t newlen, - int rdwr, void *data, size_t len) -{ - if (newval && !rdwr) - return -EPERM; - if (newval && newlen != len) - return -EINVAL; - if (oldval) { - int old_l; - if(get_user(old_l, oldlenp)) - return -EFAULT; - if (old_l < len) - return -ENOMEM; - if(put_user(len, oldlenp) || copy_to_user(oldval, data, len)) - return -EFAULT; - } - if (newval) - if(copy_from_user(data, newval, len)) - return -EFAULT; - return 0; -} - #else /* CONFIG_SYSCTL */ diff --git a/kernel/time.c b/kernel/time.c index 843ac0cbb..ffad77ad6 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -34,7 +34,7 @@ * The timezone where the local system is located. Used as a default by some * programs who obtain this value by using gettimeofday. */ -struct timezone sys_tz = { 0, 0}; +struct timezone sys_tz; static void do_normal_gettime(struct timeval * tm) { @@ -218,7 +218,7 @@ long pps_errcnt; /* calibration errors */ long pps_stbcnt; /* stability limit exceeded */ /* hook for a loadable hardpps kernel module */ -void (*hardpps_ptr)(struct timeval *) = (void (*)(struct timeval *))0; +void (*hardpps_ptr)(struct timeval *); /* adjtimex mainly allows reading (and writing, if superuser) of * kernel time-keeping variables. used by xntpd. diff --git a/kernel/timer.c b/kernel/timer.c index 0dd0a7331..e67783a30 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -164,7 +164,7 @@ static inline void internal_add_timer(struct timer_list *timer) spinlock_t timerlist_lock = SPIN_LOCK_UNLOCKED; #ifdef CONFIG_SMP -volatile struct timer_list * volatile running_timer = NULL; +volatile struct timer_list * volatile running_timer; #define timer_enter(t) do { running_timer = t; mb(); } while (0) #define timer_exit() do { running_timer = NULL; } while (0) #define timer_is_running(t) (running_timer == t) diff --git a/kernel/user.c b/kernel/user.c index daae4dff4..d033c9659 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -17,11 +17,15 @@ * UID task count cache, to get fast user lookup in "alloc_uid" * when changing user ID's (ie setuid() and friends). */ -#define UIDHASH_SZ (256) +#define UIDHASH_BITS 8 +#define UIDHASH_SZ (1 << UIDHASH_BITS) +#define UIDHASH_MASK (UIDHASH_SZ - 1) +#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) ^ uid) & UIDHASH_MASK) +#define uidhashentry(uid) (uidhash_table + __uidhashfn(uid)) -static struct user_struct *uidhash[UIDHASH_SZ]; - -spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED; +static kmem_cache_t *uid_cachep; +static struct user_struct *uidhash_table[UIDHASH_SZ]; +static spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED; struct user_struct root_user = { __count: ATOMIC_INIT(1), @@ -29,49 +33,50 @@ struct user_struct root_user = { files: ATOMIC_INIT(0) }; -static kmem_cache_t *uid_cachep; - -#define uidhashfn(uid) (((uid >> 8) ^ uid) & (UIDHASH_SZ - 1)) - /* * These routines must be called with the uidhash spinlock held! */ -static inline void uid_hash_insert(struct user_struct *up, unsigned int hashent) +static inline void uid_hash_insert(struct user_struct *up, struct user_struct **hashent) { - if((up->next = uidhash[hashent]) != NULL) - uidhash[hashent]->pprev = &up->next; - up->pprev = &uidhash[hashent]; - uidhash[hashent] = up; + struct user_struct *next = *hashent; + + up->next = next; + if (next) + next->pprev = &up->next; + up->pprev = hashent; + *hashent = up; } static inline void uid_hash_remove(struct user_struct *up) { - if(up->next) - up->next->pprev = up->pprev; - *up->pprev = up->next; + struct user_struct *next = up->next; + struct user_struct **pprev = up->pprev; + + if (next) + next->pprev = pprev; + *pprev = next; } -static inline struct user_struct *uid_hash_find(unsigned short uid, unsigned int hashent) +static inline struct user_struct *uid_hash_find(uid_t uid, struct user_struct **hashent) { - struct user_struct *up, *next; + struct user_struct *next; - next = uidhash[hashent]; + next = *hashent; for (;;) { - up = next; + struct user_struct *up = next; if (next) { next = up->next; if (up->uid != uid) continue; atomic_inc(&up->__count); } - break; + return up; } - return up; } /* * For SMP, we need to re-test the user struct counter - * after having aquired the spinlock. This allows us to do + * after having acquired the spinlock. This allows us to do * the common case (not freeing anything) without having * any locking. */ @@ -97,7 +102,7 @@ void free_uid(struct user_struct *up) struct user_struct * alloc_uid(uid_t uid) { - unsigned int hashent = uidhashfn(uid); + struct user_struct **hashent = uidhashentry(uid); struct user_struct *up; spin_lock(&uidhash_lock); @@ -136,19 +141,14 @@ struct user_struct * alloc_uid(uid_t uid) static int __init uid_cache_init(void) { - int i; - uid_cachep = kmem_cache_create("uid_cache", sizeof(struct user_struct), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if(!uid_cachep) panic("Cannot create uid taskcount SLAB cache\n"); - for(i = 0; i < UIDHASH_SZ; i++) - uidhash[i] = 0; - /* Insert the root user immediately - init already runs with this */ - uid_hash_insert(&root_user, uidhashfn(0)); + uid_hash_insert(&root_user, uidhashentry(0)); return 0; } diff --git a/mm/Makefile b/mm/Makefile index 56e93693b..d74cdec48 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -10,7 +10,7 @@ O_TARGET := mm.o O_OBJS := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \ vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \ - page_alloc.o swap_state.o swapfile.o numa.o + page_alloc.o swap_state.o swapfile.o numa.o oom_kill.o ifeq ($(CONFIG_HIGHMEM),y) O_OBJS += highmem.o diff --git a/mm/bootmem.c b/mm/bootmem.c index 0a8d37ba2..e9e9ef7bc 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -41,11 +41,15 @@ unsigned long __init bootmem_bootmap_pages (unsigned long pages) /* * Called once to set up the allocator itself. */ -static unsigned long __init init_bootmem_core (bootmem_data_t *bdata, +static unsigned long __init init_bootmem_core (pg_data_t *pgdat, unsigned long mapstart, unsigned long start, unsigned long end) { + bootmem_data_t *bdata = pgdat->bdata; unsigned long mapsize = ((end - start)+7)/8; + pgdat->node_next = pgdat_list; + pgdat_list = pgdat; + mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL); bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT); bdata->node_boot_start = (start << PAGE_SHIFT); @@ -172,10 +176,6 @@ restart_scan: preferred = 0; goto restart_scan; } - /* - * Whoops, we cannot satisfy the allocation request. - */ - BUG(); found: if (start >= eidx) BUG(); @@ -221,15 +221,15 @@ found: return ret; } -static unsigned long __init free_all_bootmem_core(int nid, bootmem_data_t *bdata) +static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat) { - struct page * page; + struct page *page = pgdat->node_mem_map; + bootmem_data_t *bdata = pgdat->bdata; unsigned long i, count, total = 0; unsigned long idx; if (!bdata->node_bootmem_map) BUG(); - page = NODE_MEM_MAP(nid); count = 0; idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT); for (i = 0; i < idx; i++, page++) { @@ -260,59 +260,78 @@ static unsigned long __init free_all_bootmem_core(int nid, bootmem_data_t *bdata return total; } -unsigned long __init init_bootmem_node (int nid, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn) +unsigned long __init init_bootmem_node (pg_data_t *pgdat, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn) { - return(init_bootmem_core(NODE_DATA(nid)->bdata, freepfn, startpfn, endpfn)); + return(init_bootmem_core(pgdat, freepfn, startpfn, endpfn)); } -void __init reserve_bootmem_node (int nid, unsigned long physaddr, unsigned long size) +void __init reserve_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsigned long size) { - reserve_bootmem_core(NODE_DATA(nid)->bdata, physaddr, size); + reserve_bootmem_core(pgdat->bdata, physaddr, size); } -void __init free_bootmem_node (int nid, unsigned long physaddr, unsigned long size) +void __init free_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsigned long size) { - return(free_bootmem_core(NODE_DATA(nid)->bdata, physaddr, size)); + return(free_bootmem_core(pgdat->bdata, physaddr, size)); } -unsigned long __init free_all_bootmem_node (int nid) +unsigned long __init free_all_bootmem_node (pg_data_t *pgdat) { - return(free_all_bootmem_core(nid, NODE_DATA(nid)->bdata)); + return(free_all_bootmem_core(pgdat)); } unsigned long __init init_bootmem (unsigned long start, unsigned long pages) { max_low_pfn = pages; min_low_pfn = start; - return(init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages)); + return(init_bootmem_core(&contig_page_data, start, 0, pages)); } void __init reserve_bootmem (unsigned long addr, unsigned long size) { - reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size); + reserve_bootmem_core(contig_page_data.bdata, addr, size); } void __init free_bootmem (unsigned long addr, unsigned long size) { - return(free_bootmem_core(NODE_DATA(0)->bdata, addr, size)); + return(free_bootmem_core(contig_page_data.bdata, addr, size)); } unsigned long __init free_all_bootmem (void) { - return(free_all_bootmem_core(0, NODE_DATA(0)->bdata)); + return(free_all_bootmem_core(&contig_page_data)); } void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal) { + pg_data_t *pgdat = pgdat_list; + void *ptr; + + while (pgdat) { + if ((ptr = __alloc_bootmem_core(pgdat->bdata, size, + align, goal))) + return(ptr); + pgdat = pgdat->node_next; + } /* - * In the discontigmem case, all non-node specific allocations come - * from the first node, node 0. + * Whoops, we cannot satisfy the allocation request. */ - return(__alloc_bootmem_core(NODE_DATA(0)->bdata, size, align, goal)); + BUG(); + return NULL; } -void * __init __alloc_bootmem_node (int nid, unsigned long size, unsigned long align, unsigned long goal) +void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal) { - return(__alloc_bootmem_core(NODE_DATA(nid)->bdata, size, align, goal)); + void *ptr; + + ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal); + if (ptr) + return (ptr); + + /* + * Whoops, we cannot satisfy the allocation request. + */ + BUG(); + return NULL; } diff --git a/mm/filemap.c b/mm/filemap.c index 6aca16409..b19f4c5b3 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -135,6 +135,12 @@ void invalidate_inode_pages(struct inode * inode) if (TryLockPage(page)) continue; + /* Neither can we invalidate something in use.. */ + if (page_count(page) != 1) { + UnlockPage(page); + continue; + } + __lru_cache_del(page); __remove_inode_page(page); UnlockPage(page); @@ -156,6 +162,7 @@ static inline void truncate_partial_page(struct page *page, unsigned partial) static inline void truncate_complete_page(struct page *page) { + /* Leave it on the LRU if it gets converted into anonymous buffers */ if (!page->buffers || block_flushpage(page, 0)) lru_cache_del(page); @@ -167,6 +174,7 @@ static inline void truncate_complete_page(struct page *page) * all sorts of fun problems ... */ ClearPageDirty(page); + ClearPageUptodate(page); remove_inode_page(page); page_cache_release(page); } @@ -495,20 +503,46 @@ void ___wait_on_page(struct page *page) } /* - * Get an exclusive lock on the page.. + * Get a lock on the page, assuming we need to sleep + * to get it.. */ -void lock_page(struct page *page) +static void __lock_page(struct page *page) { - while (TryLockPage(page)) - ___wait_on_page(page); + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + + add_wait_queue_exclusive(&page->wait, &wait); + for (;;) { + sync_page(page); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + if (PageLocked(page)) { + run_task_queue(&tq_disk); + schedule(); + continue; + } + if (!TryLockPage(page)) + break; + } + tsk->state = TASK_RUNNING; + remove_wait_queue(&page->wait, &wait); } + +/* + * Get an exclusive lock on the page, optimistically + * assuming it's not locked.. + */ +void lock_page(struct page *page) +{ + if (TryLockPage(page)) + __lock_page(page); +} /* * a rather lightweight function, finding and getting a reference to a * hashed page atomically, waiting for it if it's locked. */ -struct page * __find_get_page (struct address_space *mapping, +static struct page * __find_get_page(struct address_space *mapping, unsigned long offset, struct page **hash) { struct page *page; @@ -517,41 +551,11 @@ struct page * __find_get_page (struct address_space *mapping, * We scan the hash list read-only. Addition to and removal from * the hash-list needs a held write-lock. */ -repeat: spin_lock(&pagecache_lock); page = __find_page_nolock(mapping, offset, *hash); if (page) page_cache_get(page); spin_unlock(&pagecache_lock); - - /* Found the page, sleep if locked. */ - if (page && PageLocked(page)) { - struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); - - sync_page(page); - - __set_task_state(tsk, TASK_UNINTERRUPTIBLE); - add_wait_queue(&page->wait, &wait); - - if (PageLocked(page)) - schedule(); - __set_task_state(tsk, TASK_RUNNING); - remove_wait_queue(&page->wait, &wait); - - /* - * The page might have been unhashed meanwhile. It's - * not freed though because we hold a reference to it. - * If this is the case then it will be freed _here_, - * and we recheck the hash anyway. - */ - page_cache_release(page); - goto repeat; - } - /* - * It's not locked so we can return the page and we hold - * a reference to it. - */ return page; } @@ -570,39 +574,23 @@ struct page * __find_lock_page (struct address_space *mapping, repeat: spin_lock(&pagecache_lock); page = __find_page_nolock(mapping, offset, *hash); - if (page) + if (page) { page_cache_get(page); - spin_unlock(&pagecache_lock); - - /* Found the page, sleep if locked. */ - if (page && TryLockPage(page)) { - struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); - - sync_page(page); + spin_unlock(&pagecache_lock); - __set_task_state(tsk, TASK_UNINTERRUPTIBLE); - add_wait_queue(&page->wait, &wait); + lock_page(page); - if (PageLocked(page)) - schedule(); - __set_task_state(tsk, TASK_RUNNING); - remove_wait_queue(&page->wait, &wait); + /* Is the page still hashed? Ok, good.. */ + if (page->mapping) + return page; - /* - * The page might have been unhashed meanwhile. It's - * not freed though because we hold a reference to it. - * If this is the case then it will be freed _here_, - * and we recheck the hash anyway. - */ + /* Nope: we raced. Release and try again.. */ + UnlockPage(page); page_cache_release(page); goto repeat; } - /* - * It's not locked so we can return the page and we hold - * a reference to it. - */ - return page; + spin_unlock(&pagecache_lock); + return NULL; } #if 0 @@ -993,7 +981,7 @@ page_ok: * virtual addresses, take care about potential aliasing * before reading the page on the kernel side. */ - if (page->mapping->i_mmap_shared != NULL) + if (mapping->i_mmap_shared != NULL) flush_dcache_page(page); /* @@ -1027,6 +1015,15 @@ page_not_up_to_date: /* Get exclusive access to the page ... */ lock_page(page); + + /* Did it get unhashed before we got the lock? */ + if (!page->mapping) { + UnlockPage(page); + page_cache_release(page); + continue; + } + + /* Did somebody else fill it already? */ if (Page_Uptodate(page)) { UnlockPage(page); goto page_ok; @@ -1323,16 +1320,16 @@ struct page * filemap_nopage(struct vm_area_struct * area, struct inode *inode = file->f_dentry->d_inode; struct address_space *mapping = inode->i_mapping; struct page *page, **hash, *old_page; - unsigned long size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; + unsigned long size, pgoff; - unsigned long pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff; + pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff; +retry_all: /* - * Semantics for shared and private memory areas are different - * past the end of the file. A shared mapping past the last page - * of the file is an error and results in a SIGBUS, while a - * private mapping just maps in a zero page. + * An external ptracer can access pages that normally aren't + * accessible.. */ + size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; if ((pgoff >= size) && (area->vm_mm == current->mm)) return NULL; @@ -1411,6 +1408,15 @@ no_cached_page: page_not_uptodate: lock_page(page); + + /* Did it get unhashed while we waited for it? */ + if (!page->mapping) { + UnlockPage(page); + page_cache_release(page); + goto retry_all; + } + + /* Did somebody else get it up-to-date? */ if (Page_Uptodate(page)) { UnlockPage(page); goto success; @@ -1429,6 +1435,15 @@ page_not_uptodate: * and we need to check for errors. */ lock_page(page); + + /* Somebody truncated the page on us? */ + if (!page->mapping) { + UnlockPage(page); + page_cache_release(page); + goto retry_all; + } + + /* Somebody else successfully read it in? */ if (Page_Uptodate(page)) { UnlockPage(page); goto success; @@ -1448,17 +1463,25 @@ page_not_uptodate: return NULL; } +/* + * If a task terminates while we're swapping the page, the vma and + * and file could be released: try_to_swap_out has done a get_file. + * vma/file is guaranteed to exist in the unmap/sync cases because + * mmap_sem is held. + * + * The "mapping" test takes care of somebody having truncated the + * page and thus made this write-page a no-op.. + */ static int filemap_write_page(struct file *file, struct page * page, int wait) { - /* - * If a task terminates while we're swapping the page, the vma and - * and file could be released: try_to_swap_out has done a get_file. - * vma/file is guaranteed to exist in the unmap/sync cases because - * mmap_sem is held. - */ - return page->mapping->a_ops->writepage(file, page); + struct address_space * mapping = page->mapping; + int error = 0; + + if (mapping) + error = mapping->a_ops->writepage(file, page); + return error; } @@ -1475,39 +1498,47 @@ int filemap_swapout(struct page * page, struct file * file) return retval; } +/* Called with mm->page_table_lock held to protect against other + * threads/the swapper from ripping pte's out from under us. + */ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma, unsigned long address, unsigned int flags) { unsigned long pgoff; - pte_t pte = *ptep; + pte_t pte; struct page *page; int error; + pte = *ptep; + if (!(flags & MS_INVALIDATE)) { if (!pte_present(pte)) - return 0; - if (!pte_dirty(pte)) - return 0; + goto out; + if (!ptep_test_and_clear_dirty(ptep)) + goto out; flush_page_to_ram(pte_page(pte)); flush_cache_page(vma, address); - set_pte(ptep, pte_mkclean(pte)); flush_tlb_page(vma, address); page = pte_page(pte); page_cache_get(page); } else { if (pte_none(pte)) - return 0; + goto out; flush_cache_page(vma, address); - pte_clear(ptep); + + pte = ptep_get_and_clear(ptep); flush_tlb_page(vma, address); + if (!pte_present(pte)) { + spin_unlock(&vma->vm_mm->page_table_lock); swap_free(pte_to_swp_entry(pte)); - return 0; + spin_lock(&vma->vm_mm->page_table_lock); + goto out; } page = pte_page(pte); if (!pte_dirty(pte) || flags == MS_INVALIDATE) { page_cache_free(page); - return 0; + goto out; } } pgoff = (address - vma->vm_start) >> PAGE_CACHE_SHIFT; @@ -1516,11 +1547,20 @@ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma, printk("weirdness: pgoff=%lu index=%lu address=%lu vm_start=%lu vm_pgoff=%lu\n", pgoff, page->index, address, vma->vm_start, vma->vm_pgoff); } + + spin_unlock(&vma->vm_mm->page_table_lock); lock_page(page); + error = filemap_write_page(vma->vm_file, page, 1); + UnlockPage(page); page_cache_free(page); + + spin_lock(&vma->vm_mm->page_table_lock); return error; + +out: + return 0; } static inline int filemap_sync_pte_range(pmd_t * pmd, @@ -1590,6 +1630,11 @@ int filemap_sync(struct vm_area_struct * vma, unsigned long address, unsigned long end = address + size; int error = 0; + /* Aquire the lock early; it may be possible to avoid dropping + * and reaquiring it repeatedly. + */ + spin_lock(&vma->vm_mm->page_table_lock); + dir = pgd_offset(vma->vm_mm, address); flush_cache_range(vma->vm_mm, end - size, end); if (address >= end) @@ -1600,6 +1645,9 @@ int filemap_sync(struct vm_area_struct * vma, unsigned long address, dir++; } while (address && (address < end)); flush_tlb_range(vma->vm_mm, end - size, end); + + spin_unlock(&vma->vm_mm->page_table_lock); + return error; } @@ -1766,11 +1814,11 @@ static long madvise_fixup_start(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = end; insert_vm_struct(current->mm, n); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -1790,10 +1838,10 @@ static long madvise_fixup_end(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_end = start; insert_vm_struct(current->mm, n); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -1823,7 +1871,7 @@ static long madvise_fixup_middle(struct vm_area_struct * vma, vma->vm_ops->open(left); vma->vm_ops->open(right); } - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = start; vma->vm_end = end; @@ -1831,7 +1879,7 @@ static long madvise_fixup_middle(struct vm_area_struct * vma, vma->vm_raend = 0; insert_vm_struct(current->mm, left); insert_vm_struct(current->mm, right); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -2270,13 +2318,20 @@ struct page *read_cache_page(struct address_space *mapping, int (*filler)(void *,struct page*), void *data) { - struct page *page = __read_cache_page(mapping, index, filler, data); + struct page *page; int err; +retry: + page = __read_cache_page(mapping, index, filler, data); if (IS_ERR(page) || Page_Uptodate(page)) goto out; lock_page(page); + if (!page->mapping) { + UnlockPage(page); + page_cache_release(page); + goto retry; + } if (Page_Uptodate(page)) { UnlockPage(page); goto out; diff --git a/mm/highmem.c b/mm/highmem.c index 3be601c6f..d83d9bb87 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -130,10 +130,9 @@ static void flush_all_zero_pkmaps(void) if (pkmap_count[i] != 1) continue; pkmap_count[i] = 0; - pte = pkmap_page_table[i]; + pte = ptep_get_and_clear(pkmap_page_table+i); if (pte_none(pte)) BUG(); - pte_clear(pkmap_page_table+i); page = pte_page(pte); page->virtual = NULL; } @@ -310,7 +309,7 @@ struct buffer_head * create_bounce(int rw, struct buffer_head * bh_orig) repeat_bh: bh = kmem_cache_alloc(bh_cachep, SLAB_BUFFER); if (!bh) { - wakeup_bdflush(1); + wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */ current->policy |= SCHED_YIELD; schedule(); goto repeat_bh; @@ -324,7 +323,7 @@ repeat_bh: repeat_page: page = alloc_page(GFP_BUFFER); if (!page) { - wakeup_bdflush(1); + wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */ current->policy |= SCHED_YIELD; schedule(); goto repeat_page; diff --git a/mm/memory.c b/mm/memory.c index 6b047821d..11048ddce 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -215,30 +215,30 @@ skip_copy_pte_range: address = (address + PMD_SIZE) & PMD_MASK; /* copy_one_pte */ if (pte_none(pte)) - goto cont_copy_pte_range; + goto cont_copy_pte_range_noset; if (!pte_present(pte)) { swap_duplicate(pte_to_swp_entry(pte)); - set_pte(dst_pte, pte); goto cont_copy_pte_range; } ptepage = pte_page(pte); if ((!VALID_PAGE(ptepage)) || - PageReserved(ptepage)) { - set_pte(dst_pte, pte); + PageReserved(ptepage)) goto cont_copy_pte_range; - } + /* If it's a COW mapping, write protect it both in the parent and the child */ if (cow) { - pte = pte_wrprotect(pte); - set_pte(src_pte, pte); + ptep_clear_wrprotect(src_pte); + pte = *src_pte; } + /* If it's a shared mapping, mark it clean in the child */ if (vma->vm_flags & VM_SHARED) pte = pte_mkclean(pte); - set_pte(dst_pte, pte_mkold(pte)); + pte = pte_mkold(pte); get_page(ptepage); - -cont_copy_pte_range: address += PAGE_SIZE; + +cont_copy_pte_range: set_pte(dst_pte, pte); +cont_copy_pte_range_noset: address += PAGE_SIZE; if (address >= end) goto out; src_pte++; @@ -306,10 +306,9 @@ static inline int zap_pte_range(struct mm_struct *mm, pmd_t * pmd, unsigned long pte_t page; if (!size) break; - page = *pte; + page = ptep_get_and_clear(pte); pte++; size--; - pte_clear(pte-1); if (pte_none(page)) continue; freed += free_pte(page); @@ -642,7 +641,7 @@ static inline void zeromap_pte_range(pte_t * pte, unsigned long address, end = PMD_SIZE; do { pte_t zero_pte = pte_wrprotect(mk_pte(ZERO_PAGE(address), prot)); - pte_t oldpage = *pte; + pte_t oldpage = ptep_get_and_clear(pte); set_pte(pte, zero_pte); forget_pte(oldpage); address += PAGE_SIZE; @@ -712,8 +711,8 @@ static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned end = PMD_SIZE; do { struct page *page; - pte_t oldpage = *pte; - pte_clear(pte); + pte_t oldpage; + oldpage = ptep_get_and_clear(pte); page = virt_to_page(__va(phys_addr)); if ((!VALID_PAGE(page)) || PageReserved(page)) @@ -746,6 +745,7 @@ static inline int remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned l return 0; } +/* Note: this is only safe if the mm semaphore is held when called. */ int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot) { int error = 0; @@ -781,8 +781,8 @@ int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long */ static inline void establish_pte(struct vm_area_struct * vma, unsigned long address, pte_t *page_table, pte_t entry) { - flush_tlb_page(vma, address); set_pte(page_table, entry); + flush_tlb_page(vma, address); update_mmu_cache(vma, address, entry); } @@ -867,7 +867,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, /* * Re-check the pte - we dropped the lock */ - if (pte_val(*page_table) == pte_val(pte)) { + if (pte_same(*page_table, pte)) { if (PageReserved(old_page)) ++mm->rss; break_cow(vma, old_page, new_page, address, page_table); @@ -1214,7 +1214,7 @@ static inline int handle_pte_fault(struct mm_struct *mm, * didn't change from under us.. */ spin_lock(&mm->page_table_lock); - if (pte_val(entry) == pte_val(*pte)) { + if (pte_same(entry, *pte)) { if (write_access) { if (!pte_write(entry)) return do_wp_page(mm, vma, address, pte, entry); diff --git a/mm/mlock.c b/mm/mlock.c index a3d10ff99..f684a3c60 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -14,9 +14,9 @@ static inline int mlock_fixup_all(struct vm_area_struct * vma, int newflags) { - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_flags = newflags; - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -36,11 +36,11 @@ static inline int mlock_fixup_start(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = end; insert_vm_struct(current->mm, n); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -61,10 +61,10 @@ static inline int mlock_fixup_end(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_end = start; insert_vm_struct(current->mm, n); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -96,7 +96,7 @@ static inline int mlock_fixup_middle(struct vm_area_struct * vma, vma->vm_ops->open(left); vma->vm_ops->open(right); } - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = start; vma->vm_end = end; @@ -104,7 +104,7 @@ static inline int mlock_fixup_middle(struct vm_area_struct * vma, vma->vm_raend = 0; insert_vm_struct(current->mm, left); insert_vm_struct(current->mm, right); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -183,9 +183,9 @@ static int do_mlock(unsigned long start, size_t len, int on) break; } } - vmlist_modify_lock(current->mm); + spin_lock(¤t->mm->page_table_lock); merge_segments(current->mm, start, end); - vmlist_modify_unlock(current->mm); + spin_unlock(¤t->mm->page_table_lock); return error; } @@ -257,9 +257,9 @@ static int do_mlockall(int flags) if (error) break; } - vmlist_modify_lock(current->mm); + spin_lock(¤t->mm->page_table_lock); merge_segments(current->mm, 0, TASK_SIZE); - vmlist_modify_unlock(current->mm); + spin_unlock(¤t->mm->page_table_lock); return error; } @@ -317,12 +317,12 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned lon */ flags = vma->vm_flags; addr = vma->vm_start; /* can addr have changed?? */ - vmlist_modify_lock(mm); + spin_lock(&mm->page_table_lock); insert_vm_struct(mm, vma); if (correct_wcount) atomic_inc(&file->f_dentry->d_inode->i_writecount); merge_segments(mm, vma->vm_start, vma->vm_end); - vmlist_modify_unlock(mm); + spin_unlock(&mm->page_table_lock); mm->total_vm += len >> PAGE_SHIFT; if (flags & VM_LOCKED) { @@ -534,11 +534,11 @@ static struct vm_area_struct * unmap_fixup(struct mm_struct *mm, /* Work out to one of the ends. */ if (end == area->vm_end) { area->vm_end = addr; - vmlist_modify_lock(mm); + spin_lock(&mm->page_table_lock); } else if (addr == area->vm_start) { area->vm_pgoff += (end - area->vm_start) >> PAGE_SHIFT; area->vm_start = end; - vmlist_modify_lock(mm); + spin_lock(&mm->page_table_lock); } else { /* Unmapping a hole: area->vm_start < addr <= end < area->vm_end */ /* Add end mapping -- leave beginning for below */ @@ -560,12 +560,12 @@ static struct vm_area_struct * unmap_fixup(struct mm_struct *mm, if (mpnt->vm_ops && mpnt->vm_ops->open) mpnt->vm_ops->open(mpnt); area->vm_end = addr; /* Truncate area */ - vmlist_modify_lock(mm); + spin_lock(&mm->page_table_lock); insert_vm_struct(mm, mpnt); } insert_vm_struct(mm, area); - vmlist_modify_unlock(mm); + spin_unlock(&mm->page_table_lock); return extra; } @@ -670,7 +670,7 @@ int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len) npp = (prev ? &prev->vm_next : &mm->mmap); free = NULL; - vmlist_modify_lock(mm); + spin_lock(&mm->page_table_lock); for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) { *npp = mpnt->vm_next; mpnt->vm_next = free; @@ -679,7 +679,7 @@ int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len) avl_remove(mpnt, &mm->mmap_avl); } mm->mmap_cache = NULL; /* Kill the cache. */ - vmlist_modify_unlock(mm); + spin_unlock(&mm->page_table_lock); /* Ok - we have the memory areas we should free on the 'free' list, * so release them, and unmap the page range.. @@ -811,10 +811,10 @@ unsigned long do_brk(unsigned long addr, unsigned long len) flags = vma->vm_flags; addr = vma->vm_start; - vmlist_modify_lock(mm); + spin_lock(&mm->page_table_lock); insert_vm_struct(mm, vma); merge_segments(mm, vma->vm_start, vma->vm_end); - vmlist_modify_unlock(mm); + spin_unlock(&mm->page_table_lock); mm->total_vm += len >> PAGE_SHIFT; if (flags & VM_LOCKED) { @@ -840,10 +840,10 @@ void exit_mmap(struct mm_struct * mm) struct vm_area_struct * mpnt; release_segments(mm); + spin_lock(&mm->page_table_lock); mpnt = mm->mmap; - vmlist_modify_lock(mm); mm->mmap = mm->mmap_avl = mm->mmap_cache = NULL; - vmlist_modify_unlock(mm); + spin_unlock(&mm->page_table_lock); mm->rss = 0; mm->total_vm = 0; mm->locked_vm = 0; @@ -985,9 +985,9 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l if (mpnt->vm_ops && mpnt->vm_ops->close) { mpnt->vm_pgoff += (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; mpnt->vm_start = mpnt->vm_end; - vmlist_modify_unlock(mm); + spin_unlock(&mm->page_table_lock); mpnt->vm_ops->close(mpnt); - vmlist_modify_lock(mm); + spin_lock(&mm->page_table_lock); } mm->map_count--; remove_shared_vm_struct(mpnt); diff --git a/mm/mprotect.c b/mm/mprotect.c index 53fc53acb..7b61abb3e 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -30,9 +30,16 @@ static inline void change_pte_range(pmd_t * pmd, unsigned long address, if (end > PMD_SIZE) end = PMD_SIZE; do { - pte_t entry = *pte; - if (pte_present(entry)) + if (pte_present(*pte)) { + pte_t entry; + + /* Avoid an SMP race with hardware updated dirty/clean + * bits by wiping the pte and then setting the new pte + * into place. + */ + entry = ptep_get_and_clear(pte); set_pte(pte, pte_modify(entry, newprot)); + } address += PAGE_SIZE; pte++; } while (address && (address < end)); @@ -86,10 +93,10 @@ static void change_protection(unsigned long start, unsigned long end, pgprot_t n static inline int mprotect_fixup_all(struct vm_area_struct * vma, int newflags, pgprot_t prot) { - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_flags = newflags; vma->vm_page_prot = prot; - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -111,11 +118,11 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = end; insert_vm_struct(current->mm, n); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -138,10 +145,10 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma, get_file(n->vm_file); if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_end = start; insert_vm_struct(current->mm, n); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -172,7 +179,7 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma, vma->vm_ops->open(left); vma->vm_ops->open(right); } - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT; vma->vm_start = start; vma->vm_end = end; @@ -181,7 +188,7 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma, vma->vm_page_prot = prot; insert_vm_struct(current->mm, left); insert_vm_struct(current->mm, right); - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); return 0; } @@ -263,9 +270,9 @@ asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot break; } } - vmlist_modify_lock(current->mm); + spin_lock(¤t->mm->page_table_lock); merge_segments(current->mm, start, end); - vmlist_modify_unlock(current->mm); + spin_unlock(¤t->mm->page_table_lock); out: up(¤t->mm->mmap_sem); return error; diff --git a/mm/mremap.c b/mm/mremap.c index d1f6a7b8b..719ca1ec1 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -63,14 +63,14 @@ static inline int copy_one_pte(struct mm_struct *mm, pte_t * src, pte_t * dst) pte_t pte; spin_lock(&mm->page_table_lock); - pte = *src; - if (!pte_none(pte)) { - error++; - if (dst) { - pte_clear(src); - set_pte(dst, pte); - error--; + if (!pte_none(*src)) { + pte = ptep_get_and_clear(src); + if (!dst) { + /* No dest? We must put it back. */ + dst = src; + error++; } + set_pte(dst, pte); } spin_unlock(&mm->page_table_lock); return error; @@ -141,10 +141,10 @@ static inline unsigned long move_vma(struct vm_area_struct * vma, get_file(new_vma->vm_file); if (new_vma->vm_ops && new_vma->vm_ops->open) new_vma->vm_ops->open(new_vma); - vmlist_modify_lock(current->mm); + spin_lock(¤t->mm->page_table_lock); insert_vm_struct(current->mm, new_vma); merge_segments(current->mm, new_vma->vm_start, new_vma->vm_end); - vmlist_modify_unlock(current->mm); + spin_unlock(¤t->mm->page_table_lock); do_munmap(current->mm, addr, old_len); current->mm->total_vm += new_len >> PAGE_SHIFT; if (new_vma->vm_flags & VM_LOCKED) { @@ -258,9 +258,9 @@ unsigned long do_mremap(unsigned long addr, /* can we just expand the current mapping? */ if (max_addr - addr >= new_len) { int pages = (new_len - old_len) >> PAGE_SHIFT; - vmlist_modify_lock(vma->vm_mm); + spin_lock(&vma->vm_mm->page_table_lock); vma->vm_end = addr + new_len; - vmlist_modify_unlock(vma->vm_mm); + spin_unlock(&vma->vm_mm->page_table_lock); current->mm->total_vm += pages; if (vma->vm_flags & VM_LOCKED) { current->mm->locked_vm += pages; @@ -11,11 +11,11 @@ int numnodes = 1; /* Initialized for UMA platforms */ -#ifndef CONFIG_DISCONTIGMEM - static bootmem_data_t contig_bootmem_data; pg_data_t contig_page_data = { bdata: &contig_bootmem_data }; +#ifndef CONFIG_DISCONTIGMEM + /* * This is meant to be invoked by platforms whose physical memory starts * at a considerably higher value than 0. Examples are Super-H, ARM, m68k. @@ -25,7 +25,7 @@ void __init free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap, unsigned long *zones_size, unsigned long zone_start_paddr, unsigned long *zholes_size) { - free_area_init_core(0, NODE_DATA(0), &mem_map, zones_size, + free_area_init_core(0, &contig_page_data, &mem_map, zones_size, zone_start_paddr, zholes_size, pmap); } @@ -33,7 +33,11 @@ void __init free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap, struct page * alloc_pages_node(int nid, int gfp_mask, unsigned long order) { +#ifdef CONFIG_NUMA return __alloc_pages(NODE_DATA(nid)->node_zonelists + gfp_mask, order); +#else + return alloc_pages(gfp_mask, order); +#endif } #ifdef CONFIG_DISCONTIGMEM @@ -42,13 +46,12 @@ struct page * alloc_pages_node(int nid, int gfp_mask, unsigned long order) static spinlock_t node_lock = SPIN_LOCK_UNLOCKED; -void show_free_areas_node(int nid) +void show_free_areas_node(pg_data_t *pgdat) { unsigned long flags; spin_lock_irqsave(&node_lock, flags); - printk("Memory information for node %d:\n", nid); - show_free_areas_core(nid); + show_free_areas_core(pgdat); spin_unlock_irqrestore(&node_lock, flags); } @@ -75,10 +78,16 @@ void __init free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap, for (i = 0; i < MAX_NR_ZONES; i++) size += zones_size[i]; size = LONG_ALIGN((size + 7) >> 3); - pgdat->valid_addr_bitmap = (unsigned long *)alloc_bootmem_node(nid, size); + pgdat->valid_addr_bitmap = (unsigned long *)alloc_bootmem_node(pgdat, size); memset(pgdat->valid_addr_bitmap, 0, size); } +static struct page * alloc_pages_pgdat(pg_data_t *pgdat, int gfp_mask, + unsigned long order) +{ + return __alloc_pages(pgdat->node_zonelists + gfp_mask, order); +} + /* * This can be refined. Currently, tries to do round robin, instead * should do concentratic circle search, starting from current node. @@ -86,33 +95,34 @@ void __init free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap, struct page * alloc_pages(int gfp_mask, unsigned long order) { struct page *ret = 0; - int startnode, tnode; + pg_data_t *start, *temp; #ifndef CONFIG_NUMA unsigned long flags; - static int nextnid = 0; + static pg_data_t *next = 0; #endif if (order >= MAX_ORDER) return NULL; #ifdef CONFIG_NUMA - tnode = numa_node_id(); + temp = NODE_DATA(numa_node_id()); #else spin_lock_irqsave(&node_lock, flags); - tnode = nextnid; - nextnid++; - if (nextnid == numnodes) - nextnid = 0; + if (!next) next = pgdat_list; + temp = next; + next = next->node_next; spin_unlock_irqrestore(&node_lock, flags); #endif - startnode = tnode; - while (tnode < numnodes) { - if ((ret = alloc_pages_node(tnode++, gfp_mask, order))) + start = temp; + while (temp) { + if ((ret = alloc_pages_pgdat(temp, gfp_mask, order))) return(ret); + temp = temp->node_next; } - tnode = 0; - while (tnode != startnode) { - if ((ret = alloc_pages_node(tnode++, gfp_mask, order))) + temp = pgdat_list; + while (temp != start) { + if ((ret = alloc_pages_pgdat(temp, gfp_mask, order))) return(ret); + temp = temp->node_next; } return(0); } diff --git a/mm/oom_kill.c b/mm/oom_kill.c new file mode 100644 index 000000000..9882fe7cd --- /dev/null +++ b/mm/oom_kill.c @@ -0,0 +1,210 @@ +/* + * linux/mm/oom_kill.c + * + * Copyright (C) 1998,2000 Rik van Riel + * Thanks go out to Claus Fischer for some serious inspiration and + * for goading me into coding this file... + * + * The routines in this file are used to kill a process when + * we're seriously out of memory. This gets called from kswapd() + * in linux/mm/vmscan.c when we really run out of memory. + * + * Since we won't call these routines often (on a well-configured + * machine) this file will double as a 'coding guide' and a signpost + * for newbie kernel hackers. It features several pointers to major + * kernel subsystems and hints as to where to find out what things do. + */ + +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/swap.h> +#include <linux/swapctl.h> +#include <linux/timex.h> + +/* #define DEBUG */ + +/** + * int_sqrt - oom_kill.c internal function, rough approximation to sqrt + * @x: integer of which to calculate the sqrt + * + * A very rough approximation to the sqrt() function. + */ +static unsigned int int_sqrt(unsigned int x) +{ + unsigned int out = x; + while (x & ~(unsigned int)1) x >>=2, out >>=1; + if (x) out -= out >> 2; + return (out ? out : 1); +} + +/** + * oom_badness - calculate a numeric value for how bad this task has been + * @p: task struct of which task we should calculate + * + * The formula used is relatively simple and documented inline in the + * function. The main rationale is that we want to select a good task + * to kill when we run out of memory. + * + * Good in this context means that: + * 1) we lose the minimum amount of work done + * 2) we recover a large amount of memory + * 3) we don't kill anything innocent of eating tons of memory + * 4) we want to kill the minimum amount of processes (one) + * 5) we try to kill the process the user expects us to kill, this + * algorithm has been meticulously tuned to meet the priniciple + * of least surprise ... (be careful when you change it) + */ + +static int badness(struct task_struct *p) +{ + int points, cpu_time, run_time; + + if (!p->mm) + return 0; + /* + * The memory size of the process is the basis for the badness. + */ + points = p->mm->total_vm; + + /* + * CPU time is in seconds and run time is in minutes. There is no + * particular reason for this other than that it turned out to work + * very well in practice. This is not safe against jiffie wraps + * but we don't care _that_ much... + */ + cpu_time = (p->times.tms_utime + p->times.tms_stime) >> (SHIFT_HZ + 3); + run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10); + + points /= int_sqrt(cpu_time); + points /= int_sqrt(int_sqrt(run_time)); + + /* + * Niced processes are most likely less important, so double + * their badness points. + */ + if (p->nice > 0) + points *= 2; + + /* + * Superuser processes are usually more important, so we make it + * less likely that we kill those. + */ + if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) || + p->uid == 0 || p->euid == 0) + points /= 4; + + /* + * We don't want to kill a process with direct hardware access. + * Not only could that mess up the hardware, but usually users + * tend to only have this flag set on applications they think + * of as important. + */ + if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) + points /= 4; +#ifdef DEBUG + printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n", + p->pid, p->comm, points); +#endif + return points; +} + +/* + * Simple selection loop. We chose the process with the highest + * number of 'points'. We need the locks to make sure that the + * list of task structs doesn't change while we look the other way. + * + * (not docbooked, we don't want this one cluttering up the manual) + */ +static struct task_struct * select_bad_process(void) +{ + int points = 0, maxpoints = 0; + struct task_struct *p = NULL; + struct task_struct *chosen = NULL; + + read_lock(&tasklist_lock); + for_each_task(p) + { + if (p->pid) + points = badness(p); + if (points > maxpoints) { + chosen = p; + maxpoints = points; + } + } + read_unlock(&tasklist_lock); + return chosen; +} + +/** + * oom_kill - kill the "best" process when we run out of memory + * + * If we run out of memory, we have the choice between either + * killing a random task (bad), letting the system crash (worse) + * OR try to be smart about which process to kill. Note that we + * don't have to be perfect here, we just have to be good. + * + * We must be careful though to never send SIGKILL a process with + * CAP_SYS_RAW_IO set, send SIGTERM instead (but it's unlikely that + * we select a process with CAP_SYS_RAW_IO set). + */ +void oom_kill(void) +{ + + struct task_struct *p = select_bad_process(); + + /* Found nothing?!?! Either we hang forever, or we panic. */ + if (p == NULL) + panic("Out of memory and no killable processes...\n"); + + printk(KERN_ERR "Out of Memory: Killed process %d (%s).", p->pid, p->comm); + + /* + * We give our sacrificial lamb high priority and access to + * all the memory it needs. That way it should be able to + * exit() and clear out its resources quickly... + */ + p->counter = 5 * HZ; + p->flags |= PF_MEMALLOC; + + /* This process has hardware access, be more careful. */ + if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) { + force_sig(SIGTERM, p); + } else { + force_sig(SIGKILL, p); + } + + /* + * Make kswapd go out of the way, so "p" has a good chance of + * killing itself before someone else gets the chance to ask + * for more memory. + */ + current->policy |= SCHED_YIELD; + schedule(); + return; +} + +/** + * out_of_memory - is the system out of memory? + * + * Returns 0 if there is still enough memory left, + * 1 when we are out of memory (otherwise). + */ +int out_of_memory(void) +{ + struct sysinfo swp_info; + + /* Enough free memory? Not OOM. */ + if (nr_free_pages() > freepages.min) + return 0; + + if (nr_free_pages() + nr_inactive_clean_pages() > freepages.low) + return 0; + + /* Enough swap space left? Not OOM. */ + si_swapinfo(&swp_info); + if (swp_info.freeswap > 0) + return 0; + + /* Else... */ + return 1; +} diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 0b5990a11..90c077439 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -17,13 +17,6 @@ #include <linux/pagemap.h> #include <linux/bootmem.h> -/* Use NUMNODES instead of numnodes for better code inside kernel APIs */ -#ifndef CONFIG_DISCONTIGMEM -#define NUMNODES 1 -#else -#define NUMNODES numnodes -#endif - int nr_swap_pages; int nr_active_pages; int nr_inactive_dirty_pages; @@ -294,7 +287,7 @@ struct page * __alloc_pages(zonelist_t *zonelist, unsigned long order) zone_t **zone; int direct_reclaim = 0; unsigned int gfp_mask = zonelist->gfp_mask; - struct page * page = NULL; + struct page * page; /* * Allocations put pressure on the VM subsystem. @@ -329,7 +322,7 @@ struct page * __alloc_pages(zonelist_t *zonelist, unsigned long order) * wake up bdflush. */ else if (free_shortage() && nr_inactive_dirty_pages > free_shortage() - && nr_inactive_dirty_pages > freepages.high) + && nr_inactive_dirty_pages >= freepages.high) wakeup_bdflush(0); try_again: @@ -347,7 +340,7 @@ try_again: if (!z->size) BUG(); - if (z->free_pages > z->pages_low) { + if (z->free_pages >= z->pages_low) { page = rmqueue(z, order); if (page) return page; @@ -517,17 +510,17 @@ try_again: * happen when the OOM killer selects this task for * instant execution... */ - if (direct_reclaim) + if (direct_reclaim) { page = reclaim_page(z); - if (page) - return page; + if (page) + return page; + } /* XXX: is pages_min/4 a good amount to reserve for this? */ if (z->free_pages < z->pages_min / 4 && !(current->flags & PF_MEMALLOC)) continue; - if (!page) - page = rmqueue(z, order); + page = rmqueue(z, order); if (page) return page; } @@ -588,12 +581,14 @@ unsigned int nr_free_pages (void) { unsigned int sum; zone_t *zone; - int i; + pg_data_t *pgdat = pgdat_list; sum = 0; - for (i = 0; i < NUMNODES; i++) - for (zone = NODE_DATA(i)->node_zones; zone < NODE_DATA(i)->node_zones + MAX_NR_ZONES; zone++) + while (pgdat) { + for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++) sum += zone->free_pages; + pgdat = pgdat->node_next; + } return sum; } @@ -604,12 +599,14 @@ unsigned int nr_inactive_clean_pages (void) { unsigned int sum; zone_t *zone; - int i; + pg_data_t *pgdat = pgdat_list; sum = 0; - for (i = 0; i < NUMNODES; i++) - for (zone = NODE_DATA(i)->node_zones; zone < NODE_DATA(i)->node_zones + MAX_NR_ZONES; zone++) + while (pgdat) { + for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++) sum += zone->inactive_clean_pages; + pgdat = pgdat->node_next; + } return sum; } @@ -644,11 +641,13 @@ unsigned int nr_free_buffer_pages (void) #if CONFIG_HIGHMEM unsigned int nr_free_highpages (void) { - int i; + pg_data_t *pgdat = pgdat_list; unsigned int pages = 0; - for (i = 0; i < NUMNODES; i++) - pages += NODE_DATA(i)->node_zones[ZONE_HIGHMEM].free_pages; + while (pgdat) { + pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages; + pgdat = pgdat->node_next; + } return pages; } #endif @@ -658,7 +657,7 @@ unsigned int nr_free_highpages (void) * We also calculate the percentage fragmentation. We do this by counting the * memory on each free list with the exception of the first item on the list. */ -void show_free_areas_core(int nid) +void show_free_areas_core(pg_data_t *pgdat) { unsigned long order; unsigned type; @@ -678,7 +677,7 @@ void show_free_areas_core(int nid) for (type = 0; type < MAX_NR_ZONES; type++) { struct list_head *head, *curr; - zone_t *zone = NODE_DATA(nid)->node_zones + type; + zone_t *zone = pgdat->node_zones + type; unsigned long nr, total, flags; total = 0; @@ -710,7 +709,7 @@ void show_free_areas_core(int nid) void show_free_areas(void) { - show_free_areas_core(0); + show_free_areas_core(pgdat_list); } /* @@ -780,9 +779,6 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap, unsigned long totalpages, offset, realtotalpages; unsigned int cumulative = 0; - pgdat->node_next = pgdat_list; - pgdat_list = pgdat; - totalpages = 0; for (i = 0; i < MAX_NR_ZONES; i++) { unsigned long size = zones_size[i]; @@ -795,21 +791,6 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap, printk("On node %d totalpages: %lu\n", nid, realtotalpages); - /* - * Select nr of pages we try to keep free for important stuff - * with a minimum of 10 pages and a maximum of 256 pages, so - * that we don't waste too much memory on large systems. - * This is fairly arbitrary, but based on some behaviour - * analysis. - */ - i = realtotalpages >> 7; - if (i < 10) - i = 10; - if (i > 256) - i = 256; - freepages.min += i; - freepages.low += i * 2; - freepages.high += i * 3; memlist_init(&active_list); memlist_init(&inactive_dirty_list); @@ -822,7 +803,7 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap, */ map_size = (totalpages + 1)*sizeof(struct page); if (lmem_map == (struct page *)0) { - lmem_map = (struct page *) alloc_bootmem_node(nid, map_size); + lmem_map = (struct page *) alloc_bootmem_node(pgdat, map_size); lmem_map = (struct page *)(PAGE_OFFSET + MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET)); } @@ -875,6 +856,20 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap, zone->pages_min = mask; zone->pages_low = mask*2; zone->pages_high = mask*3; + /* + * Add these free targets to the global free target; + * we have to be SURE that freepages.high is higher + * than SUM [zone->pages_min] for all zones, otherwise + * we may have bad bad problems. + * + * This means we cannot make the freepages array writable + * in /proc, but have to add a separate extra_free_target + * for people who require it to catch load spikes in eg. + * gigabit ethernet routing... + */ + freepages.min += mask; + freepages.low += mask*2; + freepages.high += mask*3; zone->zone_mem_map = mem_map + offset; zone->zone_start_mapnr = offset; zone->zone_start_paddr = zone_start_paddr; @@ -900,7 +895,7 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap, bitmap_size = (bitmap_size + 7) >> 3; bitmap_size = LONG_ALIGN(bitmap_size); zone->free_area[i].map = - (unsigned int *) alloc_bootmem_node(nid, bitmap_size); + (unsigned int *) alloc_bootmem_node(pgdat, bitmap_size); } } build_zonelists(pgdat); @@ -908,7 +903,7 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap, void __init free_area_init(unsigned long *zones_size) { - free_area_init_core(0, NODE_DATA(0), &mem_map, zones_size, 0, 0, 0); + free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 0, 0, 0); } static int __init setup_mem_frac(char *str) @@ -174,6 +174,7 @@ void deactivate_page_nolock(struct page * page) */ int maxcount = (page->buffers ? 3 : 2); page->age = 0; + ClearPageReferenced(page); /* * Don't touch it if it's not on the active list. diff --git a/mm/swapfile.c b/mm/swapfile.c index fa4cb133e..688e2fcdd 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -223,10 +223,10 @@ static inline void unuse_pte(struct vm_area_struct * vma, unsigned long address, if (pte_page(pte) != page) return; /* We will be removing the swap cache in a moment, so... */ - set_pte(dir, pte_mkdirty(pte)); + ptep_mkdirty(dir); return; } - if (pte_val(pte) != entry.val) + if (pte_to_swp_entry(pte).val != entry.val) return; set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot))); swap_free(entry); @@ -315,12 +315,12 @@ static void unuse_process(struct mm_struct * mm, */ if (!mm) return; - vmlist_access_lock(mm); + spin_lock(&mm->page_table_lock); for (vma = mm->mmap; vma; vma = vma->vm_next) { pgd_t * pgd = pgd_offset(mm, vma->vm_start); unuse_vma(vma, pgd, entry, page); } - vmlist_access_unlock(mm); + spin_unlock(&mm->page_table_lock); return; } diff --git a/mm/vmalloc.c b/mm/vmalloc.c index e8c557e04..15261612e 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -34,8 +34,8 @@ static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned lo if (end > PMD_SIZE) end = PMD_SIZE; do { - pte_t page = *pte; - pte_clear(pte); + pte_t page; + page = ptep_get_and_clear(pte); address += PAGE_SIZE; pte++; if (pte_none(page)) @@ -142,15 +142,14 @@ inline int vmalloc_area_pages (unsigned long address, unsigned long size, flush_cache_all(); do { pmd_t *pmd; - pgd_t olddir = *dir; pmd = pmd_alloc_kernel(dir, address); if (!pmd) return -ENOMEM; + if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot)) return -ENOMEM; - if (pgd_val(olddir) != pgd_val(*dir)) - set_pgdir(address, *dir); + address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); @@ -222,14 +221,11 @@ void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot) return NULL; } area = get_vm_area(size, VM_ALLOC); - if (!area) { - BUG(); + if (!area) return NULL; - } addr = area->addr; if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, gfp_mask, prot)) { vfree(addr); - BUG(); return NULL; } return addr; diff --git a/mm/vmscan.c b/mm/vmscan.c index aacd9a5b0..d7fd0aca8 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -55,22 +55,8 @@ static int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, un onlist = PageActive(page); /* Don't look at this pte if it's been accessed recently. */ - if (pte_young(pte)) { - set_pte(page_table, pte_mkold(pte)); - if (onlist) { - /* - * Transfer the "accessed" bit from the page - * tables to the global page map. Page aging - * will be done by refill_inactive_scan(). - */ - SetPageReferenced(page); - } else { - /* - * The page is not on the active list, so - * we have to do the page aging ourselves. - */ - age_page_up(page); - } + if (ptep_test_and_clear_young(page_table)) { + age_page_up(page); goto out_failed; } if (!onlist) @@ -88,6 +74,13 @@ static int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, un if (TryLockPage(page)) goto out_failed; + /* From this point on, the odds are that we're going to + * nuke this pte, so read and clear the pte. This hook + * is needed on CPUs which update the accessed and dirty + * bits in hardware. + */ + pte = ptep_get_and_clear(page_table); + /* * Is the page already in the swap cache? If so, then * we can just drop our reference to it without doing @@ -124,7 +117,6 @@ drop_pte: */ if (!pte_dirty(pte)) { flush_cache_page(vma, address); - pte_clear(page_table); goto drop_pte; } @@ -134,7 +126,7 @@ drop_pte: * locks etc. */ if (!(gfp_mask & __GFP_IO)) - goto out_unlock; + goto out_unlock_restore; /* * Don't do any of the expensive stuff if @@ -143,7 +135,7 @@ drop_pte: if (page->zone->free_pages + page->zone->inactive_clean_pages + page->zone->inactive_dirty_pages > page->zone->pages_high + inactive_target) - goto out_unlock; + goto out_unlock_restore; /* * Ok, it's really dirty. That means that @@ -169,10 +161,10 @@ drop_pte: int error; struct file *file = vma->vm_file; if (file) get_file(file); - pte_clear(page_table); + mm->rss--; flush_tlb_page(vma, address); - vmlist_access_unlock(mm); + spin_unlock(&mm->page_table_lock); error = swapout(page, file); UnlockPage(page); if (file) fput(file); @@ -191,7 +183,7 @@ drop_pte: */ entry = get_swap_page(); if (!entry.val) - goto out_unlock; /* No swap space left */ + goto out_unlock_restore; /* No swap space left */ if (!(page = prepare_highmem_swapout(page))) goto out_swap_free; @@ -205,7 +197,7 @@ drop_pte: mm->rss--; set_pte(page_table, swp_entry_to_pte(entry)); flush_tlb_page(vma, address); - vmlist_access_unlock(mm); + spin_unlock(&mm->page_table_lock); /* OK, do a physical asynchronous write to swap. */ rw_swap_page(WRITE, page, 0); @@ -215,10 +207,12 @@ out_free_success: page_cache_release(page); return 1; out_swap_free: + set_pte(page_table, pte); swap_free(entry); out_failed: return 0; -out_unlock: +out_unlock_restore: + set_pte(page_table, pte); UnlockPage(page); return 0; } @@ -307,7 +301,7 @@ static int swap_out_vma(struct mm_struct * mm, struct vm_area_struct * vma, unsi unsigned long end; /* Don't swap out areas which are locked down */ - if (vma->vm_flags & VM_LOCKED) + if (vma->vm_flags & (VM_LOCKED|VM_RESERVED)) return 0; pgdir = pgd_offset(mm, address); @@ -341,7 +335,7 @@ static int swap_out_mm(struct mm_struct * mm, int gfp_mask) * Find the proper vm-area after freezing the vma chain * and ptes. */ - vmlist_access_lock(mm); + spin_lock(&mm->page_table_lock); vma = find_vma(mm, address); if (vma) { if (address < vma->vm_start) @@ -364,7 +358,7 @@ static int swap_out_mm(struct mm_struct * mm, int gfp_mask) mm->swap_cnt = 0; out_unlock: - vmlist_access_unlock(mm); + spin_unlock(&mm->page_table_lock); /* We didn't find anything for the process */ return 0; @@ -790,7 +784,8 @@ int refill_inactive_scan(unsigned int priority, int oneshot) * * SUBTLE: we can have buffer pages with count 1. */ - if (page_count(page) <= (page->buffers ? 2 : 1)) { + if (page->age == 0 && page_count(page) <= + (page->buffers ? 2 : 1)) { deactivate_page_nolock(page); page_active = 0; } else { @@ -837,8 +832,9 @@ int free_shortage(void) for(i = 0; i < MAX_NR_ZONES; i++) { zone_t *zone = pgdat->node_zones+ i; if (zone->size && (zone->inactive_clean_pages + - zone->free_pages < zone->pages_min)) { - sum += zone->pages_min; + zone->free_pages < zone->pages_min+1)) { + /* + 1 to have overlap with alloc_pages() !! */ + sum += zone->pages_min + 1; sum -= zone->free_pages; sum -= zone->inactive_clean_pages; } @@ -1095,12 +1091,20 @@ int kswapd(void *unused) * We go to sleep for one second, but if it's needed * we'll be woken up earlier... */ - if (!free_shortage() || !inactive_shortage()) + if (!free_shortage() || !inactive_shortage()) { interruptible_sleep_on_timeout(&kswapd_wait, HZ); /* - * TODO: insert out of memory check & oom killer - * invocation in an else branch here. + * If we couldn't free enough memory, we see if it was + * due to the system just not having enough memory. + * If that is the case, the only solution is to kill + * a process (the alternative is enternal deadlock). + * + * If there still is enough memory around, we just loop + * and try free some more memory... */ + } else if (out_of_memory()) { + oom_kill(); + } } } diff --git a/net/802/llc_macinit.c b/net/802/llc_macinit.c index 792bfd5e8..987d8a5c4 100644 --- a/net/802/llc_macinit.c +++ b/net/802/llc_macinit.c @@ -204,24 +204,11 @@ EXPORT_SYMBOL(llc_cancel_timers); #define ALL_TYPES_8022 0 -void __init llc_init(struct net_proto *proto) +static int __init llc_init(void) { printk(KERN_NOTICE "IEEE 802.2 LLC for Linux 2.1 (c) 1996 Tim Alpaerts\n"); - return; -} - -#ifdef MODULE - - -int init_module(void) -{ - llc_init(NULL); return 0; } -void cleanup_module(void) -{ - -} -#endif +module_init(llc_init); diff --git a/net/802/p8022.c b/net/802/p8022.c index 9be3100dd..41a755e88 100644 --- a/net/802/p8022.c +++ b/net/802/p8022.c @@ -90,12 +90,15 @@ static struct packet_type p8022_packet_type = EXPORT_SYMBOL(register_8022_client); EXPORT_SYMBOL(unregister_8022_client); -void __init p8022_proto_init(struct net_proto *pro) +static int __init p8022_init(void) { p8022_packet_type.type=htons(ETH_P_802_2); dev_add_pack(&p8022_packet_type); + return 0; } +module_init(p8022_init); + struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *)) { struct datalink_proto *proto; diff --git a/net/802/psnap.c b/net/802/psnap.c index 3c493d7d9..907ac1b54 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c @@ -89,12 +89,14 @@ static void snap_datalink_header(struct datalink_proto *dl, struct sk_buff *skb, EXPORT_SYMBOL(register_snap_client); EXPORT_SYMBOL(unregister_snap_client); -void __init snap_proto_init(struct net_proto *pro) +static int __init snap_init(void) { snap_dl=register_8022_client(0xAA, snap_rcv); if(snap_dl==NULL) printk("SNAP - unable to register with 802.2\n"); + return 0; } +module_init(snap_init); /* * Register SNAP clients. We don't yet use this for IP. diff --git a/net/802/tr.c b/net/802/tr.c index 097929257..73c938486 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -540,7 +540,7 @@ static int rif_get_info(char *buffer,char **start, off_t offset, int length) * too much for this. */ -void __init rif_init(struct net_proto *unused) +static int __init rif_init(void) { rif_timer.expires = RIF_TIMEOUT; rif_timer.data = 0L; @@ -549,4 +549,7 @@ void __init rif_init(struct net_proto *unused) add_timer(&rif_timer); proc_net_create("tr_rif",0,rif_get_info); + return 0; } + +module_init(rif_init); diff --git a/net/Config.in b/net/Config.in index f383bbbd2..4d4f6c373 100644 --- a/net/Config.in +++ b/net/Config.in @@ -63,6 +63,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25 tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB bool '802.2 LLC (EXPERIMENTAL)' CONFIG_LLC + bool 'Frame Diverter (EXPERIMENTAL)' CONFIG_NET_DIVERT # if [ "$CONFIG_LLC" = "y" ]; then # bool ' Netbeui (EXPERIMENTAL)' CONFIG_NETBEUI # fi diff --git a/net/Makefile b/net/Makefile index 44f47fabc..ff79d8584 100644 --- a/net/Makefile +++ b/net/Makefile @@ -7,7 +7,7 @@ O_TARGET := network.o -mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm +mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink export-objs := netsyms.o subdir-y := core ethernet @@ -46,7 +46,7 @@ subdir-$(CONFIG_DECNET) += decnet subdir-$(CONFIG_ECONET) += econet -obj-y := socket.o protocols.o $(join $(subdir-y), $(patsubst %,/%.o,$(notdir $(subdir-y)))) +obj-y := socket.o $(join $(subdir-y), $(patsubst %,/%.o,$(notdir $(subdir-y)))) ifeq ($(CONFIG_NET),y) obj-$(CONFIG_MODULES) += netsyms.o obj-$(CONFIG_SYSCTL) += sysctl_net.o diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 260a5e530..e7784dabd 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -2120,7 +2120,7 @@ EXPORT_SYMBOL(atalk_find_dev_addr); /* Called by proto.c on kernel start up */ -void __init atalk_proto_init(struct net_proto *pro) +static int __init atalk_init(void) { (void) sock_register(&atalk_family_ops); if((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL) @@ -2148,16 +2148,11 @@ void __init atalk_proto_init(struct net_proto *pro) #endif /* CONFIG_SYSCTL */ printk(KERN_INFO "NET4: AppleTalk 0.18 for Linux NET4.0\n"); + return 0; } +module_init(atalk_init); #ifdef MODULE - -int init_module(void) -{ - atalk_proto_init(NULL); - return (0); -} - /* * Note on MOD_{INC,DEC}_USE_COUNT: * @@ -2171,7 +2166,7 @@ int init_module(void) * sockets be closed from user space. */ -void cleanup_module(void) +static void __exit atalk_exit(void) { #ifdef CONFIG_SYSCTL atalk_unregister_sysctl(); @@ -2195,6 +2190,7 @@ void cleanup_module(void) return; } - +module_exit(atalk_exit); #endif /* MODULE */ + #endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */ diff --git a/net/atm/pvc.c b/net/atm/pvc.c index fc71c2435..ff28ed551 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c @@ -123,7 +123,7 @@ static struct net_proto_family pvc_family_ops = { */ -void __init atmpvc_proto_init(struct net_proto *pro) +static int __init atmpvc_init(void) { int error; @@ -139,4 +139,7 @@ void __init atmpvc_proto_init(struct net_proto *pro) error = atm_proc_init(); if (error) printk("atm_proc_init fails with %d\n",error); #endif + return 0; } + +module_init(atmpvc_init); diff --git a/net/atm/svc.c b/net/atm/svc.c index bffe7aac5..7984cb22a 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c @@ -442,10 +442,13 @@ static struct net_proto_family svc_family_ops = { * Initialize the ATM SVC protocol family */ -void __init atmsvc_proto_init(struct net_proto *pro) +static int __init atmsvc_init(void) { if (sock_register(&svc_family_ops) < 0) { printk(KERN_ERR "ATMSVC: can't register"); - return; + return -1; } + return 0; } + +module_init(atmsvc_init); diff --git a/net/ax25/Config.in b/net/ax25/Config.in index 2670528b3..b8e5d7333 100644 --- a/net/ax25/Config.in +++ b/net/ax25/Config.in @@ -3,7 +3,7 @@ # # 19971130 Now in an own category to make correct compilation of the # AX.25 stuff easier... -# Joerg Reuter DL1BKE <jreuter@poboxes.com> +# Joerg Reuter DL1BKE <jreuter@yaina.de> # 19980129 Moved to net/ax25/Config.in, sourcing device drivers. mainmenu_option next_comment diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index fc8910f2d..8e34e42e2 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -101,6 +101,7 @@ * ax25_connect() and ax25_sendmsg() * Joerg(DL1BKE) Added support for SO_BINDTODEVICE * Arnaldo C. Melo s/suser/capable(CAP_NET_ADMIN)/, some more cleanups + * Michal Ostrowski Module initialization cleanup. */ #include <linux/config.h> @@ -137,6 +138,8 @@ #include <net/ip.h> #include <net/arp.h> + + ax25_cb *volatile ax25_list = NULL; static struct proto_ops ax25_proto_ops; @@ -1193,7 +1196,7 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le */ if (sk->zapped) { /* check if we can remove this feature. It is broken. */ - printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@poboxes.com\n", + printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@yaina.de\n", current->comm); if ((err = ax25_rt_autobind(sk->protinfo.ax25, &fsa->fsa_ax25.sax25_call)) < 0) return err; @@ -1844,7 +1847,7 @@ EXPORT_SYMBOL(asc2ax); EXPORT_SYMBOL(null_ax25_address); EXPORT_SYMBOL(ax25_display_timer); -void __init ax25_proto_init(struct net_proto *pro) +static int __init ax25_init(void) { sock_register(&ax25_family_ops); ax25_packet_type.type = htons(ETH_P_AX25); @@ -1861,20 +1864,16 @@ void __init ax25_proto_init(struct net_proto *pro) #endif printk(KERN_INFO "NET4: G4KLX/GW4PTS AX.25 for Linux. Version 0.37 for Linux NET4.0\n"); + return 0; } +module_init(ax25_init); + #ifdef MODULE MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>"); MODULE_DESCRIPTION("The amateur radio AX.25 link layer protocol"); -int init_module(void) -{ - ax25_proto_init(NULL); - - return 0; -} - -void cleanup_module(void) +static void __exit ax25_exit(void) { #ifdef CONFIG_PROC_FS proc_net_remove("ax25_route"); @@ -1895,6 +1894,7 @@ void cleanup_module(void) sock_unregister(PF_AX25); } -#endif +module_exit(ax25_exit); +#endif /* MODULE */ #endif diff --git a/net/ax25/ax25_ds_in.c b/net/ax25/ax25_ds_in.c index 464122823..3354206df 100644 --- a/net/ax25/ax25_ds_in.c +++ b/net/ax25/ax25_ds_in.c @@ -89,10 +89,8 @@ static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int framet ax25_dama_on(ax25); /* according to DK4EG´s spec we are required to - * send a RR RESPONSE FINAL NR=0. Please mail - * <jreuter@poboxes.com> if this causes problems - * with the TheNetNode DAMA Master implementation. - */ + * send a RR RESPONSE FINAL NR=0. + */ ax25_std_enquiry_response(ax25); break; diff --git a/net/bridge/br.c b/net/bridge/br.c index 3c6c9b72d..cda2e570a 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -5,7 +5,7 @@ * Authors: * Lennert Buytenhek <buytenh@gnu.org> * - * $Id: br.c,v 1.44 2000/08/04 06:08:32 davem Exp $ + * $Id: br.c,v 1.45 2000/10/22 18:26:07 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -38,7 +38,7 @@ void br_inc_use_count() MOD_INC_USE_COUNT; } -int __init br_init(void) +static int __init br_init(void) { printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n"); diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 86355509d..295cfc973 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -5,7 +5,7 @@ * Authors: * Lennert Buytenhek <buytenh@gnu.org> * - * $Id: br_if.c,v 1.3 2000/05/05 02:17:17 davem Exp $ + * $Id: br_if.c,v 1.4 2000/10/05 01:58:16 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -14,6 +14,7 @@ */ #include <linux/kernel.h> +#include <linux/if_arp.h> #include <linux/if_bridge.h> #include <linux/inetdevice.h> #include <linux/rtnetlink.h> @@ -222,7 +223,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) if (dev->br_port != NULL) return -EBUSY; - if (dev->flags & IFF_LOOPBACK) + if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER) return -EINVAL; dev_hold(dev); diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index dad96fb99..4d04aec66 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -5,7 +5,7 @@ * Authors: * Lennert Buytenhek <buytenh@gnu.org> * - * $Id: br_ioctl.c,v 1.2 2000/02/21 15:51:34 davem Exp $ + * $Id: br_ioctl.c,v 1.3 2000/10/05 01:58:16 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -138,7 +138,7 @@ static int br_ioctl_device(struct net_bridge *br, p.hold_timer_value = br_timer_get_residue(&pt->hold_timer); if (copy_to_user((void *)arg0, &p, sizeof(p))) - return -EINVAL; + return -EFAULT; return 0; } diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h index 91faafff5..2857d5c91 100644 --- a/net/bridge/br_private_stp.h +++ b/net/bridge/br_private_stp.h @@ -4,7 +4,7 @@ * Authors: * Lennert Buytenhek <buytenh@gnu.org> * - * $Id: br_private_stp.h,v 1.1 2000/02/18 16:47:13 davem Exp $ + * $Id: br_private_stp.h,v 1.2 2000/10/30 22:03:20 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,7 +16,7 @@ #define _BR_PRIVATE_STP_H #define BPDU_TYPE_CONFIG 0 -#define BPDU_TYPE_TCN 1 +#define BPDU_TYPE_TCN 0x80 struct br_config_bpdu { diff --git a/net/core/Makefile b/net/core/Makefile index 7ee0db3fd..af3c74091 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -29,6 +29,10 @@ ifdef CONFIG_NETFILTER OX_OBJS += netfilter.o endif +ifeq ($(CONFIG_NET_DIVERT),y) +O_OBJS += dv.o +endif + endif ifdef CONFIG_NET_PROFILE diff --git a/net/core/dev.c b/net/core/dev.c index e6f440cf4..17fae7a1e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -59,6 +59,8 @@ * Paul Rusty Russell : SIOCSIFNAME * Pekka Riikonen : Netdev boot-time settings code * Andrew Morton : Make unregister_netdevice wait indefinitely on dev->refcnt + * J Hadi Salim : - Backlog queue sampling + * - netif_rx() feedback */ #include <asm/uaccess.h> @@ -85,6 +87,7 @@ #include <linux/proc_fs.h> #include <linux/stat.h> #include <linux/if_bridge.h> +#include <linux/divert.h> #include <net/dst.h> #include <net/pkt_sched.h> #include <net/profile.h> @@ -97,6 +100,18 @@ extern int plip_init(void); #endif +/* This define, if set, will randomly drop a packet when congestion + * is more than moderate. It helps fairness in the multi-interface + * case when one of them is a hog, but it kills performance for the + * single interface case so it is off now by default. + */ +#undef RAND_LIE + +/* Setting this will sample the queue lengths and thus congestion + * via a timer instead of as each packet is received. + */ +#undef OFFLINE_SAMPLE + NET_PROFILE_DEFINE(dev_queue_xmit) NET_PROFILE_DEFINE(softnet_process) @@ -133,6 +148,11 @@ const char *if_port_text[] = { static struct packet_type *ptype_base[16]; /* 16 way hashed list */ static struct packet_type *ptype_all = NULL; /* Taps */ +#ifdef OFFLINE_SAMPLE +static void sample_queue(unsigned long dummy); +static struct timer_list samp_timer = { function: sample_queue }; +#endif + /* * Our notifier list */ @@ -933,12 +953,20 @@ int dev_queue_xmit(struct sk_buff *skb) =======================================================================*/ int netdev_max_backlog = 300; +/* These numbers are selected based on intuition and some + * experimentatiom, if you have more scientific way of doing this + * please go ahead and fix things. + */ +int no_cong_thresh = 10; +int no_cong = 20; +int lo_cong = 100; +int mod_cong = 290; struct netif_rx_stats netdev_rx_stat[NR_CPUS]; #ifdef CONFIG_NET_HW_FLOWCONTROL -static atomic_t netdev_dropping = ATOMIC_INIT(0); +atomic_t netdev_dropping = ATOMIC_INIT(0); static unsigned long netdev_fc_mask = 1; unsigned long netdev_fc_xoff = 0; spinlock_t netdev_fc_lock = SPIN_LOCK_UNLOCKED; @@ -996,6 +1024,56 @@ static void netdev_wakeup(void) } #endif +static void get_sample_stats(int cpu) +{ +#ifdef RAND_LIE + unsigned long rd; + int rq; +#endif + int blog = softnet_data[cpu].input_pkt_queue.qlen; + int avg_blog = softnet_data[cpu].avg_blog; + + avg_blog = (avg_blog >> 1)+ (blog >> 1); + + if (avg_blog > mod_cong) { + /* Above moderate congestion levels. */ + softnet_data[cpu].cng_level = NET_RX_CN_HIGH; +#ifdef RAND_LIE + rd = net_random(); + rq = rd % netdev_max_backlog; + if (rq < avg_blog) /* unlucky bastard */ + softnet_data[cpu].cng_level = NET_RX_DROP; +#endif + } else if (avg_blog > lo_cong) { + softnet_data[cpu].cng_level = NET_RX_CN_MOD; +#ifdef RAND_LIE + rd = net_random(); + rq = rd % netdev_max_backlog; + if (rq < avg_blog) /* unlucky bastard */ + softnet_data[cpu].cng_level = NET_RX_CN_HIGH; +#endif + } else if (avg_blog > no_cong) + softnet_data[cpu].cng_level = NET_RX_CN_LOW; + else /* no congestion */ + softnet_data[cpu].cng_level = NET_RX_SUCCESS; + + softnet_data[cpu].avg_blog = avg_blog; +} + +#ifdef OFFLINE_SAMPLE +static void sample_queue(unsigned long dummy) +{ +/* 10 ms 0r 1ms -- i dont care -- JHS */ + int next_tick = 1; + int cpu = smp_processor_id(); + + get_sample_stats(cpu); + next_tick += jiffies; + mod_timer(&samp_timer, next_tick); +} +#endif + + /** * netif_rx - post buffer to the network code * @skb: buffer to post @@ -1004,9 +1082,18 @@ static void netdev_wakeup(void) * the upper (protocol) levels to process. It always succeeds. The buffer * may be dropped during processing for congestion control or by the * protocol layers. + * + * return values: + * NET_RX_SUCCESS (no congestion) + * NET_RX_CN_LOW (low congestion) + * NET_RX_CN_MOD (moderate congestion) + * NET_RX_CN_HIGH (high congestion) + * NET_RX_DROP (packet was dropped) + * + * */ -void netif_rx(struct sk_buff *skb) +int netif_rx(struct sk_buff *skb) { int this_cpu = smp_processor_id(); struct softnet_data *queue; @@ -1036,7 +1123,10 @@ enqueue: __skb_queue_tail(&queue->input_pkt_queue,skb); __cpu_raise_softirq(this_cpu, NET_RX_SOFTIRQ); local_irq_restore(flags); - return; +#ifndef OFFLINE_SAMPLE + get_sample_stats(this_cpu); +#endif + return softnet_data[this_cpu].cng_level; } if (queue->throttle) { @@ -1062,19 +1152,22 @@ drop: local_irq_restore(flags); kfree_skb(skb); + return NET_RX_DROP; } /* Deliver skb to an old protocol, which is not threaded well or which do not understand shared skbs. */ -static void deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int last) +static int deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int last) { static spinlock_t net_bh_lock = SPIN_LOCK_UNLOCKED; + int ret = NET_RX_DROP; + if (!last) { skb = skb_clone(skb, GFP_ATOMIC); if (skb == NULL) - return; + return ret; } /* The assumption (correct one) is that old protocols @@ -1087,10 +1180,11 @@ static void deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int /* Disable timers and wait for all timers completion */ tasklet_disable(bh_task_vec+TIMER_BH); - pt->func(skb, skb->dev, pt); + ret = pt->func(skb, skb->dev, pt); tasklet_enable(bh_task_vec+TIMER_BH); spin_unlock(&net_bh_lock); + return ret; } /* Reparent skb to master device. This function is called @@ -1173,22 +1267,35 @@ void net_call_rx_atomic(void (*fn)(void)) void (*br_handle_frame_hook)(struct sk_buff *skb) = NULL; #endif -static void __inline__ handle_bridge(struct sk_buff *skb, +static int __inline__ handle_bridge(struct sk_buff *skb, struct packet_type *pt_prev) { + int ret = NET_RX_DROP; + if (pt_prev) { if (!pt_prev->data) - deliver_to_old_ones(pt_prev, skb, 0); + ret = deliver_to_old_ones(pt_prev, skb, 0); else { atomic_inc(&skb->users); - pt_prev->func(skb, skb->dev, pt_prev); + ret = pt_prev->func(skb, skb->dev, pt_prev); } } br_handle_frame_hook(skb); + return ret; } +#ifdef CONFIG_NET_DIVERT +static inline void handle_diverter(struct sk_buff *skb) +{ + /* if diversion is supported on device, then divert */ + if (skb->dev->divert && skb->dev->divert->divert) + divert_frame(skb); +} +#endif /* CONFIG_NET_DIVERT */ + + static void net_rx_action(struct softirq_action *h) { int this_cpu = smp_processor_id(); @@ -1239,6 +1346,12 @@ static void net_rx_action(struct softirq_action *h) } } +#ifdef CONFIG_NET_DIVERT + if (skb->dev->divert && skb->dev->divert->divert) + handle_diverter(skb); +#endif /* CONFIG_NET_DIVERT */ + + #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) if (skb->dev->br_port != NULL && br_handle_frame_hook != NULL) { @@ -1275,6 +1388,17 @@ static void net_rx_action(struct softirq_action *h) if (bugdet-- < 0 || jiffies - start_time > 1) goto softnet_break; + +#ifdef CONFIG_NET_HW_FLOWCONTROL + if (queue->throttle && queue->input_pkt_queue.qlen < no_cong_thresh ) { + if (atomic_dec_and_test(&netdev_dropping)) { + queue->throttle = 0; + netdev_wakeup(); + goto softnet_break; + } + } +#endif + } br_read_unlock(BR_NETPROTO_LOCK); @@ -2113,9 +2237,9 @@ int dev_ioctl(unsigned int cmd, void *arg) /** * dev_new_index - allocate an ifindex * - * Returns a suitable unique value for a new device interface number. - * The caller must hold the rtnl semaphore to be sure it remains - * unique. + * Returns a suitable unique value for a new device interface + * number. The caller must hold the rtnl semaphore or the + * dev_base_lock to be sure it remains unique. */ int dev_new_index(void) @@ -2140,6 +2264,10 @@ static int dev_boot_phase = 1; * chain. 0 is returned on success. A negative errno code is returned * on a failure to set up the device, or if the name is a duplicate. * + * Callers must hold the rtnl semaphore. See the comment at the + * end of Space.c for details about the locking. You may want + * register_netdev() instead of this. + * * BUGS: * The locking appears insufficient to guarantee two parallel registers * will not get the same name. @@ -2148,6 +2276,9 @@ static int dev_boot_phase = 1; int register_netdevice(struct net_device *dev) { struct net_device *d, **dp; +#ifdef CONFIG_NET_DIVERT + int ret; +#endif spin_lock_init(&dev->queue_lock); spin_lock_init(&dev->xmit_lock); @@ -2182,6 +2313,12 @@ int register_netdevice(struct net_device *dev) dev_hold(dev); write_unlock_bh(&dev_base_lock); +#ifdef CONFIG_NET_DIVERT + ret = alloc_divert_blk(dev); + if (ret) + return ret; +#endif /* CONFIG_NET_DIVERT */ + /* * Default initial state at registry is that the * device is present. @@ -2231,6 +2368,12 @@ int register_netdevice(struct net_device *dev) dev->deadbeaf = 0; write_unlock_bh(&dev_base_lock); +#ifdef CONFIG_NET_DIVERT + ret = alloc_divert_blk(dev); + if (ret) + return ret; +#endif /* CONFIG_NET_DIVERT */ + /* Notify protocols, that a new device appeared. */ notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); @@ -2272,6 +2415,10 @@ int netdev_finish_unregister(struct net_device *dev) * This function shuts down a device interface and removes it * from the kernel tables. On success 0 is returned, on a failure * a negative errno code is returned. + * + * Callers must hold the rtnl semaphore. See the comment at the + * end of Space.c for details about the locking. You may want + * unregister_netdev() instead of this. */ int unregister_netdevice(struct net_device *dev) @@ -2325,6 +2472,10 @@ int unregister_netdevice(struct net_device *dev) /* Notifier chain MUST detach us from master device. */ BUG_TRAP(dev->master==NULL); +#ifdef CONFIG_NET_DIVERT + free_divert_blk(dev); +#endif + if (dev->new_style) { #ifdef NET_REFCNT_DEBUG if (atomic_read(&dev->refcnt) != 1) @@ -2397,7 +2548,15 @@ int unregister_netdevice(struct net_device *dev) extern void net_device_init(void); extern void ip_auto_config(void); +#ifdef CONFIG_NET_DIVERT +extern void dv_init(void); +#endif /* CONFIG_NET_DIVERT */ + +/* + * Callers must hold the rtnl semaphore. See the comment at the + * end of Space.c for details about the locking. + */ int __init net_dev_init(void) { struct net_device *dev, **dp; @@ -2407,6 +2566,10 @@ int __init net_dev_init(void) pktsched_init(); #endif +#ifdef CONFIG_NET_DIVERT + dv_init(); +#endif /* CONFIG_NET_DIVERT */ + /* * Initialise the packet receive queues. */ @@ -2417,6 +2580,8 @@ int __init net_dev_init(void) queue = &softnet_data[i]; skb_queue_head_init(&queue->input_pkt_queue); queue->throttle = 0; + queue->cng_level = 0; + queue->avg_blog = 10; /* arbitrary non-zero */ queue->completion_queue = NULL; } @@ -2425,6 +2590,12 @@ int __init net_dev_init(void) NET_PROFILE_REGISTER(dev_queue_xmit); NET_PROFILE_REGISTER(softnet_process); #endif + +#ifdef OFFLINE_SAMPLE + samp_timer.expires = jiffies + (10 * HZ); + add_timer(&samp_timer); +#endif + /* * Add the devices. * If the call to dev->init fails, the dev is removed diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index cf590db04..6b24a1416 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -13,6 +13,7 @@ * rather than any time but... * Alan Cox : IFF_ALLMULTI support. * Alan Cox : New format set_multicast_list() calls. + * Gleb Natapov : Remove dev_mc_lock. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -59,16 +60,14 @@ * Device mc lists are changed by bh at least if IPv6 is enabled, * so that it must be bh protected. * - * We protect all mc lists with global rw lock - * and block accesses to device mc filters with dev->xmit_lock. + * We block accesses to device mc filters with dev->xmit_lock. */ -static rwlock_t dev_mc_lock = RW_LOCK_UNLOCKED; /* * Update the multicast list into the physical NIC controller. */ -void dev_mc_upload(struct net_device *dev) +static void __dev_mc_upload(struct net_device *dev) { /* Don't do anything till we up the interface * [dev_open will call this function so the list will @@ -87,13 +86,14 @@ void dev_mc_upload(struct net_device *dev) !netif_device_present(dev)) return; - read_lock_bh(&dev_mc_lock); - spin_lock(&dev->xmit_lock); - dev->xmit_lock_owner = smp_processor_id(); dev->set_multicast_list(dev); - dev->xmit_lock_owner = -1; - spin_unlock(&dev->xmit_lock); - read_unlock_bh(&dev_mc_lock); +} + +void dev_mc_upload(struct net_device *dev) +{ + spin_lock_bh(&dev->xmit_lock); + __dev_mc_upload(dev); + spin_unlock_bh(&dev->xmit_lock); } /* @@ -105,7 +105,8 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) int err = 0; struct dev_mc_list *dmi, **dmip; - write_lock_bh(&dev_mc_lock); + spin_lock_bh(&dev->xmit_lock); + for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) { /* * Find the entry we want to delete. The device could @@ -127,7 +128,6 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) */ *dmip = dmi->next; dev->mc_count--; - write_unlock_bh(&dev_mc_lock); kfree(dmi); @@ -135,13 +135,15 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) * We have altered the list, so the card * loaded filter is now wrong. Fix it */ - dev_mc_upload(dev); + __dev_mc_upload(dev); + + spin_unlock_bh(&dev->xmit_lock); return 0; } } err = -ENOENT; done: - write_unlock_bh(&dev_mc_lock); + spin_unlock_bh(&dev->xmit_lock); return err; } @@ -156,7 +158,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) dmi1 = (struct dev_mc_list *)kmalloc(sizeof(*dmi), GFP_ATOMIC); - write_lock_bh(&dev_mc_lock); + spin_lock_bh(&dev->xmit_lock); for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) { if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 && dmi->dmi_addrlen == alen) { @@ -172,7 +174,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) } if ((dmi = dmi1) == NULL) { - write_unlock_bh(&dev_mc_lock); + spin_unlock_bh(&dev->xmit_lock); return -ENOMEM; } memcpy(dmi->dmi_addr, addr, alen); @@ -182,12 +184,14 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) dmi->dmi_gusers = glbl ? 1 : 0; dev->mc_list = dmi; dev->mc_count++; - write_unlock_bh(&dev_mc_lock); - dev_mc_upload(dev); + + __dev_mc_upload(dev); + + spin_unlock_bh(&dev->xmit_lock); return 0; done: - write_unlock_bh(&dev_mc_lock); + spin_unlock_bh(&dev->xmit_lock); if (dmi1) kfree(dmi1); return err; @@ -199,7 +203,8 @@ done: void dev_mc_discard(struct net_device *dev) { - write_lock_bh(&dev_mc_lock); + spin_lock_bh(&dev->xmit_lock); + while (dev->mc_list != NULL) { struct dev_mc_list *tmp = dev->mc_list; dev->mc_list = tmp->next; @@ -208,7 +213,8 @@ void dev_mc_discard(struct net_device *dev) kfree(tmp); } dev->mc_count = 0; - write_unlock_bh(&dev_mc_lock); + + spin_unlock_bh(&dev->xmit_lock); } #ifdef CONFIG_PROC_FS @@ -222,7 +228,7 @@ static int dev_mc_read_proc(char *buffer, char **start, off_t offset, read_lock(&dev_base_lock); for (dev = dev_base; dev; dev = dev->next) { - read_lock_bh(&dev_mc_lock); + spin_lock_bh(&dev->xmit_lock); for (m = dev->mc_list; m; m = m->next) { int i; @@ -240,11 +246,11 @@ static int dev_mc_read_proc(char *buffer, char **start, off_t offset, begin = pos; } if (pos > offset + length) { - read_unlock_bh(&dev_mc_lock); + spin_unlock_bh(&dev->xmit_lock); goto done; } } - read_unlock_bh(&dev_mc_lock); + spin_unlock_bh(&dev->xmit_lock); } *eof = 1; diff --git a/net/core/dv.c b/net/core/dv.c new file mode 100644 index 000000000..4df7747b8 --- /dev/null +++ b/net/core/dv.c @@ -0,0 +1,551 @@ +/* + * 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. + * + * Generic frame diversion + * + * Version: @(#)eth.c 0.41 09/09/2000 + * + * Authors: + * Benoit LOCHER: initial integration within the kernel with support for ethernet + * Dave Miller: improvement on the code (correctness, performance and source files) + * + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/socket.h> +#include <linux/in.h> +#include <linux/inet.h> +#include <linux/ip.h> +#include <linux/udp.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <net/dst.h> +#include <net/arp.h> +#include <net/sock.h> +#include <net/ipv6.h> +#include <net/ip.h> +#include <asm/uaccess.h> +#include <asm/system.h> +#include <asm/checksum.h> +#include <linux/divert.h> +#include <linux/sockios.h> + +const char sysctl_divert_version[32]="0.46"; /* Current version */ + +int __init dv_init(void) +{ + printk(KERN_INFO "NET4: Frame Diverter %s\n", sysctl_divert_version); + return 0; +} + +/* + * Allocate a divert_blk for a device. This must be an ethernet nic. + */ +int alloc_divert_blk(struct net_device *dev) +{ + int alloc_size = (sizeof(struct divert_blk) + 3) & ~3; + + if (!strncmp(dev->name, "eth", 3)) { + printk(KERN_DEBUG "divert: allocating divert_blk for %s\n", + dev->name); + + dev->divert = (struct divert_blk *) + kmalloc(alloc_size, GFP_KERNEL); + if (dev->divert == NULL) { + printk(KERN_DEBUG "divert: unable to allocate divert_blk for %s\n", + dev->name); + return -EFAULT; + } else { + memset(dev->divert, 0, sizeof(struct divert_blk)); + } + } else { + printk(KERN_DEBUG "divert: not allocating divert_blk for non-ethernet device %s\n", + dev->name); + + dev->divert = NULL; + } + return 0; +} + +/* + * Free a divert_blk allocated by the above function, if it was + * allocated on that device. + */ +void free_divert_blk(struct net_device *dev) +{ + if (dev->divert) { + kfree(dev->divert); + dev->divert=NULL; + printk(KERN_DEBUG "divert: freeing divert_blk for %s\n", + dev->name); + } else { + printk(KERN_DEBUG "divert: no divert_blk to free, %s not ethernet\n", + dev->name); + } +} + +/* + * Adds a tcp/udp (source or dest) port to an array + */ +int add_port(u16 ports[], u16 port) +{ + int i; + + if (port == 0) + return -EINVAL; + + /* Storing directly in network format for performance, + * thanks Dave :) + */ + port = htons(port); + + for (i = 0; i < MAX_DIVERT_PORTS; i++) { + if (ports[i] == port) + return -EALREADY; + } + + for (i = 0; i < MAX_DIVERT_PORTS; i++) { + if (ports[i] == 0) { + ports[i] = port; + return 0; + } + } + + return -ENOBUFS; +} + +/* + * Removes a port from an array tcp/udp (source or dest) + */ +int remove_port(u16 ports[], u16 port) +{ + int i; + + if (port == 0) + return -EINVAL; + + /* Storing directly in network format for performance, + * thanks Dave ! + */ + port = htons(port); + + for (i = 0; i < MAX_DIVERT_PORTS; i++) { + if (ports[i] == port) { + ports[i] = 0; + return 0; + } + } + + return -EINVAL; +} + +/* Some basic sanity checks on the arguments passed to divert_ioctl() */ +int check_args(struct divert_cf *div_cf, struct net_device **dev) +{ + char devname[32]; + + if (dev == NULL) + return -EFAULT; + + /* GETVERSION: all other args are unused */ + if (div_cf->cmd == DIVCMD_GETVERSION) + return 0; + + /* Network device index should reasonably be between 0 and 1000 :) */ + if (div_cf->dev_index < 0 || div_cf->dev_index > 1000) + return -EINVAL; + + /* Let's try to find the ifname */ + sprintf(devname, "eth%d", div_cf->dev_index); + *dev = dev_get_by_name(devname); + + /* dev should NOT be null */ + if (*dev == NULL) + return -EINVAL; + + /* user issuing the ioctl must be a super one :) */ + if (!suser()) + return -EPERM; + + /* Device must have a divert_blk member NOT null */ + if ((*dev)->divert == NULL) + return -EFAULT; + + return 0; +} + +/* + * control function of the diverter + */ +#define DVDBG(a) \ + printk(KERN_DEBUG "divert_ioctl() line %d %s\n", __LINE__, (a)) + +int divert_ioctl(unsigned int cmd, struct divert_cf *arg) +{ + struct divert_cf div_cf; + struct divert_blk *div_blk; + struct net_device *dev; + int ret; + + switch (cmd) { + case SIOCGIFDIVERT: + DVDBG("SIOCGIFDIVERT, copy_from_user"); + if (copy_from_user(&div_cf, arg, sizeof(struct divert_cf))) + return -EFAULT; + DVDBG("before check_args"); + ret = check_args(&div_cf, &dev); + if (ret) + return ret; + DVDBG("after checkargs"); + div_blk = dev->divert; + + DVDBG("befre switch()"); + switch (div_cf.cmd) { + case DIVCMD_GETSTATUS: + /* Now, just give the user the raw divert block + * for him to play with :) + */ + if (copy_to_user(div_cf.arg1.ptr, dev->divert, + sizeof(struct divert_blk))) + return -EFAULT; + break; + + case DIVCMD_GETVERSION: + DVDBG("GETVERSION: checking ptr"); + if (div_cf.arg1.ptr == NULL) + return -EINVAL; + DVDBG("GETVERSION: copying data to userland"); + if (copy_to_user(div_cf.arg1.ptr, + sysctl_divert_version, 32)) + return -EFAULT; + DVDBG("GETVERSION: data copied"); + break; + + default: + return -EINVAL; + }; + + break; + + case SIOCSIFDIVERT: + if (copy_from_user(&div_cf, arg, sizeof(struct divert_cf))) + return -EFAULT; + + ret = check_args(&div_cf, &dev); + if (ret) + return ret; + + div_blk = dev->divert; + + switch(div_cf.cmd) { + case DIVCMD_RESET: + div_blk->divert = 0; + div_blk->protos = DIVERT_PROTO_NONE; + memset(div_blk->tcp_dst, 0, + MAX_DIVERT_PORTS * sizeof(u16)); + memset(div_blk->tcp_src, 0, + MAX_DIVERT_PORTS * sizeof(u16)); + memset(div_blk->udp_dst, 0, + MAX_DIVERT_PORTS * sizeof(u16)); + memset(div_blk->udp_src, 0, + MAX_DIVERT_PORTS * sizeof(u16)); + return 0; + + case DIVCMD_DIVERT: + switch(div_cf.arg1.int32) { + case DIVARG1_ENABLE: + if (div_blk->divert) + return -EALREADY; + div_blk->divert = 1; + break; + + case DIVARG1_DISABLE: + if (!div_blk->divert) + return -EALREADY; + div_blk->divert = 0; + break; + + default: + return -EINVAL; + }; + + break; + + case DIVCMD_IP: + switch(div_cf.arg1.int32) { + case DIVARG1_ENABLE: + if (div_blk->protos & DIVERT_PROTO_IP) + return -EALREADY; + div_blk->protos |= DIVERT_PROTO_IP; + break; + + case DIVARG1_DISABLE: + if (!(div_blk->protos & DIVERT_PROTO_IP)) + return -EALREADY; + div_blk->protos &= ~DIVERT_PROTO_IP; + break; + + default: + return -EINVAL; + }; + + break; + + case DIVCMD_TCP: + switch(div_cf.arg1.int32) { + case DIVARG1_ENABLE: + if (div_blk->protos & DIVERT_PROTO_TCP) + return -EALREADY; + div_blk->protos |= DIVERT_PROTO_TCP; + break; + + case DIVARG1_DISABLE: + if (!(div_blk->protos & DIVERT_PROTO_TCP)) + return -EALREADY; + div_blk->protos &= ~DIVERT_PROTO_TCP; + break; + + default: + return -EINVAL; + }; + + break; + + case DIVCMD_TCPDST: + switch(div_cf.arg1.int32) { + case DIVARG1_ADD: + return add_port(div_blk->tcp_dst, + div_cf.arg2.uint16); + + case DIVARG1_REMOVE: + return remove_port(div_blk->tcp_dst, + div_cf.arg2.uint16); + + default: + return -EINVAL; + }; + + break; + + case DIVCMD_TCPSRC: + switch(div_cf.arg1.int32) { + case DIVARG1_ADD: + return add_port(div_blk->tcp_src, + div_cf.arg2.uint16); + + case DIVARG1_REMOVE: + return remove_port(div_blk->tcp_src, + div_cf.arg2.uint16); + + default: + return -EINVAL; + }; + + break; + + case DIVCMD_UDP: + switch(div_cf.arg1.int32) { + case DIVARG1_ENABLE: + if (div_blk->protos & DIVERT_PROTO_UDP) + return -EALREADY; + div_blk->protos |= DIVERT_PROTO_UDP; + break; + + case DIVARG1_DISABLE: + if (!(div_blk->protos & DIVERT_PROTO_UDP)) + return -EALREADY; + div_blk->protos &= ~DIVERT_PROTO_UDP; + break; + + default: + return -EINVAL; + }; + + break; + + case DIVCMD_UDPDST: + switch(div_cf.arg1.int32) { + case DIVARG1_ADD: + return add_port(div_blk->udp_dst, + div_cf.arg2.uint16); + + case DIVARG1_REMOVE: + return remove_port(div_blk->udp_dst, + div_cf.arg2.uint16); + + default: + return -EINVAL; + }; + + break; + + case DIVCMD_UDPSRC: + switch(div_cf.arg1.int32) { + case DIVARG1_ADD: + return add_port(div_blk->udp_src, + div_cf.arg2.uint16); + + case DIVARG1_REMOVE: + return remove_port(div_blk->udp_src, + div_cf.arg2.uint16); + + default: + return -EINVAL; + }; + + break; + + case DIVCMD_ICMP: + switch(div_cf.arg1.int32) { + case DIVARG1_ENABLE: + if (div_blk->protos & DIVERT_PROTO_ICMP) + return -EALREADY; + div_blk->protos |= DIVERT_PROTO_ICMP; + break; + + case DIVARG1_DISABLE: + if (!(div_blk->protos & DIVERT_PROTO_ICMP)) + return -EALREADY; + div_blk->protos &= ~DIVERT_PROTO_ICMP; + break; + + default: + return -EINVAL; + }; + + break; + + default: + return -EINVAL; + }; + + break; + + default: + return -EINVAL; + }; + + return 0; +} + + +/* + * Check if packet should have its dest mac address set to the box itself + * for diversion + */ + +#define ETH_DIVERT_FRAME(skb) \ + memcpy(skb->mac.ethernet, skb->dev->dev_addr, ETH_ALEN); \ + skb->pkt_type=PACKET_HOST + +void divert_frame(struct sk_buff *skb) +{ + struct ethhdr *eth = skb->mac.ethernet; + struct iphdr *iph; + struct tcphdr *tcph; + struct udphdr *udph; + struct divert_blk *divert = skb->dev->divert; + int i, src, dst; + unsigned char *skb_data_end = skb->data + skb->len; + + /* Packet is already aimed at us, return */ + if (!memcmp(eth, skb->dev->dev_addr, ETH_ALEN)) + return; + + /* proto is not IP, do nothing */ + if (eth->h_proto != htons(ETH_P_IP)) + return; + + /* Divert all IP frames ? */ + if (divert->protos & DIVERT_PROTO_IP) { + ETH_DIVERT_FRAME(skb); + return; + } + + /* Check for possible (maliciously) malformed IP frame (thanks Dave) */ + iph = (struct iphdr *) skb->data; + if (((iph->ihl<<2)+(unsigned char*)(iph)) >= skb_data_end) { + printk(KERN_INFO "divert: malformed IP packet !\n"); + return; + } + + switch (iph->protocol) { + /* Divert all ICMP frames ? */ + case IPPROTO_ICMP: + if (divert->protos & DIVERT_PROTO_ICMP) { + ETH_DIVERT_FRAME(skb); + return; + } + break; + + /* Divert all TCP frames ? */ + case IPPROTO_TCP: + if (divert->protos & DIVERT_PROTO_TCP) { + ETH_DIVERT_FRAME(skb); + return; + } + + /* Check for possible (maliciously) malformed IP + * frame (thanx Dave) + */ + tcph = (struct tcphdr *) + (((unsigned char *)iph) + (iph->ihl<<2)); + if (((unsigned char *)(tcph+1)) >= skb_data_end) { + printk(KERN_INFO "divert: malformed TCP packet !\n"); + return; + } + + /* Divert some tcp dst/src ports only ?*/ + for (i = 0; i < MAX_DIVERT_PORTS; i++) { + dst = divert->tcp_dst[i]; + src = divert->tcp_src[i]; + if ((dst && dst == tcph->dest) || + (src && src == tcph->source)) { + ETH_DIVERT_FRAME(skb); + return; + } + } + break; + + /* Divert all UDP frames ? */ + case IPPROTO_UDP: + if (divert->protos & DIVERT_PROTO_UDP) { + ETH_DIVERT_FRAME(skb); + return; + } + + /* Check for possible (maliciously) malformed IP + * packet (thanks Dave) + */ + udph = (struct udphdr *) + (((unsigned char *)iph) + (iph->ihl<<2)); + if (((unsigned char *)(udph+1)) >= skb_data_end) { + printk(KERN_INFO + "divert: malformed UDP packet !\n"); + return; + } + + /* Divert some udp dst/src ports only ? */ + for (i = 0; i < MAX_DIVERT_PORTS; i++) { + dst = divert->udp_dst[i]; + src = divert->udp_src[i]; + if ((dst && dst == udph->dest) || + (src && src == udph->source)) { + ETH_DIVERT_FRAME(skb); + return; + } + } + break; + }; + + return; +} + diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 4ea599a88..2f6090a2f 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -12,6 +12,10 @@ #ifdef CONFIG_SYSCTL extern int netdev_max_backlog; +extern int no_cong_thresh; +extern int no_cong; +extern int lo_cong; +extern int mod_cong; extern int netdev_fastroute; extern int net_msg_cost; extern int net_msg_burst; @@ -25,6 +29,10 @@ extern int sysctl_core_destroy_delay; extern int sysctl_optmem_max; extern int sysctl_hot_list_len; +#ifdef CONFIG_NET_DIVERT +extern char sysctl_divert_version[]; +#endif /* CONFIG_NET_DIVERT */ + ctl_table core_table[] = { #ifdef CONFIG_NET {NET_CORE_WMEM_MAX, "wmem_max", @@ -42,6 +50,18 @@ ctl_table core_table[] = { {NET_CORE_MAX_BACKLOG, "netdev_max_backlog", &netdev_max_backlog, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_CORE_NO_CONG_THRESH, "no_cong_thresh", + &no_cong, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_CORE_NO_CONG, "no_cong", + &no_cong, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_CORE_LO_CONG, "lo_cong", + &lo_cong, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_CORE_MOD_CONG, "mod_cong", + &mod_cong, sizeof(int), 0644, NULL, + &proc_dointvec}, #ifdef CONFIG_NET_FASTROUTE {NET_CORE_FASTROUTE, "netdev_fastroute", &netdev_fastroute, sizeof(int), 0644, NULL, @@ -59,6 +79,11 @@ ctl_table core_table[] = { {NET_CORE_HOT_LIST_LENGTH, "hot_list_length", &sysctl_hot_list_len, sizeof(int), 0644, NULL, &proc_dointvec}, +#ifdef CONFIG_NET_DIVERT + {NET_CORE_DIVERT_VERSION, "divert_version", + (void *)sysctl_divert_version, 32, 0444, NULL, + &proc_dostring}, +#endif /* CONFIG_NET_DIVERT */ #endif /* CONFIG_NET */ { 0 } }; diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 348c30fce..8de443979 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -2053,8 +2053,36 @@ void dn_register_sysctl(void); void dn_unregister_sysctl(void); #endif -void __init decnet_proto_init(struct net_proto *pro) + +#ifdef MODULE +EXPORT_NO_SYMBOLS; +MODULE_DESCRIPTION("The Linux DECnet Network Protocol"); +MODULE_AUTHOR("Linux DECnet Project Team"); + +static int addr[2] = {0, 0}; + +MODULE_PARM(addr, "2i"); +MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node"); +#endif + + +static int __init decnet_init(void) { +#ifdef MODULE + if (addr[0] > 63 || addr[0] < 0) { + printk(KERN_ERR "DECnet: Area must be between 0 and 63"); + return 1; + } + + if (addr[1] > 1023 || addr[1] < 0) { + printk(KERN_ERR "DECnet: Node must be between 0 and 1023"); + return 1; + } + + decnet_address = dn_htons((addr[0] << 10) | addr[1]); + dn_dn2eth(decnet_ether_address, dn_ntohs(decnet_address)); +#endif + printk(KERN_INFO "NET4: DECnet for Linux: V.2.3.49s (C) 1995-2000 Linux DECnet Project Team\n"); sock_register(&dn_family_ops); @@ -2074,6 +2102,7 @@ void __init decnet_proto_init(struct net_proto *pro) #ifdef CONFIG_SYSCTL dn_register_sysctl(); #endif /* CONFIG_SYSCTL */ + return 0; } @@ -2093,37 +2122,7 @@ static int __init decnet_setup(char *str) __setup("decnet=", decnet_setup); #endif -#ifdef MODULE -EXPORT_NO_SYMBOLS; -MODULE_DESCRIPTION("The Linux DECnet Network Protocol"); -MODULE_AUTHOR("Linux DECnet Project Team"); - -static int addr[2] = {0, 0}; - -MODULE_PARM(addr, "2i"); -MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node"); - -int __init init_module(void) -{ - if (addr[0] > 63 || addr[0] < 0) { - printk(KERN_ERR "DECnet: Area must be between 0 and 63"); - return 1; - } - - if (addr[1] > 1023 || addr[1] < 0) { - printk(KERN_ERR "DECnet: Node must be between 0 and 1023"); - return 1; - } - - decnet_address = dn_htons((addr[0] << 10) | addr[1]); - dn_dn2eth(decnet_ether_address, dn_ntohs(decnet_address)); - - decnet_proto_init(NULL); - - return 0; -} - -void __exit cleanup_module(void) +static void __exit decnet_exit(void) { #ifdef CONFIG_SYSCTL dn_unregister_sysctl(); @@ -2145,4 +2144,5 @@ void __exit cleanup_module(void) sock_unregister(AF_DECnet); } -#endif +module_init(decnet_init); +module_exit(decnet_exit); diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 7a2a815ce..5d44e1f12 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -1143,7 +1143,5 @@ int __init econet_proto_init(void) return 0; } -#ifdef MODULE module_init(econet_proto_init); module_exit(econet_proto_exit); -#endif diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 69c6ff036..584814ad8 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -5,7 +5,7 @@ * * PF_INET protocol family socket handler. * - * Version: $Id: af_inet.c,v 1.114 2000/09/18 05:59:48 davem Exp $ + * Version: $Id: af_inet.c,v 1.121 2000/10/24 21:26:18 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -107,6 +107,9 @@ #ifdef CONFIG_KMOD #include <linux/kmod.h> #endif +#ifdef CONFIG_NET_DIVERT +#include <linux/divert.h> +#endif /* CONFIG_NET_DIVERT */ #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */ #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ @@ -444,6 +447,9 @@ int inet_release(struct socket *sock) return(0); } +/* It is off by default, see below. */ +int sysctl_ip_nonlocal_bind; + static int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sockaddr_in *addr=(struct sockaddr_in *)uaddr; @@ -461,6 +467,21 @@ static int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); + /* Not specified by any standard per-se, however it breaks too + * many applications when removed. It is unfortunate since + * allowing applications to make a non-local bind solves + * several problems with systems using dynamic addressing. + * (ie. your servers still start up even if your ISDN link + * is temporarily down) + */ + if (sysctl_ip_nonlocal_bind == 0 && + sk->protinfo.af_inet.freebind == 0 && + addr->sin_addr.s_addr != INADDR_ANY && + chk_addr_ret != RTN_LOCAL && + chk_addr_ret != RTN_MULTICAST && + chk_addr_ret != RTN_BROADCAST) + return -EADDRNOTAVAIL; + snum = ntohs(addr->sin_port); if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) return -EACCES; @@ -750,14 +771,15 @@ int inet_shutdown(struct socket *sock, int how) } switch (sk->state) { - default: + case TCP_CLOSE: + err = -ENOTCONN; + /* Hack to wake up other listeners, who can poll for + POLLHUP, even on eg. unconnected UDP sockets -- RR */ + default: sk->shutdown |= how; if (sk->prot->shutdown) sk->prot->shutdown(sk, how); break; - case TCP_CLOSE: - err = -ENOTCONN; - break; /* Remaining two branches are temporary solution for missing * close() in multithreaded environment. It is _not_ a good idea, @@ -847,6 +869,13 @@ static int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if (br_ioctl_hook != NULL) return br_ioctl_hook(arg); #endif + case SIOCGIFDIVERT: + case SIOCSIFDIVERT: +#ifdef CONFIG_NET_DIVERT + return(divert_ioctl(cmd, (struct divert_cf *) arg)); +#else + return -ENOPKG; +#endif /* CONFIG_NET_DIVERT */ return -ENOPKG; case SIOCADDDLCI: @@ -946,7 +975,7 @@ extern void tcp_v4_init(struct net_proto_family *); * Called by socket.c on kernel startup. */ -void __init inet_proto_init(struct net_proto *pro) +static int __init inet_init(void) { struct sk_buff *dummy_skb; struct inet_protocol *p; @@ -956,7 +985,7 @@ void __init inet_proto_init(struct net_proto *pro) if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) { printk(KERN_CRIT "inet_proto_init: panic\n"); - return; + return -EINVAL; } /* @@ -1030,4 +1059,6 @@ void __init inet_proto_init(struct net_proto *pro) proc_net_create ("tcp", 0, tcp_get_info); proc_net_create ("udp", 0, udp_get_info); #endif /* CONFIG_PROC_FS */ + return 0; } +module_init(inet_init); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index c173b9eb3..b410d1de4 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1,6 +1,6 @@ /* linux/net/inet/arp.c * - * Version: $Id: arp.c,v 1.88 2000/08/02 06:05:02 davem Exp $ + * Version: $Id: arp.c,v 1.90 2000/10/04 09:20:56 anton Exp $ * * Copyright (C) 1994 by Florian La Roche * diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index cda89659c..8c103857c 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -3,7 +3,7 @@ * * This source is covered by the GNU GPL, the same as all kernel sources. * - * Version: $Id: inetpeer.c,v 1.2 2000/05/03 06:37:06 davem Exp $ + * Version: $Id: inetpeer.c,v 1.3 2000/10/03 07:29:00 anton Exp $ * * Authors: Andrey V. Savochkin <saw@msu.ru> */ diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 7d8efb6dd..7df6e72e3 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -5,7 +5,7 @@ * * The IP forwarding functionality. * - * Version: $Id: ip_forward.c,v 1.46 2000/01/09 02:19:37 davem Exp $ + * Version: $Id: ip_forward.c,v 1.47 2000/10/24 22:54:26 davem Exp $ * * Authors: see ip.c * @@ -63,13 +63,11 @@ static inline int ip_forward_finish(struct sk_buff *skb) dst_release(old_dst); } #endif - ip_send(skb); - return 0; + return (ip_send(skb)); } ip_forward_options(skb); - ip_send(skb); - return 0; + return (ip_send(skb)); } int ip_forward(struct sk_buff *skb) @@ -81,7 +79,7 @@ int ip_forward(struct sk_buff *skb) unsigned short mtu; if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb)) - return 0; + return NET_RX_SUCCESS; if (skb->pkt_type != PACKET_HOST) goto drop; @@ -119,7 +117,7 @@ int ip_forward(struct sk_buff *skb) /* We are about to mangle packet. Copy it! */ if ((skb = skb_cow(skb, dev2->hard_header_len)) == NULL) - return -1; + return NET_RX_DROP; iph = skb->nh.iph; opt = &(IPCB(skb)->opt); @@ -138,7 +136,7 @@ int ip_forward(struct sk_buff *skb) if (rt->rt_flags & RTCF_NAT) { if (ip_do_nat(skb)) { kfree_skb(skb); - return -1; + return NET_RX_BAD; } } #endif @@ -163,5 +161,5 @@ too_many_hops: icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); drop: kfree_skb(skb); - return -1; + return NET_RX_DROP; } diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index e7167aa65..f7b73adb8 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1266,7 +1266,9 @@ int __init ipgre_init(void) #ifdef MODULE register_netdev(&ipgre_fb_tunnel_dev); #else + rtnl_lock(); register_netdevice(&ipgre_fb_tunnel_dev); + rtnl_unlock(); #endif inet_add_protocol(&ipgre_protocol); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index bb76f7ce5..873030d0a 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -5,7 +5,7 @@ * * The Internet Protocol (IP) module. * - * Version: $Id: ip_input.c,v 1.49 2000/08/21 20:41:55 davem Exp $ + * Version: $Id: ip_input.c,v 1.50 2000/10/24 22:54:26 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -341,7 +341,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb) skb = skb_cow(skb, skb_headroom(skb)); if (skb == NULL) - return 0; + return NET_RX_DROP; iph = skb->nh.iph; skb->ip_summed = 0; @@ -372,7 +372,7 @@ inhdr_error: IP_INC_STATS_BH(IpInHdrErrors); drop: kfree_skb(skb); - return(0); + return NET_RX_DROP; } /* @@ -429,6 +429,6 @@ inhdr_error: drop: kfree_skb(skb); out: - return(0); + return NET_RX_DROP; } diff --git a/net/ipv4/ip_nat_dumb.c b/net/ipv4/ip_nat_dumb.c index b45377af4..88e3ff9e2 100644 --- a/net/ipv4/ip_nat_dumb.c +++ b/net/ipv4/ip_nat_dumb.c @@ -5,7 +5,7 @@ * * Dumb Network Address Translation. * - * Version: $Id: ip_nat_dumb.c,v 1.9 1999/08/20 11:05:46 davem Exp $ + * Version: $Id: ip_nat_dumb.c,v 1.10 2000/10/24 22:54:26 davem Exp $ * * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> * @@ -152,8 +152,9 @@ ip_do_nat(struct sk_buff *skb) break; } } - return 0; + return NET_RX_SUCCESS; truncated: + /* should be return NET_RX_BAD; */ return -EINVAL; } diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 056767890..ce7618fe1 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -5,7 +5,7 @@ * * The Internet Protocol (IP) output module. * - * Version: $Id: ip_output.c,v 1.85 2000/08/31 23:39:12 davem Exp $ + * Version: $Id: ip_output.c,v 1.87 2000/10/25 20:07:22 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a82e4be1f..f87921077 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -5,7 +5,7 @@ * * The IP to API glue. * - * Version: $Id: ip_sockglue.c,v 1.52 2000/09/09 08:26:04 davem Exp $ + * Version: $Id: ip_sockglue.c,v 1.53 2000/10/22 16:06:56 davem Exp $ * * Authors: see ip.c * @@ -372,21 +372,23 @@ out: /* * Socket option code for IP. This is the end of the line after any TCP,UDP etc options on * an IP socket. - * - * We implement IP_TOS (type of service), IP_TTL (time to live). */ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen) { int val=0,err; - if (optname == IP_PKTINFO || optname == IP_RECVTTL || - optname == IP_RECVTOS || optname == IP_RECVOPTS || - optname == IP_RETOPTS || optname == IP_TOS || - optname == IP_TTL || optname == IP_HDRINCL || - optname == IP_MTU_DISCOVER || optname == IP_RECVERR || - optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_LOOP || - optname == IP_ROUTER_ALERT) { + if (level != SOL_IP) + return -ENOPROTOOPT; + + if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) | + (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) | + (1<<IP_RETOPTS) | (1<<IP_TOS) | + (1<<IP_TTL) | (1<<IP_HDRINCL) | + (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | + (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND))) || + optname == IP_MULTICAST_TTL || + optname == IP_MULTICAST_LOOP) { if (optlen >= sizeof(int)) { if (get_user(val, (int *) optval)) return -EFAULT; @@ -400,9 +402,6 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt } /* If optlen==0, it is equivalent to val == 0 */ - - if (level != SOL_IP) - return -ENOPROTOOPT; #ifdef CONFIG_IP_MROUTE if (optname >= MRT_BASE && optname <= (MRT_BASE + 10)) @@ -612,6 +611,12 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt case IP_ROUTER_ALERT: err = ip_ra_control(sk, val ? 1 : 0, NULL); break; + + case IP_FREEBIND: + if (optlen<1) + goto e_inval; + sk->protinfo.af_inet.freebind = !!val; + break; default: #ifdef CONFIG_NETFILTER @@ -771,6 +776,9 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op len -= msg.msg_controllen; return put_user(len, optlen); } + case IP_FREEBIND: + val = sk->protinfo.af_inet.freebind; + break; default: #ifdef CONFIG_NETFILTER val = nf_getsockopt(sk, PF_INET, optname, optval, diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index eae29c0b0..a8cb239a8 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -1,7 +1,7 @@ /* * Linux NET3: IP/IP protocol decoder. * - * Version: $Id: ipip.c,v 1.39 2000/08/25 02:15:47 davem Exp $ + * Version: $Id: ipip.c,v 1.40 2000/10/28 17:19:25 davem Exp $ * * Authors: * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95 @@ -894,7 +894,9 @@ int __init ipip_init(void) #ifdef MODULE register_netdev(&ipip_fb_tunnel_dev); #else + rtnl_lock(); register_netdevice(&ipip_fb_tunnel_dev); + rtnl_unlock(); #endif inet_add_protocol(&ipip_protocol); diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 10d09a6bd..e5fbe41af 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -72,7 +72,7 @@ ip_nat_fn(unsigned int hooknum, unreliable. */ if (!ct) { if (net_ratelimit()) - printk("NAT: %u dropping untracked packet %p %u %u.%u.%u.%u -> %u.%u.%u.%u\n", + printk(KERN_DEBUG "NAT: %u dropping untracked packet %p %u %u.%u.%u.%u -> %u.%u.%u.%u\n", hooknum, *pskb, (*pskb)->nh.iph->protocol, diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index db57fedb9..cacd7a3f8 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c @@ -5,7 +5,7 @@ * * INET protocol dispatch tables. * - * Version: $Id: protocol.c,v 1.11 2000/02/22 23:54:26 davem Exp $ + * Version: $Id: protocol.c,v 1.12 2000/10/03 07:29:00 anton Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 81f20361a..675154d91 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -5,7 +5,7 @@ * * RAW - implementation of IP "raw" sockets. * - * Version: $Id: raw.c,v 1.53 2000/08/09 11:59:04 davem Exp $ + * Version: $Id: raw.c,v 1.55 2000/10/24 22:54:26 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -227,11 +227,11 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) { IP_INC_STATS(IpInDiscards); kfree_skb(skb); - return -1; + return NET_RX_DROP; } IP_INC_STATS(IpInDelivers); - return 0; + return NET_RX_SUCCESS; } /* @@ -653,7 +653,7 @@ int raw_get_info(char *buffer, char **start, off_t offset, int length) if (sk->family != PF_INET) continue; pos += 128; - if (pos < offset) + if (pos <= offset) continue; get_raw_sock(sk, tmpbuf, i); len += sprintf(buffer+len, "%-127s\n", tmpbuf); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 4734d8087..cacf36b71 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -5,7 +5,7 @@ * * ROUTE - implementation of the IP router. * - * Version: $Id: route.c,v 1.90 2000/08/31 23:39:12 davem Exp $ + * Version: $Id: route.c,v 1.91 2000/10/03 07:29:00 anton Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index d9f05c671..68d536e10 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -1,7 +1,7 @@ /* * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem. * - * $Id: sysctl_net_ipv4.c,v 1.46 2000/09/16 09:38:30 davem Exp $ + * $Id: sysctl_net_ipv4.c,v 1.47 2000/10/19 15:51:02 davem Exp $ * * Begun April 1, 1996, Mike Shaver. * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS] @@ -15,6 +15,9 @@ #include <net/route.h> #include <net/tcp.h> +/* From af_inet.c */ +extern int sysctl_ip_nonlocal_bind; + /* From icmp.c */ extern int sysctl_icmp_echo_ignore_all; extern int sysctl_icmp_echo_ignore_broadcasts; @@ -110,6 +113,9 @@ ctl_table ipv4_table[] = { {NET_IPV4_NO_PMTU_DISC, "ip_no_pmtu_disc", &ipv4_config.no_pmtu_disc, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_NONLOCAL_BIND, "ip_nonlocal_bind", + &sysctl_ip_nonlocal_bind, sizeof(int), 0644, NULL, + &proc_dointvec}, {NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries", &sysctl_tcp_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_TCP_SYNACK_RETRIES, "tcp_synack_retries", diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 05027bc93..0f97c2d27 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.174 2000/09/18 05:59:48 davem Exp $ + * Version: $Id: tcp.c,v 1.176 2000/10/06 22:45:41 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -1026,7 +1026,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size) skb = NULL; if (tcp_memory_free(sk)) - skb = tcp_alloc_skb(sk, tmp, GFP_KERNEL); + skb = tcp_alloc_skb(sk, tmp, sk->allocation); if (skb == NULL) { /* If we didn't get any memory, we need to sleep. */ set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index d2a79b4b1..1a0f278b4 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.213 2000/09/18 05:59:48 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.218 2000/10/18 18:04:22 davem Exp $ * * IPv4 specific functions * @@ -75,37 +75,21 @@ static struct socket *tcp_socket=&tcp_inode.u.socket_i; void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, struct sk_buff *skb); -/* This is for sockets with full identity only. Sockets here will always - * be without wildcards and will have the following invariant: - * TCP_ESTABLISHED <= sk->state < TCP_CLOSE - * - * First half of the table is for sockets not in TIME_WAIT, second half - * is for TIME_WAIT sockets only. - */ -struct tcp_ehash_bucket *tcp_ehash; - -/* Ok, let's try this, I give up, we do need a local binding - * TCP hash as well as the others for fast bind/connect. - */ -struct tcp_bind_hashbucket *tcp_bhash; - -int tcp_bhash_size; -int tcp_ehash_size; - -/* All sockets in TCP_LISTEN state will be in here. This is the only table - * where wildcard'd TCP sockets can exist. Hash function here is just local - * port number. +/* + * ALL members must be initialised to prevent gcc-2.7.2.3 miscompilation */ -struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE]; -char __tcp_clean_cacheline_pad[(SMP_CACHE_BYTES - - (((sizeof(void *) * (TCP_LHTABLE_SIZE + 2)) + - (sizeof(int) * 2)) % SMP_CACHE_BYTES))] = { 0, }; - -rwlock_t tcp_lhash_lock = RW_LOCK_UNLOCKED; -atomic_t tcp_lhash_users = ATOMIC_INIT(0); -DECLARE_WAIT_QUEUE_HEAD(tcp_lhash_wait); - -spinlock_t tcp_portalloc_lock = SPIN_LOCK_UNLOCKED; +struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = { + __tcp_ehash: NULL, + __tcp_bhash: NULL, + __tcp_bhash_size: 0, + __tcp_ehash_size: 0, + __tcp_listening_hash: { NULL, }, + __tcp_lhash_lock: RW_LOCK_UNLOCKED, + __tcp_lhash_users: ATOMIC_INIT(0), + __tcp_lhash_wait: + __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait), + __tcp_portalloc_lock: SPIN_LOCK_UNLOCKED +}; /* * This array holds the first and last local port number. @@ -2113,7 +2097,7 @@ skip_listen: continue; pos += TMPSZ; - if (pos < offset) + if (pos <= offset) continue; get_openreq(sk, req, tmpbuf, num, uid); len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf); @@ -2145,7 +2129,7 @@ skip_listen: if (!TCP_INET_FAMILY(sk->family)) continue; pos += TMPSZ; - if (pos < offset) + if (pos <= offset) continue; get_tcp_sock(sk, tmpbuf, num); len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf); @@ -2160,7 +2144,7 @@ skip_listen: if (!TCP_INET_FAMILY(tw->family)) continue; pos += TMPSZ; - if (pos < offset) + if (pos <= offset) continue; get_timewait_sock(tw, tmpbuf, num); len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 8dca4474b..7b6f45428 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_output.c,v 1.127 2000/08/15 20:15:23 davem Exp $ + * Version: $Id: tcp_output.c,v 1.128 2000/10/29 01:51:09 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -318,7 +318,7 @@ void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue, unsigne if (!force_queue && tp->send_head == NULL && tcp_snd_test(tp, skb, cur_mss, 1)) { /* Send it out now. */ TCP_SKB_CB(skb)->when = tcp_time_stamp; - if (tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)) == 0) { + if (tcp_transmit_skb(sk, skb_clone(skb, sk->allocation)) == 0) { tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; tcp_minshall_update(tp, cur_mss, skb); if (tp->packets_out++ == 0) diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 5e5af83c2..f57aeb32e 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_timer.c,v 1.79 2000/08/11 00:13:36 davem Exp $ + * Version: $Id: tcp_timer.c,v 1.80 2000/10/03 07:29:01 anton Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ff8a3d109..e098b9ff2 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -5,7 +5,7 @@ * * The User Datagram Protocol (UDP). * - * Version: $Id: udp.c,v 1.87 2000/09/20 02:11:34 davem Exp $ + * Version: $Id: udp.c,v 1.90 2000/10/18 18:04:22 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -677,8 +677,6 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, int len, if (flags & MSG_ERRQUEUE) return ip_recv_error(sk, msg, len); - - retry: /* * From here the generic datagram does a lot of the work. Come * the finished NET3, it will do _ALL_ the work! @@ -734,21 +732,22 @@ out: csum_copy_err: UDP_INC_STATS_BH(UdpInErrors); - if (flags&(MSG_PEEK|MSG_DONTWAIT)) { - struct sk_buff *skb2; - + /* Clear queue. */ + if (flags&MSG_PEEK) { + int clear = 0; spin_lock_irq(&sk->receive_queue.lock); - skb2 = skb_peek(&sk->receive_queue); - if ((flags & MSG_PEEK) && skb == skb2) { + if (skb == skb_peek(&sk->receive_queue)) { __skb_unlink(skb, &sk->receive_queue); + clear = 1; } spin_unlock_irq(&sk->receive_queue.lock); - skb_free_datagram(sk, skb); - if ((flags & MSG_DONTWAIT) && !skb2) - return -EAGAIN; - } else - skb_free_datagram(sk, skb); - goto retry; + if (clear) + kfree_skb(skb); + } + + skb_free_datagram(sk, skb); + + return -EAGAIN; } int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) @@ -1029,7 +1028,7 @@ int udp_get_info(char *buffer, char **start, off_t offset, int length) if (sk->family != PF_INET) continue; pos += 128; - if (pos < offset) + if (pos <= offset) continue; get_udp_sock(sk, tmpbuf, i); len += sprintf(buffer+len, "%-127s\n", tmpbuf); diff --git a/net/ipv4/utils.c b/net/ipv4/utils.c index c6494d87f..a5a9c3873 100644 --- a/net/ipv4/utils.c +++ b/net/ipv4/utils.c @@ -6,7 +6,7 @@ * Various kernel-resident INET utility functions; mainly * for format conversion and debugging output. * - * Version: $Id: utils.c,v 1.7 1999/06/09 10:11:05 davem Exp $ + * Version: $Id: utils.c,v 1.8 2000/10/03 07:29:01 anton Exp $ * * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 869cac689..c243a6ec9 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -7,7 +7,7 @@ * * Adapted from linux/net/ipv4/af_inet.c * - * $Id: af_inet6.c,v 1.58 2000/09/18 05:59:48 davem Exp $ + * $Id: af_inet6.c,v 1.60 2000/10/19 01:05:34 davem Exp $ * * Fixes: * Hideaki YOSHIFUJI : sin6_scope_id support @@ -502,11 +502,7 @@ extern void ipv6_sysctl_register(void); extern void ipv6_sysctl_unregister(void); #endif -#ifdef MODULE -int init_module(void) -#else -void __init inet6_proto_init(struct net_proto *pro) -#endif +static int __init inet6_init(void) { struct sk_buff *dummy_skb; int err; @@ -523,11 +519,7 @@ void __init inet6_proto_init(struct net_proto *pro) if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)) { printk(KERN_CRIT "inet6_proto_init: size fault\n"); -#ifdef MODULE return -EINVAL; -#else - return; -#endif } /* @@ -577,11 +569,7 @@ void __init inet6_proto_init(struct net_proto *pro) /* Now the userspace is allowed to create INET6 sockets. */ (void) sock_register(&inet6_family_ops); -#ifdef MODULE return 0; -#else - return; -#endif #ifdef CONFIG_PROC_FS proc_snmp6_fail: @@ -603,15 +591,13 @@ icmp_fail: #if defined(MODULE) && defined(CONFIG_SYSCTL) ipv6_sysctl_unregister(); #endif -#ifdef MODULE return err; -#else - return; -#endif } +module_init(inet6_init); + #ifdef MODULE -void cleanup_module(void) +static void inet6_exit(void) { /* First of all disallow new sockets creation. */ sock_unregister(PF_INET6); @@ -636,4 +622,5 @@ void cleanup_module(void) ipv6_sysctl_unregister(); #endif } -#endif /* MODULE */ +module_exit(inet6_exit); +#endif /* MODULE */ diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 43ac35004..df1e9324f 100644 --- a/net/ipv6/protocol.c +++ b/net/ipv6/protocol.c @@ -5,7 +5,7 @@ * * PF_INET6 protocol dispatch tables. * - * Version: $Id: protocol.c,v 1.8 2000/02/22 23:54:29 davem Exp $ + * Version: $Id: protocol.c,v 1.9 2000/10/03 07:29:01 anton Exp $ * * Authors: Pedro Roque <roque@di.fc.ul.pt> * diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 0b7e00252..43ef2e87d 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -7,7 +7,7 @@ * * Adapted from linux/net/ipv4/raw.c * - * $Id: raw.c,v 1.40 2000/08/09 11:59:04 davem Exp $ + * $Id: raw.c,v 1.41 2000/10/18 18:04:23 davem Exp $ * * Fixes: * Hideaki YOSHIFUJI : sin6_scope_id support @@ -793,7 +793,7 @@ int raw6_get_info(char *buffer, char **start, off_t offset, int length) if (sk->family != PF_INET6) continue; pos += LINE_LEN+1; - if (pos < offset) + if (pos <= offset) continue; get_raw6_sock(sk, tmpbuf, i); len += sprintf(buffer+len, LINE_FMT, tmpbuf); diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 59048a22b..f263a3197 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -6,7 +6,7 @@ * Pedro Roque <roque@di.fc.ul.pt> * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> * - * $Id: sit.c,v 1.43 2000/08/25 02:15:47 davem Exp $ + * $Id: sit.c,v 1.45 2000/10/28 17:19:25 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -188,7 +188,7 @@ struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create) } if (i==100) goto failed; - memcpy(parms->name, dev->name, IFNAMSIZ); + memcpy(nt->parms.name, dev->name, IFNAMSIZ); } if (register_netdevice(dev) < 0) goto failed; @@ -829,7 +829,9 @@ int __init sit_init(void) #ifdef MODULE register_netdev(&ipip6_fb_tunnel_dev); #else + rtnl_lock(); register_netdevice(&ipip6_fb_tunnel_dev); + rtnl_unlock(); #endif inet_add_protocol(&sit_protocol); return 0; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 952e24765..b830884e8 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -5,7 +5,7 @@ * Authors: * Pedro Roque <roque@di.fc.ul.pt> * - * $Id: tcp_ipv6.c,v 1.125 2000/08/09 11:59:04 davem Exp $ + * $Id: tcp_ipv6.c,v 1.126 2000/10/18 18:04:23 davem Exp $ * * Based on: * linux/net/ipv4/tcp.c @@ -2009,7 +2009,7 @@ int tcp6_get_info(char *buffer, char **start, off_t offset, int length) if (req->class->family != PF_INET6) continue; pos += LINE_LEN+1; - if (pos < offset) + if (pos <= offset) continue; get_openreq6(sk, req, tmpbuf, num, uid); len += sprintf(buffer+len, LINE_FMT, tmpbuf); @@ -2041,7 +2041,7 @@ int tcp6_get_info(char *buffer, char **start, off_t offset, int length) if (sk->family != PF_INET6) continue; pos += LINE_LEN+1; - if (pos < offset) + if (pos <= offset) continue; get_tcp6_sock(sk, tmpbuf, num); len += sprintf(buffer+len, LINE_FMT, tmpbuf); @@ -2056,7 +2056,7 @@ int tcp6_get_info(char *buffer, char **start, off_t offset, int length) if (tw->family != PF_INET6) continue; pos += LINE_LEN+1; - if (pos < offset) + if (pos <= offset) continue; get_timewait6_sock(tw, tmpbuf, num); len += sprintf(buffer+len, LINE_FMT, tmpbuf); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 4d95aa40b..187db4414 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -7,7 +7,7 @@ * * Based on linux/ipv4/udp.c * - * $Id: udp.c,v 1.57 2000/09/18 05:59:48 davem Exp $ + * $Id: udp.c,v 1.58 2000/10/18 18:04:23 davem Exp $ * * Fixes: * Hideaki YOSHIFUJI : sin6_scope_id support @@ -956,7 +956,7 @@ int udp6_get_info(char *buffer, char **start, off_t offset, int length) if (sk->family != PF_INET6) continue; pos += LINE_LEN+1; - if (pos < offset) + if (pos <= offset) continue; get_udp6_sock(sk, tmpbuf, i); len += sprintf(buffer+len, LINE_FMT, tmpbuf); diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index bbb2b2630..2fc3ea46c 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -2387,9 +2387,8 @@ static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; -/* Called by protocols.c on kernel start up */ -void ipx_proto_init(struct net_proto *pro) +static int __init ipx_init(void) { (void) sock_register(&ipx_family_ops); @@ -2415,7 +2414,9 @@ void ipx_proto_init(struct net_proto *pro) printk(KERN_INFO "NET4: Linux IPX 0.38 for NET4.0\n"); printk(KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n"); + return 0; } +module_init(ipx_init); /* Higher layers need this info to prep tx pkts */ int ipx_if_offset(unsigned long ipx_net_number) @@ -2434,7 +2435,6 @@ EXPORT_SYMBOL(ipx_remove_socket); EXPORT_SYMBOL(ipx_register_spx); EXPORT_SYMBOL(ipx_unregister_spx); -#ifdef MODULE /* Note on MOD_{INC,DEC}_USE_COUNT: * * Use counts are incremented/decremented when @@ -2448,6 +2448,7 @@ EXPORT_SYMBOL(ipx_unregister_spx); * sockets be closed from user space. */ +#ifdef MODULE static void ipx_proto_finito(void) { ipx_interface *ifc; @@ -2486,18 +2487,7 @@ static void ipx_proto_finito(void) return; } - -int init_module(void) -{ - ipx_proto_init(NULL); - return (0); -} - -void cleanup_module(void) -{ - ipx_proto_finito(); - return; -} - +module_exit(ipx_proto_finito); #endif /* MODULE */ + #endif /* CONFIG_IPX || CONFIG_IPX_MODULE */ diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 2ba86afcc..69db79a0e 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -43,10 +43,10 @@ ********************************************************************/ #include <linux/config.h> +#include <linux/init.h> #include <linux/types.h> #include <linux/socket.h> #include <linux/sockios.h> -#include <linux/init.h> #include <linux/if_arp.h> #include <linux/net.h> #include <linux/irda.h> @@ -2155,17 +2155,19 @@ static struct notifier_block irda_dev_notifier = { * Initialize IrDA protocol layer * */ -void __init irda_proto_init(struct net_proto *pro) +static int __init irda_proto_init(void) { - sock_register(&irda_family_ops); - - irda_packet_type.type = htons(ETH_P_IRDA); + sock_register(&irda_family_ops); + + irda_packet_type.type = htons(ETH_P_IRDA); dev_add_pack(&irda_packet_type); - - register_netdevice_notifier(&irda_dev_notifier); - - irda_init(); + + register_netdevice_notifier(&irda_dev_notifier); + + irda_init(); + return 0; } +module_init(irda_proto_init); /* * Function irda_proto_cleanup (void) @@ -2186,4 +2188,5 @@ void irda_proto_cleanup(void) return; } +module_exit(irda_proto_cleanup); #endif /* MODULE */ diff --git a/net/irda/irmod.c b/net/irda/irmod.c index fde6788c3..39257f87a 100644 --- a/net/irda/irmod.c +++ b/net/irda/irmod.c @@ -545,28 +545,6 @@ void irda_proc_modcount(struct inode *inode, int fill) MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem"); MODULE_PARM(irda_debug, "1l"); - -/* - * Function init_module (void) - * - * Initialize the irda module - * - */ -int init_module(void) -{ - irda_proto_init(NULL); - - return 0; -} - -/* - * Function cleanup_module (void) - * - * Cleanup the irda module - * - */ -void cleanup_module(void) -{ - irda_proto_cleanup(); -} +module_exit(irda_proto_cleanup); #endif /* MODULE */ + diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c index 587304bca..bdc84d72f 100644 --- a/net/lapb/lapb_iface.c +++ b/net/lapb/lapb_iface.c @@ -401,25 +401,18 @@ EXPORT_SYMBOL(lapb_disconnect_request); EXPORT_SYMBOL(lapb_data_request); EXPORT_SYMBOL(lapb_data_received); -void __init lapb_proto_init(struct net_proto *pro) +static int __init lapb_init(void) { printk(KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n"); + return 0; } #ifdef MODULE MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>"); MODULE_DESCRIPTION("The X.25 Link Access Procedure B link layer protocol"); +#endif -int init_module(void) -{ - lapb_proto_init(NULL); - return 0; -} - -void cleanup_module(void) -{ -} -#endif +module_init(lapb_init); #endif diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index be011a234..3927d9c3a 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/init.h> #include <linux/major.h> #include <linux/signal.h> #include <linux/sched.h> @@ -968,16 +969,19 @@ struct net_proto_family netlink_family_ops = { netlink_create }; -void netlink_proto_init(struct net_proto *pro) +static int __init netlink_proto_init(void) { struct sk_buff *dummy_skb; if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb)) { - printk(KERN_CRIT "netlink_proto_init: panic\n"); - return; + printk(KERN_CRIT "netlink_init: panic\n"); + return -1; } sock_register(&netlink_family_ops); #ifdef CONFIG_PROC_FS create_proc_read_entry("net/netlink", 0, 0, netlink_read_proc, NULL); #endif + return 0; } + +module_init(netlink_proto_init); diff --git a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c index bc1b378fc..da7598a79 100644 --- a/net/netlink/netlink_dev.c +++ b/net/netlink/netlink_dev.c @@ -31,7 +31,7 @@ #include <asm/system.h> #include <asm/uaccess.h> -static unsigned open_map = 0; +static unsigned open_map; static struct socket *netlink_user[MAX_LINKS]; /* @@ -178,7 +178,7 @@ static struct file_operations netlink_fops = { release: netlink_release, }; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static void __init make_devfs_entries (const char *name, int minor) { diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 27d95703b..a0c139b3a 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1261,13 +1261,13 @@ static struct notifier_block nr_dev_notifier = { static struct net_device *dev_nr; -void __init nr_proto_init(struct net_proto *pro) +static int __init nr_proto_init(void) { int i; if ((dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) { printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); - return; + return -1; } memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device)); @@ -1296,8 +1296,12 @@ void __init nr_proto_init(struct net_proto *pro) proc_net_create("nr_neigh", 0, nr_neigh_get_info); proc_net_create("nr_nodes", 0, nr_nodes_get_info); #endif + return 0; } +module_init(nr_proto_init); + + #ifdef MODULE EXPORT_NO_SYMBOLS; @@ -1307,14 +1311,7 @@ MODULE_PARM_DESC(nr_ndevs, "number of NET/ROM devices"); MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>"); MODULE_DESCRIPTION("The amateur radio NET/ROM network and transport layer protocol"); -int init_module(void) -{ - nr_proto_init(NULL); - - return 0; -} - -void cleanup_module(void) +static void nr_exit(void) { int i; @@ -1348,7 +1345,9 @@ void cleanup_module(void) kfree(dev_nr); } +module_exit(nr_exit); +#endif /* MODULE */ + -#endif #endif diff --git a/net/netsyms.c b/net/netsyms.c index 8579c5b2f..ebe3bbe81 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -30,6 +30,9 @@ #include <net/scm.h> #include <linux/if_bridge.h> #include <linux/random.h> +#ifdef CONFIG_NET_DIVERT +#include <linux/divert.h> +#endif /* CONFIG_NET_DIVERT */ #ifdef CONFIG_NET extern __u32 sysctl_wmem_max; @@ -207,6 +210,12 @@ EXPORT_SYMBOL(br_ioctl_hook); #endif #endif +#ifdef CONFIG_NET_DIVERT +EXPORT_SYMBOL(alloc_divert_blk); +EXPORT_SYMBOL(free_divert_blk); +EXPORT_SYMBOL(divert_ioctl); +#endif /* CONFIG_NET_DIVERT */ + #ifdef CONFIG_INET /* Internet layer registration */ EXPORT_SYMBOL(inetdev_lock); @@ -276,16 +285,8 @@ EXPORT_SYMBOL(inet_sock_destruct); EXPORT_SYMBOL(inet_sock_release); /* Socket demultiplexing. */ -EXPORT_SYMBOL(tcp_ehash); -EXPORT_SYMBOL(tcp_ehash_size); -EXPORT_SYMBOL(tcp_listening_hash); -EXPORT_SYMBOL(tcp_lhash_lock); -EXPORT_SYMBOL(tcp_lhash_users); -EXPORT_SYMBOL(tcp_lhash_wait); +EXPORT_SYMBOL(tcp_hashinfo); EXPORT_SYMBOL(tcp_listen_wlock); -EXPORT_SYMBOL(tcp_bhash); -EXPORT_SYMBOL(tcp_bhash_size); -EXPORT_SYMBOL(tcp_portalloc_lock); EXPORT_SYMBOL(udp_hash); EXPORT_SYMBOL(udp_hash_lock); @@ -490,6 +491,7 @@ EXPORT_SYMBOL(dev_load); EXPORT_SYMBOL(dev_ioctl); EXPORT_SYMBOL(dev_queue_xmit); #ifdef CONFIG_NET_HW_FLOWCONTROL +EXPORT_SYMBOL(netdev_dropping); EXPORT_SYMBOL(netdev_register_fc); EXPORT_SYMBOL(netdev_unregister_fc); EXPORT_SYMBOL(netdev_fc_xoff); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index b7827f09f..6b4c77854 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -5,7 +5,7 @@ * * PACKET - implements raw packet sockets. * - * Version: $Id: af_packet.c,v 1.42 2000/08/29 03:44:56 davem Exp $ + * Version: $Id: af_packet.c,v 1.46 2000/10/24 21:26:19 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -33,6 +33,7 @@ * Alan Cox : Protocol setting support * Alexey Kuznetsov : Untied from IPv4 stack. * Cyrus Durgin : Fixed kerneld for kmod. + * Michal Ostrowski : Module initialization cleanup. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -67,6 +68,10 @@ #include <linux/init.h> #include <linux/if_bridge.h> +#ifdef CONFIG_NET_DIVERT +#include <linux/divert.h> +#endif /* CONFIG_NET_DIVERT */ + #ifdef CONFIG_INET #include <net/inet_common.h> #endif @@ -1484,6 +1489,14 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg #endif #endif + case SIOCGIFDIVERT: + case SIOCSIFDIVERT: +#ifdef CONFIG_NET_DIVERT + return(divert_ioctl(cmd, (struct divert_cf *) arg)); +#else + return -ENOPKG; +#endif /* CONFIG_NET_DIVERT */ + return -ENOPKG; #ifdef CONFIG_INET @@ -1860,8 +1873,8 @@ done: #endif -#ifdef MODULE -void cleanup_module(void) + +static void __exit packet_exit(void) { #ifdef CONFIG_PROC_FS remove_proc_entry("net/packet", 0); @@ -1872,17 +1885,16 @@ void cleanup_module(void) } -int init_module(void) -#else -void __init packet_proto_init(struct net_proto *pro) -#endif +static int __init packet_init(void) { sock_register(&packet_family_ops); register_netdevice_notifier(&packet_netdev_notifier); #ifdef CONFIG_PROC_FS create_proc_read_entry("net/packet", 0, 0, packet_read_proc, NULL); #endif -#ifdef MODULE return 0; -#endif } + + +module_init(packet_init); +module_exit(packet_exit); diff --git a/net/protocols.c b/net/protocols.c deleted file mode 100644 index 7de6a3bcb..000000000 --- a/net/protocols.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Protocol initializer table. Here separately for convenience - * - */ - - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/net.h> -#include <linux/fs.h> - -#ifdef CONFIG_UNIX -#include <linux/un.h> -#include <net/af_unix.h> -#endif - -#ifdef CONFIG_INET -#include <linux/inet.h> -#ifdef CONFIG_IPV6 -extern void inet6_proto_init(struct net_proto *pro); -#endif -#endif /* INET */ - -#ifdef CONFIG_ECONET -extern void econet_proto_init(struct net_proto *pro); -#endif - -#ifdef CONFIG_NETLINK -extern void netlink_proto_init(struct net_proto *pro); -#endif - -#ifdef CONFIG_PACKET -extern void packet_proto_init(struct net_proto *pro); -#endif - -#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) -#define NEED_802 -#include <net/ipxcall.h> -#endif - -#ifdef CONFIG_X25 -#include <net/x25call.h> -#endif - -#ifdef CONFIG_LAPB -#include <net/lapbcall.h> -#endif - -#ifdef CONFIG_AX25 -#include <net/ax25call.h> -#ifdef CONFIG_NETROM -#include <net/nrcall.h> -#endif -#ifdef CONFIG_ROSE -#include <net/rosecall.h> -#endif -#endif - -#ifdef CONFIG_IRDA -#include <net/irda/irdacall.h> -#endif - -#if defined(CONFIG_DECNET) -#include <net/decnet_call.h> -#endif - -#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) -#define NEED_802 -#include <net/atalkcall.h> -#endif - -#if defined(CONFIG_NETBEUI) -#define NEED_LLC -#include <net/netbeuicall.h> -#endif - -#if defined(CONFIG_LLC) -#define NEED_LLC -#endif - -#include <net/psnapcall.h> - -#ifdef CONFIG_TR -#include <linux/netdevice.h> -#include <linux/trdevice.h> -extern void rif_init(struct net_proto *); -#endif - -#ifdef CONFIG_ATM -#include <linux/atm.h> -#endif - -#ifdef NEED_LLC -#define NEED_802 -#include <net/llccall.h> -#endif - -#ifdef NEED_802 -#include <net/p8022call.h> -#endif - - -#ifdef CONFIG_PPPOE -#include <linux/if_pppox.h> -#endif - -/* - * Protocol Table - */ - -struct net_proto protocols[] = { -#ifdef CONFIG_NETLINK - { "NETLINK", netlink_proto_init }, -#endif - -#ifdef CONFIG_PACKET - { "PACKET", packet_proto_init }, -#endif - -#ifdef CONFIG_UNIX - { "UNIX", unix_proto_init }, /* Unix domain socket family */ -#endif - -#ifdef NEED_802 - { "802.2", p8022_proto_init }, /* 802.2 demultiplexor */ - { "SNAP", snap_proto_init }, /* SNAP demultiplexor */ -#endif - -#ifdef CONFIG_TR - { "RIF", rif_init }, /* RIF for Token ring */ -#endif - -#ifdef CONFIG_ATM - { "ATMPVC", atmpvc_proto_init }, /* ATM PVCs */ - { "ATMSVC", atmsvc_proto_init }, /* ATM SVCs */ -#endif - -#ifdef NEED_LLC - { "802.2LLC", llc_init }, /* 802.2 LLC */ -#endif - -#ifdef CONFIG_AX25 - { "AX.25", ax25_proto_init }, /* Amateur Radio AX.25 */ -#ifdef CONFIG_NETROM - { "NET/ROM", nr_proto_init }, /* Amateur Radio NET/ROM */ -#endif -#ifdef CONFIG_ROSE - { "Rose", rose_proto_init }, /* Amateur Radio X.25 PLP */ -#endif -#endif -#ifdef CONFIG_DECNET - { "DECnet", decnet_proto_init }, /* DECnet */ -#endif -#ifdef CONFIG_INET - { "INET", inet_proto_init }, /* TCP/IP */ -#ifdef CONFIG_IPV6 - { "INET6", inet6_proto_init}, /* IPv6 */ -#endif -#endif - -#ifdef CONFIG_IPX - { "IPX", ipx_proto_init }, /* IPX */ -#endif - -#ifdef CONFIG_ATALK - { "DDP", atalk_proto_init }, /* Netatalk Appletalk driver */ -#endif - -#ifdef CONFIG_LAPB - { "LAPB", lapb_proto_init }, /* LAPB protocols */ -#endif - -#ifdef CONFIG_X25 - { "X.25", x25_proto_init }, /* CCITT X.25 Packet Layer */ -#endif - -#ifdef CONFIG_ECONET - { "Econet", econet_proto_init }, /* Acorn Econet */ -#endif - -#ifdef CONFIG_IRDA - { "IrDA", irda_proto_init }, /* IrDA protocols */ -#endif -#ifdef CONFIG_PPPOE - { "PPPoX", pppox_proto_init }, /* PPP over Ethernet */ -#endif - { NULL, NULL } /* End marker */ -}; diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index f61d9cd34..f639e578a 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -27,6 +27,7 @@ #include <linux/config.h> #if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE) #include <linux/module.h> +#include <linux/init.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -56,7 +57,6 @@ #include <linux/proc_fs.h> #include <net/ip.h> #include <net/arp.h> -#include <linux/init.h> int rose_ndevs = 10; @@ -1427,7 +1427,7 @@ static struct notifier_block rose_dev_notifier = { static struct net_device *dev_rose; -void __init rose_proto_init(struct net_proto *pro) +static int __init rose_proto_init(void) { int i; @@ -1435,7 +1435,7 @@ void __init rose_proto_init(struct net_proto *pro) if ((dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) { printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n"); - return; + return -1; } memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device)); @@ -1466,7 +1466,9 @@ void __init rose_proto_init(struct net_proto *pro) proc_net_create("rose_nodes", 0, rose_nodes_get_info); proc_net_create("rose_routes", 0, rose_routes_get_info); #endif + return 0; } +module_init(rose_proto_init); #ifdef MODULE EXPORT_NO_SYMBOLS; @@ -1477,14 +1479,7 @@ MODULE_PARM_DESC(rose_ndevs, "number of ROSE devices"); MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>"); MODULE_DESCRIPTION("The amateur radio ROSE network layer protocol"); -int init_module(void) -{ - rose_proto_init(NULL); - - return 0; -} - -void cleanup_module(void) +static void __exit rose_exit(void) { int i; @@ -1522,7 +1517,8 @@ void cleanup_module(void) kfree(dev_rose); } +module_exit(rose_exit); +#endif /* MODULE */ -#endif #endif diff --git a/net/socket.c b/net/socket.c index 9fdc84fb5..58df6d92e 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1490,7 +1490,7 @@ out: /* * Perform a file control on a socket file descriptor. * - * Doesn't aquire a fd lock, because no network fcntl + * Doesn't acquire a fd lock, because no network fcntl * function sleeps currently. */ @@ -1638,27 +1638,9 @@ int sock_unregister(int family) return 0; } -void __init proto_init(void) -{ - extern struct net_proto protocols[]; /* Network protocols */ - struct net_proto *pro; - - /* Kick all configured protocols. */ - pro = protocols; - while (pro->name != NULL) - { - (*pro->init_func)(pro); - pro++; - } - /* We're all done... */ -} extern void sk_init(void); -#ifdef CONFIG_BRIDGE -extern int br_init(void); -#endif - #ifdef CONFIG_WAN_ROUTER extern void wanrouter_init(void); #endif @@ -1691,14 +1673,6 @@ void __init sock_init(void) #endif /* - * Ethernet bridge layer. - */ - -#ifdef CONFIG_BRIDGE - br_init(); -#endif - - /* * Wan router layer. */ @@ -1712,10 +1686,13 @@ void __init sock_init(void) register_filesystem(&sock_fs_type); sock_mnt = kern_mount(&sock_fs_type); - proto_init(); + /* The real protocol initialization is performed when + * do_initcalls is run. + */ + /* - * The netlink device handler may be needed early. + * The netlink device handler may be needed early. */ #ifdef CONFIG_RTNETLINK diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 7eb578a60..a295ecaf7 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -159,7 +159,7 @@ rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) { int nr; - nr = (cred->cr_uid % RPC_CREDCACHE_NR); + nr = (cred->cr_uid & RPC_CREDCACHE_MASK); spin_lock(&rpc_credcache_lock); cred->cr_next = auth->au_credcache[nr]; auth->au_credcache[nr] = cred; @@ -178,7 +178,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, int taskflags) int nr = 0; if (!(taskflags & RPC_TASK_ROOTCREDS)) - nr = current->uid % RPC_CREDCACHE_NR; + nr = current->uid & RPC_CREDCACHE_MASK; if (time_before(auth->au_nextgc, jiffies)) rpcauth_gc_credcache(auth); @@ -218,7 +218,7 @@ rpcauth_remove_credcache(struct rpc_auth *auth, struct rpc_cred *cred) struct rpc_cred **q, *cr; int nr; - nr = (cred->cr_uid % RPC_CREDCACHE_NR); + nr = (cred->cr_uid & RPC_CREDCACHE_MASK); spin_lock(&rpc_credcache_lock); q = &auth->au_credcache[nr]; while ((cr = *q) != NULL) { diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c index d2e645acd..a9e42721a 100644 --- a/net/sunrpc/auth_null.c +++ b/net/sunrpc/auth_null.c @@ -54,6 +54,7 @@ nul_create_cred(int flags) return NULL; cred->cr_count = 0; cred->cr_flags = RPCAUTH_CRED_UPTODATE; + cred->cr_uid = current->uid; return cred; } diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index a036faef9..26a140771 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -800,7 +800,6 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout) "svc_recv: service %p, wait queue active!\n", rqstp); -again: /* Initialize the buffers */ rqstp->rq_argbuf = rqstp->rq_defbuf; rqstp->rq_resbuf = rqstp->rq_defbuf; @@ -846,7 +845,7 @@ again: /* No data, incomplete (TCP) read, or accept() */ if (len == 0 || len == -EAGAIN) { svc_sock_release(rqstp); - goto again; + return -EAGAIN; } rqstp->rq_secure = ntohs(rqstp->rq_addr.sin_port) < 1024; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 407f8f6b6..7603a9221 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -8,7 +8,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Version: $Id: af_unix.c,v 1.105 2000/08/16 10:58:22 davem Exp $ + * Version: $Id: af_unix.c,v 1.107 2000/10/19 01:05:36 davem Exp $ * * Fixes: * Linus Torvalds : Assorted bug cures. @@ -46,6 +46,7 @@ * Artur Skawina : Hash function optimizations * Alexey Kuznetsov : Full scale SMP. Lot of bugs are introduced 8) * Malcolm Beattie : Set peercred for socketpair + * Michal Ostrowski : Module initialization cleanup. * * * Known differences from reference BSD that was tested: @@ -1845,16 +1846,12 @@ struct net_proto_family unix_family_ops = { unix_create }; -#ifdef MODULE #ifdef CONFIG_SYSCTL extern void unix_sysctl_register(void); extern void unix_sysctl_unregister(void); #endif -int init_module(void) -#else -void __init unix_proto_init(struct net_proto *pro) -#endif +static int __init af_unix_init(void) { struct sk_buff *dummy_skb; @@ -1862,28 +1859,21 @@ void __init unix_proto_init(struct net_proto *pro) if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) { printk(KERN_CRIT "unix_proto_init: panic\n"); -#ifdef MODULE return -1; -#else - return; -#endif } sock_register(&unix_family_ops); #ifdef CONFIG_PROC_FS create_proc_read_entry("net/unix", 0, 0, unix_read_proc, NULL); #endif -#ifdef MODULE #ifdef CONFIG_SYSCTL unix_sysctl_register(); #endif return 0; -#endif } -#ifdef MODULE -void cleanup_module(void) +static void __exit af_unix_exit(void) { sock_unregister(PF_UNIX); #ifdef CONFIG_SYSCTL @@ -1893,7 +1883,9 @@ void cleanup_module(void) remove_proc_entry("net/unix", 0); #endif } -#endif + +module_init(af_unix_init); +module_exit(af_unix_exit); /* * Local variables: diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c index 744a4446a..885119da3 100644 --- a/net/unix/sysctl_net_unix.c +++ b/net/unix/sysctl_net_unix.c @@ -26,7 +26,6 @@ ctl_table unix_table[] = { {0} }; -#ifdef MODULE static struct ctl_table_header * unix_sysctl_header; static struct ctl_table unix_root_table[]; static struct ctl_table unix_net_table[]; @@ -50,6 +49,5 @@ void unix_sysctl_unregister(void) { unregister_sysctl_table(unix_sysctl_header); } -#endif /* MODULE */ #endif /* CONFIG_SYSCTL */ diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 9af3a0e3d..320722c40 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1283,8 +1283,11 @@ void x25_kill_by_neigh(struct x25_neigh *neigh) } } -void __init x25_proto_init(struct net_proto *pro) +static int __init x25_init(void) { +#ifdef MODULE + struct net_device *dev; +#endif /* MODULE */ sock_register(&x25_family_ops); x25_packet_type.type = htons(ETH_P_X25); @@ -1302,20 +1305,8 @@ void __init x25_proto_init(struct net_proto *pro) proc_net_create("x25", 0, x25_get_info); proc_net_create("x25_routes", 0, x25_routes_get_info); #endif -} #ifdef MODULE -EXPORT_NO_SYMBOLS; - -MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>"); -MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol"); - -int init_module(void) -{ - struct net_device *dev; - - x25_proto_init(NULL); - /* * Register any pre existing devices. */ @@ -1329,11 +1320,20 @@ int init_module(void) x25_link_device_up(dev); } read_unlock(&dev_base_lock); - +#endif /* MODULE */ return 0; } +module_init(x25_init); + -void cleanup_module(void) + +#ifdef MODULE +EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>"); +MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol"); + +static void __exit x25_exit(void) { #ifdef CONFIG_PROC_FS @@ -1354,7 +1354,7 @@ void cleanup_module(void) sock_unregister(AF_X25); } - +module_exit(x25_exit); #endif #endif diff --git a/scripts/Configure b/scripts/Configure index 56c618697..16c99f0d4 100644 --- a/scripts/Configure +++ b/scripts/Configure @@ -420,7 +420,11 @@ function string () { old=$(eval echo "\${$2}") def=${old:-$3} while :; do - readln "$1 ($2) [$def] " "$def" "$old" + if [ "$old" = "?" ]; then + readln "$1 ($2) [$def] " "$def" "" + else + readln "$1 ($2) [$def] " "$def" "$old" + fi if [ "$ans" = "?" ]; then help "$2" else diff --git a/scripts/Menuconfig b/scripts/Menuconfig index 5cfcab45b..5a76152e7 100644 --- a/scripts/Menuconfig +++ b/scripts/Menuconfig @@ -634,6 +634,7 @@ function l_choice () { title="$1" choices="$2" current="$3" + chosen= # # Scan current value of choices and set radiolist switches. @@ -644,7 +645,12 @@ function l_choice () { while [ -n "$2" ] do case "$1" in - "$current") list="$list $2 $1 ON " ;; + "$current"*) if [ -z "$chosen" ]; then + list="$list $2 $1 ON " + chosen=1 + else + list="$list $2 $1 OFF " + fi ;; *) list="$list $2 $1 OFF " ;; esac @@ -722,13 +728,13 @@ function parser(ifile,menu) { parser(ifile, newmenu) } + else if ($0 ~ /^#|\$MAKE|mainmenu_name/) { + printf("") >>menu + } else if ($1 ~ "endmenu") { printf("}\n") >>menu return } - else if ($0 ~ /^#|\$MAKE|mainmenu_name/) { - printf("") >>menu - } else if ($1 == "source") { parser($2,menu) } @@ -751,12 +757,12 @@ BEGIN { function parser(ifile,menu) { while (getline <ifile) { - if ($1 ~ /mainmenu_option|endmenu/) { - printf("") >>menu - } - else if ($0 ~ /^#|$MAKE|mainmenu_name/) { + if ($0 ~ /^#|$MAKE|mainmenu_name/) { printf("") >>menu } + else if ($1 ~ /mainmenu_option|endmenu/) { + printf("") >>menu + } else if ($1 == "source") { parser($2,menu) } @@ -1192,6 +1198,7 @@ save_configuration () { choices="$2" default="$3" current= + chosen= set -- $choices while [ -n "$2" ] @@ -1215,12 +1222,15 @@ save_configuration () { set -- $choices while [ -n "$2" ] do - if eval [ "$1" = "$current" ] - then - define_bool "$2" "y" - else - define_bool "$2" "n" - fi + case "$1" in + "$current"*) if [ -z "$chosen" ]; then + define_bool "$2" "y" + chosen=1 + else + define_bool "$2" "n" + fi ;; + *) define_bool "$2" "n" ;; + esac shift ; shift done } diff --git a/scripts/tkparse.c b/scripts/tkparse.c index abf5ad8b0..241640f23 100644 --- a/scripts/tkparse.c +++ b/scripts/tkparse.c @@ -326,6 +326,7 @@ static struct condition * tokenize_if( const char * pnt ) static const char * tokenize_choices( struct kconfig * cfg_choose, const char * pnt ) { + int default_checked = 0; for ( ; ; ) { struct kconfig * cfg; @@ -349,12 +350,20 @@ static const char * tokenize_choices( struct kconfig * cfg_choose, cfg->token = token_choice_item; cfg->cfg_parent = cfg_choose; pnt = get_string( pnt, &cfg->label ); + if ( ! default_checked && + ! strncmp( cfg->label, cfg_choose->value, strlen( cfg_choose->value ) ) ) + { + default_checked = 1; + free( cfg_choose->value ); + cfg_choose->value = cfg->label; + } while ( *pnt == ' ' || *pnt == '\t' ) pnt++; pnt = get_string( pnt, &buffer ); cfg->nameindex = get_varnum( buffer ); } - + if ( ! default_checked ) + syntax_error( "bad 'choice' default value" ); return pnt; } @@ -515,7 +524,6 @@ static void tokenize_line( const char * pnt ) pnt = get_qstring ( pnt, &cfg->label ); pnt = get_qstring ( pnt, &choice_list ); pnt = get_string ( pnt, &cfg->value ); - cfg->nameindex = -(choose_number++); tokenize_choices( cfg, choice_list ); free( choice_list ); |