diff -ruN linux-2.4.23-pre6/CREDITS linux-2.4.23-pre6-swsusp/CREDITS --- linux-2.4.23-pre6/CREDITS 2003-10-05 04:16:36.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/CREDITS 2003-10-05 03:45:21.000000000 +0900 @@ -501,6 +501,14 @@ S: Fremont, California 94539 S: USA +N: Florent Chabaud +E: florent.chabaud@polytechnique.org +D: software suspend +S: SGDN/DCSSI/SDS/LTI +S: 58, Bd Latour-Maubourg +S: 75700 Paris 07 SP +S: France + N: Gordon Chaffee E: chaffee@cs.berkeley.edu W: http://bmrc.berkeley.edu/people/chaffee/ @@ -631,6 +639,11 @@ S: NN1 3QT S: United Kingdom +N: Nigel Cunningham +E: ncunningham@clear.net.nz +D: Major Software Suspend enchancements +S: Hastings, New Zealand + N: Stephane Dalton E: sdalton@videotron.ca D: Tieman Voyager USB Braille display driver. @@ -988,6 +1001,13 @@ S: San Jose, California 95131 S: USA +N: Nathan Friess +E: natmanz@shaw.ca +D: software suspend +S: 25 Tararidge Close NE +S: Calgary, Alberta T3J 2P4 +S: Canada + N: Fernando Fuganti E: fuganti@conectiva.com.br E: fuganti@netbank.com.br @@ -1738,6 +1758,11 @@ S: D-91080 Uttenreuth S: Germany +N: Gabor Kuti +E: seasons@falcon.sch.bme.hu +E: seasons@makosteszta.sote.hu +D: software suspend + N: Jaroslav Kysela E: perex@suse.cz W: http://www.perex.cz diff -ruN linux-2.4.23-pre6/Documentation/Configure.help linux-2.4.23-pre6-swsusp/Documentation/Configure.help --- linux-2.4.23-pre6/Documentation/Configure.help 2003-10-05 04:16:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/Documentation/Configure.help 2003-10-05 03:45:21.000000000 +0900 @@ -100,6 +100,69 @@ like MGA monitors that you are very unlikely to see on today's systems. +Software Suspend +CONFIG_SOFTWARE_SUSPEND + Enable the possibilty of suspending your machine to disk. No special + hardware support (BIOS, APM or ACPI) is required, but your milage may + vary because support for hardware is currently limited. This is partly + due to the lack of a driver model in 2.4 and partly due to the fact + that it has been developed for x86+ide in the first instance. + + Please read Documentation/swsusp.txt for more information. + +Debugging info for Software Suspend +CONFIG_SOFTWARE_SUSPEND_DEBUG + This option enables the inclusion of debugging info in the software + suspend code. Turning it off will reduce the kernel size but make + debugging suspend & resume issues harder to do. + + For normal usage, this option can be turned off. + +Compress the Software Suspend image +CONFIG_SOFTWARE_SUSPEND_COMPRESSION + This option enables compression of pages stored during Software Suspend + process. Pages are compressed using the zlib library, with a default + setting (in code) of fastest compression. If your swap device is + significantly slower than your CPU, you may improve the speed of a + suspend/resume cycle by enabling this option. + + You may also benefit from it if your swap space is small. Note, however, + that since we can't know how big the image will be until we actually + compress it, the algorithm assumes no compression will be achieved and + ensures that your data will fit on disk even if that happens. This means + that more memory will be eaten than probably needs to be. The best + solution to this issue is to increase your swapspace size. We may + implement support for a swap file in future. + + This option should be off for most people. + +Keep and reuse Software Suspend images. +CONFIG_SOFTWARE_SUSPEND_KEEP_IMAGE + After resuming, Software Suspend normally frees the swap space it + used for storing your image and resets the swap signature to its + normal state. This stops a future boot from seeing the image and + loading it again, possibly resulting in corruption of your file + system. + + If, however, you are running entirely from read-only filesystems, + it doesn't matter if you boot from the same image a number of times, + as nothing will have changed and there will be no possibility of + corruption. In this case, you might want to enable this option and + read Documentation/swsusp.txt for details on how to use it. + + Since usage of this option also requires explicitly setting a + /proc/swsusp entry, it is safe to say 'Y' here. Most users will however + never use or want this option, and should therefore say 'N' to get an + extra degree of protection against accidentally invoking the functionality. + +Relaxed permissions on /proc/swsusp entries. +CONFIG_SOFTWARE_SUSPEND_RELAXED_PROC + This option makes /proc/swsusp entries world-accessible, rather than + root-only. It is intended for systems where security is not a concern. + + Networked machines, and particularly those where users are granted + shell access, should say 'N' here! + Symmetric Multi-Processing support CONFIG_SMP This enables support for systems with more than one CPU. If you have diff -ruN linux-2.4.23-pre6/Documentation/kernel-parameters.txt linux-2.4.23-pre6-swsusp/Documentation/kernel-parameters.txt --- linux-2.4.23-pre6/Documentation/kernel-parameters.txt 2003-10-05 04:16:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/Documentation/kernel-parameters.txt 2003-10-05 03:45:21.000000000 +0900 @@ -46,6 +46,7 @@ SERIAL Serial support is enabled. SMP The kernel is an SMP kernel. SOUND Appropriate sound system support is enabled. + SWSUSP Software suspension is enabled. V4L Video For Linux support is enabled. VGA The VGA console has been enabled. VT Virtual terminal support is enabled. @@ -415,6 +416,8 @@ initial RAM disk. nointroute [IA-64] + + noresume [SWSUSP] Disables resume and restore original swap space. nolapic [IA-32,APIC] Do not enable or use the local APIC. @@ -536,6 +539,8 @@ reserve= [KNL,BUGS] force the kernel to ignore some iomem area. + resume= [SWSUSP] specify the partition device for software suspension. + riscom8= [HW,SERIAL] ro [KNL] Mount root device read-only on boot. diff -ruN linux-2.4.23-pre6/Documentation/swsusp.txt linux-2.4.23-pre6-swsusp/Documentation/swsusp.txt --- linux-2.4.23-pre6/Documentation/swsusp.txt 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/Documentation/swsusp.txt 2003-10-05 03:42:25.000000000 +0900 @@ -0,0 +1,495 @@ + --- Software Suspend ('swsusp') for Linux, version 1.1 --- + +1. What is it? +2. Why would you want it? +3. What do you need to use it? +4. How do you use it? +5. What do all those entries in /proc/swsusp do? +6. How do you get support? +7. I think I've found a bug. What should I do? +8. What about 2.5 kernels? +9. When will XXX be supported? +10. How does it work? +11. Who wrote Software Suspend? + +1. What is it? + + Imagine you're sitting at your computer, working away. For some reason, you + need to turn off your computer for a while - perhaps it's time to go home + for the day. When you come back to your computer next, you're going to want + to carry on where you left off. Now imagine that you could push a button and + have your computer store the contents of its memory to disk and power down. + Then, when you next start up your computer, it loads that image back into + memory and you can carry on from where you were, just as if you'd never + turned the computer off. Far less time to start up, no reopening + applications and finding what directory you put that file in yesterday. + That's what Software Suspend does. + +2. Why would you want it? + + Why wouldn't you want it? + + Being able to save the state of your system and quickly restore it improves + your productivity - you get a useful system in far less time than through + the normal boot process. + +3. What do you need to use it? + + a. Kernel Support. + + Software Suspend is part of the Linux Kernel. It is not part of Marcelo's + 2.4 tree at the moment, so you will need to download the kernel source and + apply the latest patch. Having done that, enable the appropriate options in + make [menu|x]config (under General Setup), compile and install your kernel. + Software Suspend is incompatible with SMP, scsi and non x86 hardware but + works with preempt support and HighMem. It requires your swap + partitions/files to be on IDE devices. + + Software Suspend patches are available from http://swsusp.sf.net. + + You may also want to apply the optional patches. At the time of writing, + option patches are available to support Bootsplash (www.bootsplash.org, for + an even nicer display during suspend), Laptop mode and Win4Lin. The laptop + mode patch is a variation on Jens Axboe's patch, which disables laptop mode + when suspending. The Win4Lin option patch provides support for Win4Lin. + + Option patches should be applied after the main patch and after Win4Lin + or Bootsplash. + + b. Swapspace. + + Software Suspend can store the suspend image in your swap partition, + a swap file or a combination thereof. Whichever combination you choose, you + will probably want to create enough swap space to store the largest image + you could have, plus the space you'd normally use for swap. A good rule of + thumb would be to calculate the amount of swap you'd want without using + Software Suspend, and then add the amount of memory you have. This swap + space can be arranged in any way you'd like. It can be in one partition or + file, or spread over a number. The only requirement is that they be active + when you start a suspend cycle. + + There is one exception to this requirement. Software Suspend has + the ability to turn on one swap file or partition at the start of + suspending and turn it back off at the end. If you want to ensure you have + enough memory to store a image when your memory is fully used, you might + want to make one swap partition/file for 'normal' use, and another for + Software Suspend to activate & deactivate automatically. (Further details + below). + + c. Bootloader configuration. + + Using Software Suspend also requires that you add an extra parameter to + your lilo.conf or equivalent. Here's an example for a swap partition: + + append="resume=/dev/hda1" + + This would tell Software Suspend that /dev/hda1 is a swap partition you + have. Software Suspend will use the swap signature of this partition as a + pointer to your data when you suspend. This means that (in this example) + /dev/hda1 doesn't need to be _the_ swap partition where all of your data + is actually stored. It just needs to be a swap partition that will be + turned on at suspend time. + + You don't need to have a swap partition for this purpose. Software Suspend + can also use a swap file, but usage is a little more complex. Having made + your swap file, turn it on and do "cat /proc/swsusp/header_locations" + (this assumes you've already compiled your kernel with Software Suspend + support and booted it). The results of the cat command will tell you + what you need to put in lilo.conf: + + For swap partitions like /dev/hda1, simply use resume=/dev/hda1. + For swapfile `swapfile`, use resume=/dev/hda2 resume_block=0x242d. + + If the swapfile changes for any reason (it is moved to a different + location, it is deleted and recreated, or the filesystem is + defragmented) then you will have to check + /proc/swsusp/header_locations for a new resume_block value. + + Once you've compiled and installed the kernel, adjusted your lilo.conf + and rerun lilo, you should only need to reboot for the most basic part + of Software Suspend to be ready. + + d. A suspend script. + + Since 2.4 kernels don't have the driver model that's being developed for + 2.5, you may need to do more, however. Users of Software Suspend usually + start the process via a script which prepares for the suspend, tells the + kernel to do its stuff and then restore things afterwards. This script might + involve: + + - Switching to a text console and back if X doesn't like the video card + status on resume. + - Running /sbin/hwclock [--directisa] to update the clock on resume + - Un/reloading PCMCIA support since it doesn't play well with swsusp. + + Note that you might not be able to unload some drivers if there are + processes using them. You might have to kill off processes that hold + devices open. Hint: if your X server accesses an USB mouse, doing a + 'chvt' to a text console releases the device and you can unload the + module. + + Check out the latest script (available on Sourceforge). + +4. How do you use it? + + Once your script is properly set up, you should just be able to start it + and everything should go like clockwork. Of course things aren't always + that easy out of the box. + + Check out (in the kernel source tree) include/linux/suspend-debug for + settings you can use to get detailed information about what swsusp is doing. + /proc/sys/kernel/swsusp and the kernel parameters swsusp_act, swsusp_dbg + and swsusp_lvl allow you to set the action and debugging parameters prior + to starting a suspend and/or at the lilo prompt before resuming. There is + also a nice little program that should be available from Sourceforge which + makes it easier to turn these debugging settings on and off. Note that to + get any debugging output, you need to enable it when compiling the kernel. + If cat /proc/sys/kernel/swsusp only shows 4 numbers, you didn't do that. + + A neat feature of Software Suspend is that you can press Escape at any time + during suspending, and the process will be aborted. + + Due to the way swsusp works, this means you'll have your system back and + perfectly usable almost instantly. The only exception is when it's at + the very end of writing the image. Then it will need to reload a small + (usually 4-50MBs) portion first. + + If you run into problems with resuming, adding the "noresume" option to + the kernel command line will let you skip the resume step and + (hopefully) recover your system. + +5. What do all those entries in /proc/swsusp do? + + /proc/swsusp is the directory which contains files you can use to tune + and configure Software Suspend to your liking. The exact contents of + the directory will depend upon the version of Software Suspend you're + running, and the options you selected at compile time. In the following + descriptions, names in brackets refer to compile time options that + control whether the file exists. (Note that they're all dependant upon + you having selected CONFIG_SOFTWARE_SUSPEND in the first place!) + + Since the values of these settings can open potential security risks, they + are usually accessible only to the root user. You can, however, enable a + compile time option which makes all of these files world-accessible. This + should only be done if you trust everyone with shell access to this + computer! + + - activate: + + When anything is written to this file swsusp will be activated and suspend + the system. The value is completely ignored. It is just the fact that you + write to the file that initiates the suspend. + + - async_io_limit: + + This value is the limit on the number of pages Software Suspend will submit + for reading or writing at once. The ideal value depends upon the speed of + your hard disks, but the default of 32 should be fine. + + - beeping: + + Set this value to 1 to hear beeps at the different stages of suspending and + resuming. + + - debug_info: + + This file returns information about your configuration that may be helpful + in diagnosing problems with suspending. + + - debug_sections (CONFIG_SOFTWARE_SUSPEND_DEBUG): + + This value, together with the console log level, controls what debugging + information is displayed. The console log level determines the level of + detail, and this value determines what detail is displayed. This value is + a bit vector, and the meaning of the bits can be found in the kernel tree + in include/linux/suspend-debug.h. It can be over-ridden using the kernel's + command line option swsusp_dbg. + + - default_console_level (CONFIG_SOFTWARE_SUSPEND_DEBUG): + + This determines the value of the console log level at the start of a + suspend cycle. If debugging is compiled in, the console log level can be + changed during a cycle by pressing the digit keys. Meanings are: + + 0: Nice display. + 1: Nice display plus numerical progress. + 2: Errors only. + 3: Low level debugging info. + 4: Medium level debugging info. + 5: High level debugging info. + 6: Verbose debugging info. + + This value can be over-ridden using the kernel command line option + swsusp_lvl. + + - disable_compression (CONFIG_SOFTWARE_SUSPEND_COMPRESSION): + + If compression support is compiled in, this option can be used to disable + compression support. + + - enable_escape: + + Setting this to "1" will enable you abort a suspend by + pressing escape, "0" (default) disables this feature. Note that enabling + this option means that you cannot initiate a suspend and then walk away + from your computer, expecting it to be secure. With feature disabled, + you can validly have this expectation once Suspend begins to write the + image to disk. (Prior to this point, it is possible that Suspend might + about because of failure to freeze all processes or because constraints + on its ability to save the image are not met). + + - expected_compression (CONFIG_SOFTWARE_SUSPEND_COMPRESSION): + + This value allows you to set an expected compression ratio, which Software + Suspend will use in calculating whether it meets constraints on the image + size. If this expected compression ratio is not attained, the suspend will + abort, so it is wise to allow some spare. You can see what compression + ratio is achieved in the logs after suspending. + + - header_locations: + + This option tells you the resume= options to use for swap devices you + currently have activated. It is particularly useful when you only want to + use a swap file to store your image. See above for further details. + + - image_size_limit: + + The maximum size of suspend image written to disk, measured in megabytes + (1024*1024). + + - interface_version: + + The value returned by this file can be used by scripts and configuration + tools to determine what entries should be looked for. The value is + incremented whenever an entry in /proc/swsusp is obsoleted or added. + + - last_result: + + The result of the last suspend, as defined in + include/linux/suspend-debug.h with the values SUSPEND_ABORTED to + SUSPEND_KEPT_IMAGE. This is a bitmask. + + - log_everything (CONFIG_SOFTWARE_SUSPEND_DEBUG): + + Setting this option results in all messages printed being logged. Normally, + only a subset are logged, so as to not slow the process and not clutter the + logs. Useful for debugging. It can be toggled during a cycle by pressing + 'L'. + + - no_output: + + Setting this to "1" disables all output from suspend. It may be useful if a + distribution wants to implement a static display while suspending. + + - pause_between_steps (CONFIG_SOFTWARE_SUSPEND_DEBUG): + + This option is used during debugging, to make Software Suspend pause between + each step of the process. It is ignored when the nice display is on. + + - progressbar_granularity_limit (CONFIG_FBCON_SPLASHSCREEN): + + This option can be used to limit the granularity of the progress bar + displayed with a bootsplash screen. The value is the maximum number of + steps. That is, 10 will make the progress bar jump in 10% increments. + + - reboot (CONFIG_SOFTWARE_SUSPEND_DEBUG): + + This option causes Software Suspend to reboot rather than powering down + at the end of saving an image. It can be toggled during a cycle by pressing + 'R'. + + - slow: + + This option inserts a couple of one+ second delays in the code. It should + not be needed, and may disappear in a future version. + + - swapfile: + + This entry is used to specify the swapfile or partition that + Software Suspend will attempt to swapon/swapoff automatically. Thus, if + I normally use /dev/hda1 for swap, and want to use /dev/hda2 for specifically + for my suspend image, I would + + echo /dev/hda2 > /proc/swsusp/swapfile + + /dev/hda2 would then be automatically swapon'd and swapoff'd. Note that the + swapon and swapoff occur while other processes are frozen (including kswapd) + so this swap file will not be used up when attempting to free memory. The + parition/file is also given the highest priority, so other swapfiles/partitions + will only be used to save the image when this one is filled. + + The value of this file is used by header_locations along with any currently + activated swapfiles/partitions. + + - version: + + The version of swsusp you have compiled into the currently running kernel. + +6. How do you get support? + + Glad you asked. Software Suspend is being actively maintained and supported, + both by Nigel (the guy doing most of the coding at the moment) and its + users. You can find the mailing list via the Sourceforge project page. + +7. I think I've found a bug. What should I do? + + If you're seeing Software Suspend hang at some point, and especially if + lights are flashing on your keyboard, you should compile in debugging + support and try... + + echo 1 > /proc/swsusp/debug_sections + echo 3 > /proc/swsusp/default_console_level + echo > /proc/swsusp/activate + + You should then see low level debugging information and eventually an + oops. + + Good information on how to provide us with useful information from an + oops is found in the file REPORTING-BUGS, in the top level directory + of the kernel tree. If you get an oops, please especially note the + information about running what is printed on the screen through ksymoops. + The raw information is useless. + + You might also read the FAQ and HOWTO on the web site for known issues, + and subscribe to the mailing list. + + Beginning with 1.1rc10, you should include the contents of + /proc/swsusp/debug_info in your report. Prior to this version, similar + information is written to /var/log/messages at the end of a successful + resume and should be sent. It is also a good idea to check /var/log/messages + for relevant information as well. Information from the unloading and + reloading of drivers and modules prior to and after suspending is sometimes + helpful. + +8. What about 2.6 kernels? + + There is a version of Software Suspend already included in the 2.6 kernel + tree. Unfortunately, it lacks a large proportion of the features in 2.4. + Now that the 1.1 release of the 2.4 version is nearly done, work is underway + to complete the port to 2.6 (which shouldn't take long). The struggle + will then be to get it integrated into Linus' tree (don't expect this to + be quick). + +9. When will XXX be supported? + + Software Suspend currently lacks support for SMP, non x86 and SCSI. + + Patches for the other items (and anything that's been missed) are welcome. + Please send to the list. + + Because Nigel's main task is definitely not Software Suspend and he doesn't + have the hardware, he will be unlikely to develop support for any of these + in the near future. His development work to date has been driven by the + desire to be a user of a more feature complete Software Suspend. + +10. How does it work? + + Software Suspend does its work in a number of steps. + + a. Freezing system activity. + + The first main stage in suspending is to stop all other activity. This is + achieved in stages. First, we stop tasks from submitting new I/O using hooks + in the system calls for reading, writing and at a number of other places as + well as at the kernel threads that start I/O. If any tasks are syncing, + we wait for them to complete. We then do our own sync, just in case no + syncs were running. Next, we stop all the others tasks. Some are signalled + and put in a 'refrigerator'. Others are simply not scheduled again until we + decide to wake them up. + + b. Eating memory. + + For a successful suspend, you need to have enough disk space to store the + image and enough memory for the various limitations of Software Suspend's + algorithm. You can also specify a maximum image size. In order to attain + to those constraints, Software Suspend may 'eat' memory. If, after freezing + processes, the constraints aren't met, Software Suspend will thaw all the + other processes and begin to eat memory until its calculations indicate + the constraints are met. It will then freeze processes again and recheck + its calculations. + + c. Suspending drivers and storing processor context. + + Software Suspend then calls the power management functions to notify + drivers of the suspend, and saves the processor state. + + d. Storage of meta data and image. + + Next, Software Suspend allocates the swap pages that will be used to save + the image and stores their locations, along with the locations of the pages + to be saved in what we call pagesets or pagedirs. Software Suspend stores + data in two pagesets. Pageset 2 contains pages on the active and inactive + lists; essentially the page cache. Pageset 1 contains all other pages, + including the kernel. We use two pagesets for one important reason: We + need to make an atomic copy of the kernel to ensure consistency of the + image. Without a second pagedir, that would limit us to an image that was + at most half the amount of memory available. Using two pagesets allows us + to store a full image. Since pageset 2 pages won't be needed in saving + pageset 1, we first save pageset 2 pages. We can then make our atomic copy + of the remaining pages using both pageset 2 pages and any other pages that + are free. While saving both pagesets, we are careful not to corrupt the + image. We immediately shoot down pages that are added to the page cache, + and we allocate a special memory pool of extra pages that can be used by + during suspending. All of the pages in this pool are saved along with the + rest of the pageset 1 pages, even if they're not used. This saves us having + to worry about the image becoming inconsistent while we're saving it. + + e. Save a second copy of the pagedirs. + + To reload pagedir 1 at resume time, we need to know where the data is + stored. This requires the saving of a second copy of the pagedirs. + + f. Save the suspend header. + + Nearly there! We save our settings and other parameters needed for + reloading pagedir 1 in a 'suspend header' this is a single swap page. + + g. Set the swap header. + + Finally, we edit the swap header for our resume= swap file/partition. The + swap signature is changed to record what kind of header it originally was + (swapspace 1 or 2) and the bdev and first block and block size details of + the suspend header. + + h. Power down. + + Or reboot if we're debugging and the appropriate option is selected. + + Whew! + + Reloading the image. + -------------------- + + Reloading the image is essentially the reverse of all the above. We load + our copy of pagedir 1, being careful to choose locations that aren't going + to be overwritten as we copy it back (We start very early in the boot + process, so there are no other processes to quiesce here). We then copy + pagedir 1 back to its original location in memory and restore the process + context. We are now running with the original kernel. Next, we reload the + pageset 2 pages, free the memory and swap used by Software Suspend, restore + the pagedir header and restart processes. Sounds easy in comparison to + suspending, doesn't it! + + There is of course more to Software Suspend than this, but this explanation + should be a good start. If there's interest, I'll write further + documentation on range pages and the low level I/O. + +11. Who wrote Software Suspend? + + (Answer based on the writings of Florent Chabaud, credits in files and + Nigel's limited knowledge; apologies to anyone missed out!) + + The main developers of Software Suspend have been... + + Gabor Kuti + Pavel Machek + Florent Chabaud + Nigel Cunningham + + They have been aided in their efforts by a host of hundreds, if not thousands + of testers and people who have submitted bug fixes & suggestions. Of special + note are the efforts of Michael Frank, who had his computers repetitively + suspend and resume for literally tens of thousands of cycles and developed + scripts to stress the system and test Software Suspend far beyond the point + most of us (Nigel included!) would consider testing. His efforts have + contributed as much to Software Suspend as any of the names above. diff -ruN linux-2.4.23-pre6/Documentation/sysctl/kernel.txt linux-2.4.23-pre6-swsusp/Documentation/sysctl/kernel.txt --- linux-2.4.23-pre6/Documentation/sysctl/kernel.txt 2001-10-01 04:26:08.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/Documentation/sysctl/kernel.txt 2003-10-05 03:42:25.000000000 +0900 @@ -39,6 +39,7 @@ - rtsig-max - sg-big-buff [ generic SCSI device (sg) ] - shmmax [ sysv ipc ] +- swsusp ==> Documentation/swsusp.txt - tainted - version - zero-paged [ PPC only ] @@ -221,6 +222,12 @@ ============================================================== +swsusp: + +Please see kernel/suspend.c for up-to-date documentation. + +============================================================== + tainted: Non-zero if the kernel has been tainted. Numeric values, which diff -ruN linux-2.4.23-pre6/MAINTAINERS linux-2.4.23-pre6-swsusp/MAINTAINERS --- linux-2.4.23-pre6/MAINTAINERS 2003-10-05 04:16:46.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/MAINTAINERS 2003-10-05 03:45:24.000000000 +0900 @@ -1660,6 +1660,13 @@ L: linux-raid@vger.kernel.org S: Maintained +SOFTWARE SUSPEND: +P: Nigel Cunningham +M: ncunningham@clear.net.nz +L: http://lister.fornax.hu/mailman/listinfo/swsusp +W: http://swsusp.sf.net/ +S: Maintained + SONIC NETWORK DRIVER P: Thomas Bogendoerfer M: tsbogend@alpha.franken.de diff -ruN linux-2.4.23-pre6/Makefile linux-2.4.23-pre6-swsusp/Makefile --- linux-2.4.23-pre6/Makefile 2003-10-05 04:16:46.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/Makefile 2003-10-05 03:59:56.000000000 +0900 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 23 -EXTRAVERSION = -pre6 +EXTRAVERSION = -pre6-swsusp KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -38,7 +38,7 @@ GENKSYMS = /sbin/genksyms DEPMOD = /sbin/depmod MODFLAGS = -DMODULE -CFLAGS_KERNEL = +CFLAGS_KERNEL = PERL = perl AWK = awk RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \ diff -ruN linux-2.4.23-pre6/arch/i386/config.in linux-2.4.23-pre6-swsusp/arch/i386/config.in --- linux-2.4.23-pre6/arch/i386/config.in 2003-10-05 04:16:36.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/config.in 2003-10-05 03:45:20.000000000 +0900 @@ -327,6 +327,8 @@ bool 'Power Management support' CONFIG_PM +source kernel/power/Config.in + dep_tristate ' Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM if [ "$CONFIG_APM" != "n" ]; then bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND diff -ruN linux-2.4.23-pre6/arch/i386/defconfig linux-2.4.23-pre6-swsusp/arch/i386/defconfig --- linux-2.4.23-pre6/arch/i386/defconfig 2003-10-05 04:16:36.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/defconfig 2003-10-05 03:45:20.000000000 +0900 @@ -110,6 +110,7 @@ CONFIG_BINFMT_MISC=y CONFIG_PM=y # CONFIG_APM is not set +# CONFIG_SOFTWARE_SUSPEND is not set # # Memory Technology Devices (MTD) diff -ruN linux-2.4.23-pre6/arch/i386/kernel/apm.c linux-2.4.23-pre6-swsusp/arch/i386/kernel/apm.c --- linux-2.4.23-pre6/arch/i386/kernel/apm.c 2003-08-25 20:44:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/kernel/apm.c 2003-10-05 03:42:25.000000000 +0900 @@ -1710,6 +1710,7 @@ daemonize(); strcpy(current->comm, "kapmd"); + current->flags |= PF_SYNCTHREAD; sigfillset(¤t->blocked); #ifdef CONFIG_SMP diff -ruN linux-2.4.23-pre6/arch/i386/kernel/mtrr.c linux-2.4.23-pre6-swsusp/arch/i386/kernel/mtrr.c --- linux-2.4.23-pre6/arch/i386/kernel/mtrr.c 2003-06-13 23:51:29.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/kernel/mtrr.c 2003-10-05 03:42:25.000000000 +0900 @@ -270,6 +270,7 @@ #include #include #include +#include #include #include @@ -2305,6 +2306,68 @@ return 0; } /* End Function mtrr_init */ +#ifdef SOFTWARE_SUSPEND_MTRR +struct mtrr_suspend_state +{ + mtrr_type ltype; + unsigned long lbase, lsize; +}; +/* We return a pointer ptr on an area of *ptr bytes + beginning at ptr+sizeof(int) + This buffer has to be saved in some way during suspension */ +int *mtrr_suspend(void) +{ + int i, max, len; + int *ptr = NULL; + static struct mtrr_suspend_state *mtrr_suspend_buffer=NULL; + + max = get_num_var_ranges (); + if(!mtrr_suspend_buffer) + { + len = max * sizeof (struct mtrr_suspend_state) + sizeof(int); + ptr = kmalloc (len, GFP_KERNEL); + if (ptr == NULL) + return(NULL); + *ptr = len; + ptr++; + mtrr_suspend_buffer = (struct mtrr_suspend_state *)ptr; + ptr--; + } + for (i = 0; i < max; ++i,mtrr_suspend_buffer++) + (*get_mtrr) (i, + &(mtrr_suspend_buffer->lbase), + &(mtrr_suspend_buffer->lsize), + &(mtrr_suspend_buffer->ltype)); + return(ptr); +} + +/* We restore mtrrs from buffer ptr */ +int mtrr_resume(int *ptr) +{ + int i, max, len; + struct mtrr_suspend_state *mtrr_suspend_buffer; + + max = get_num_var_ranges (); + len = max * sizeof (struct mtrr_suspend_state) + sizeof(int); + if(*ptr != len) + { + printk ("mtrr: Resuming failed due to different number of MTRRs\n"); + return (-1); + } + ptr++; + mtrr_suspend_buffer=(struct mtrr_suspend_state *)ptr; + for (i = 0; i < max; ++i,mtrr_suspend_buffer++) + if (mtrr_suspend_buffer->lsize) + set_mtrr(i, + mtrr_suspend_buffer->lbase, + mtrr_suspend_buffer->lsize, + mtrr_suspend_buffer->ltype); + return(0); +} +EXPORT_SYMBOL(mtrr_suspend); +EXPORT_SYMBOL(mtrr_resume); +#endif + /* * Local Variables: * mode:c diff -ruN linux-2.4.23-pre6/arch/i386/kernel/process.c linux-2.4.23-pre6-swsusp/arch/i386/kernel/process.c --- linux-2.4.23-pre6/arch/i386/kernel/process.c 2003-10-05 04:16:36.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/kernel/process.c 2003-10-05 03:45:20.000000000 +0900 @@ -749,6 +749,36 @@ } } +#ifdef CONFIG_SOFTWARE_SUSPEND +/** + * swsusp_power_off - ask the BIOS to power off + * + * Handle the power off sequence. This is the one piece of code we + * will execute even on SMP machines. In order to deal with BIOS + * bugs we support real mode APM BIOS power off calls. We also make + * the SMP call on CPU0 as some systems will only honour this call + * on their first cpu. + * + * This piece of code is extracted from apm.c. We want to be able + * to do this even if apm isn't activated. + */ + +void swsusp_power_off(void) +{ + unsigned char po_bios_call[] = { + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */ + 0x8e, 0xd0, /* movw ax,ss */ + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */ + 0xb8, 0x07, 0x53, /* movw $0x5307,ax */ + 0xbb, 0x01, 0x00, /* movw $0x0001,bx */ + 0xb9, 0x03, 0x00, /* movw $0x0003,cx */ + 0xcd, 0x15 /* int $0x15 */ + }; + + machine_real_restart(po_bios_call, sizeof(po_bios_call)); +} +#endif + asmlinkage int sys_fork(struct pt_regs regs) { return do_fork(SIGCHLD, regs.esp, ®s, 0); diff -ruN linux-2.4.23-pre6/arch/i386/kernel/signal.c linux-2.4.23-pre6-swsusp/arch/i386/kernel/signal.c --- linux-2.4.23-pre6/arch/i386/kernel/signal.c 2002-08-03 09:39:42.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/kernel/signal.c 2003-10-05 03:42:25.000000000 +0900 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -595,6 +596,11 @@ if ((regs->xcs & 3) != 3) return 1; + if (current->flags & PF_FREEZE) { + refrigerator(0); + goto no_signal; + } + if (!oldset) oldset = ¤t->blocked; @@ -702,6 +708,7 @@ return 1; } + no_signal: /* Did we come from a system call? */ if (regs->orig_eax >= 0) { /* Restart the system call - no handlers present */ diff -ruN linux-2.4.23-pre6/arch/i386/mm/fault.c linux-2.4.23-pre6-swsusp/arch/i386/mm/fault.c --- linux-2.4.23-pre6/arch/i386/mm/fault.c 2002-11-29 08:53:09.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/mm/fault.c 2003-10-05 03:42:25.000000000 +0900 @@ -325,6 +325,7 @@ printk(KERN_ALERT "*pte = %08lx\n", page); } die("Oops", regs, error_code); + printk("\n"); bust_spinlocks(0); do_exit(SIGKILL); diff -ruN linux-2.4.23-pre6/arch/i386/mm/pageattr.c linux-2.4.23-pre6-swsusp/arch/i386/mm/pageattr.c --- linux-2.4.23-pre6/arch/i386/mm/pageattr.c 2002-11-29 08:53:09.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/mm/pageattr.c 2003-10-05 03:42:25.000000000 +0900 @@ -15,7 +15,8 @@ #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT) -static inline pte_t *lookup_address(unsigned long address) +// Also used in kernel/suspend/low_level_io.c +inline pte_t *lookup_address(unsigned long address) { pmd_t *pmd; pgd_t *pgd = pgd_offset(&init_mm, address); diff -ruN linux-2.4.23-pre6/arch/i386/vmlinux.lds linux-2.4.23-pre6-swsusp/arch/i386/vmlinux.lds --- linux-2.4.23-pre6/arch/i386/vmlinux.lds 2002-02-26 04:37:53.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/arch/i386/vmlinux.lds 2003-10-05 03:42:25.000000000 +0900 @@ -53,6 +53,12 @@ __init_end = .; . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; + + . = ALIGN(4096); .data.page_aligned : { *(.data.idt) } . = ALIGN(32); diff -ruN linux-2.4.23-pre6/drivers/acpi/system.c linux-2.4.23-pre6-swsusp/drivers/acpi/system.c --- linux-2.4.23-pre6/drivers/acpi/system.c 2003-08-25 20:44:41.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/acpi/system.c 2003-10-05 03:42:25.000000000 +0900 @@ -47,6 +47,7 @@ #include #endif #endif +#include #define _COMPONENT ACPI_SYSTEM_COMPONENT @@ -127,7 +128,10 @@ * interrupts. */ #ifdef CONFIG_X86 - init_8259A(0); +#ifdef CONFIG_SOFTWARE_SUSPEND + if (state != ACPI_STATE_S4) +#endif + init_8259A(0); #endif /* wait for power to come back */ mdelay(1000); @@ -304,7 +308,7 @@ u32 state) { acpi_status status; - + int swsusp=0; /* only support S1 and S5 on kernel 2.4 */ if (state != ACPI_STATE_S1 && state != ACPI_STATE_S4 && state != ACPI_STATE_S5) @@ -312,6 +316,9 @@ if (ACPI_STATE_S4 == state) { +#ifdef CONFIG_SOFTWARE_SUSPEND + swsusp=1; +#else /* For s4bios, we need a wakeup address. */ if (1 == acpi_gbl_FACS->S4bios_f && 0 != acpi_gbl_FADT->smi_cmd) { @@ -321,6 +328,7 @@ } else /* We don't support S4 under 2.4. Give up */ return AE_ERROR; +#endif } status = acpi_system_save_state(state); @@ -334,12 +342,17 @@ ACPI_FLUSH_CPU_CACHE(); /* perform OS-specific sleep actions */ - status = acpi_system_suspend(state); - - /* Even if we failed to go to sleep, all of the devices are in an suspended - * mode. So, we run these unconditionaly to make sure we have a usable system - * no matter what. - */ + if(swsusp) { /* we just ignore acpi architecture for the moment */ + software_suspend_pending(); /* when we return, this is resume */ + status = AE_OK; + } else { + status = acpi_system_suspend(state); + + /* Even if we failed to go to sleep, all of the devices are in an suspended + * mode. So, we run these unconditionaly to make sure we have a usable system + * no matter what. + */ + } acpi_leave_sleep_state(state); acpi_system_restore_state(state); @@ -384,10 +397,15 @@ for (i=0; istates[i]) { p += sprintf(p, "S%d ", i); - if (i == ACPI_STATE_S4 && - acpi_gbl_FACS->S4bios_f && - 0 != acpi_gbl_FADT->smi_cmd) - p += sprintf(p, "S4Bios "); + if (i == ACPI_STATE_S4) { +#ifdef CONFIG_SOFTWARE_SUSPEND + p += sprintf(p, "(swsusp) "); +#else + if(acpi_gbl_FACS->S4bios_f && + 0 != acpi_gbl_FADT->smi_cmd) + p += sprintf(p, "(Bios) "); +#endif + } } } p += sprintf(p, "\n"); @@ -690,9 +708,15 @@ for (i = 0; i <= ACPI_STATE_S5; i++) { if (system->states[i]) { p += sprintf(p,"S%d ", i); - if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f && - acpi_gbl_FADT->smi_cmd != 0) - p += sprintf(p, "S4Bios "); + if (i == ACPI_STATE_S4) { +#ifdef CONFIG_SOFTWARE_SUSPEND + p += sprintf(p, "(swsusp) "); +#else + if(acpi_gbl_FACS->S4bios_f && + acpi_gbl_FADT->smi_cmd != 0) + p += sprintf(p, "(Bios) "); +#endif + } } } @@ -1244,10 +1268,16 @@ case ACPI_STATE_S4: if (acpi_gbl_FACS->S4bios_f && 0 != acpi_gbl_FADT->smi_cmd) { - printk(" S4bios"); + printk(" S4 (bios)"); + system->states[i] = 1; + } +#ifdef CONFIG_SOFTWARE_SUSPEND + else { + printk(" S4 (swsusp)"); system->states[i] = 1; } - /* no break */ +#endif + break; default: if (ACPI_SUCCESS(status)) { system->states[i] = 1; diff -ruN linux-2.4.23-pre6/drivers/block/ll_rw_blk.c linux-2.4.23-pre6-swsusp/drivers/block/ll_rw_blk.c --- linux-2.4.23-pre6/drivers/block/ll_rw_blk.c 2003-08-25 20:44:41.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/block/ll_rw_blk.c 2003-10-05 03:42:25.000000000 +0900 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -1207,6 +1208,10 @@ if (!bh->b_end_io) BUG(); +#if 0 + if (suspend_device && (bh->b_rdev != suspend_device)) + panic("Attempted to corrupt disk."); +#endif /* Test device size, when known. */ if (blk_size[major]) minorsize = blk_size[major][MINOR(bh->b_rdev)]; diff -ruN linux-2.4.23-pre6/drivers/block/loop.c linux-2.4.23-pre6-swsusp/drivers/block/loop.c --- linux-2.4.23-pre6/drivers/block/loop.c 2003-08-25 20:44:41.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/block/loop.c 2003-10-05 03:42:25.000000000 +0900 @@ -581,7 +581,9 @@ atomic_inc(&lo->lo_pending); spin_unlock_irq(&lo->lo_lock); - current->flags |= PF_NOIO; + current->flags |= PF_NOIO | PF_NOFREEZE; /* loop can be used in an encrypted device + hence, it mustn't be stopped at all because it could + be indirectly used during suspension */ /* * up sem, we are running diff -ruN linux-2.4.23-pre6/drivers/char/agp/agpgart_be.c linux-2.4.23-pre6-swsusp/drivers/char/agp/agpgart_be.c --- linux-2.4.23-pre6/drivers/char/agp/agpgart_be.c 2003-10-05 04:16:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/char/agp/agpgart_be.c 2003-10-05 03:45:21.000000000 +0900 @@ -585,7 +585,7 @@ agp_bridge.gatt_table_real = (u32 *) table; agp_gatt_table = (void *)table; -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) && !defined(CONFIG_SOFTWARE_SUSPEND) err = change_page_attr(virt_to_page(table), 1<real)); CACHE_FLUSH(); -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) && !defined(CONFIG_SOFTWARE_SUSPEND) err = change_page_attr(virt_to_page(page_map->real), 1, PAGE_KERNEL_NOCACHE); #endif if (!err) @@ -3062,7 +3058,7 @@ static void amd_free_page_map(amd_page_map *page_map) { iounmap(page_map->remapped); -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) && !defined(CONFIG_SOFTWARE_SUSPEND) change_page_attr(virt_to_page(page_map->real), 1, PAGE_KERNEL); #endif ClearPageReserved(virt_to_page(page_map->real)); @@ -4200,7 +4196,7 @@ return -ENOMEM; } SetPageReserved(virt_to_page(page_map->real)); -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) && !defined(CONFIG_SOFTWARE_SUSPEND) err = change_page_attr(virt_to_page(page_map->real), 1, PAGE_KERNEL_NOCACHE); #endif CACHE_FLUSH(); @@ -4224,7 +4220,7 @@ static void serverworks_free_page_map(serverworks_page_map *page_map) { -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) && !defined(CONFIG_SOFTWARE_SUSPEND) change_page_attr(virt_to_page(page_map->real),1,PAGE_KERNEL); #endif iounmap(page_map->remapped); diff -ruN linux-2.4.23-pre6/drivers/char/console.c linux-2.4.23-pre6-swsusp/drivers/char/console.c --- linux-2.4.23-pre6/drivers/char/console.c 2003-10-05 04:16:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/char/console.c 2003-10-05 03:45:21.000000000 +0900 @@ -147,13 +147,13 @@ static void vc_init(unsigned int console, unsigned int rows, unsigned int cols, int do_clear); static void blank_screen(unsigned long dummy); -static void gotoxy(int currcons, int new_x, int new_y); +static void gotoxy(int currcons, unsigned int new_x, unsigned int new_y); static void save_cur(int currcons); -static void reset_terminal(int currcons, int do_clear); +void reset_terminal(int currcons, int do_clear); static void con_flush_chars(struct tty_struct *tty); static void set_vesa_blanking(unsigned long arg); static void set_cursor(int currcons); -static void hide_cursor(int currcons); +void hide_cursor(int currcons); static void unblank_screen_t(unsigned long dummy); static void console_callback(void *ignored); @@ -531,7 +531,7 @@ sw->con_putc(vc_cons[currcons].d, i, y, x); } -static void hide_cursor(int currcons) +void hide_cursor(int currcons) { if (currcons == sel_cons) clear_selection(); @@ -857,9 +857,9 @@ * might also be negative. If the given position is out of * bounds, the cursor is placed at the nearest margin. */ -static void gotoxy(int currcons, int new_x, int new_y) +static void gotoxy(int currcons, unsigned int new_x, unsigned int new_y) { - int min_y, max_y; + unsigned int min_y, max_y; if (new_x < 0) x = 0; @@ -886,7 +886,7 @@ } /* for absolute user moves, when decom is set */ -static void gotoxay(int currcons, int new_x, int new_y) +static void gotoxay(int currcons, unsigned int new_x, unsigned int new_y) { gotoxy(currcons, new_x, decom ? (top+new_y) : new_y); } @@ -1398,7 +1398,7 @@ ESpalette }; /* console_sem is held (except via vc_init()) */ -static void reset_terminal(int currcons, int do_clear) +void reset_terminal(int currcons, int do_clear) { top = 0; bottom = video_num_lines; @@ -2983,13 +2983,13 @@ return screenpos(currcons, 2 * w_offset, viewed); } -void getconsxy(int currcons, char *p) +void getconsxy(int currcons, unsigned char *p) { p[0] = x; p[1] = y; } -void putconsxy(int currcons, char *p) +void putconsxy(int currcons, unsigned char *p) { gotoxy(currcons, p[0], p[1]); set_cursor(currcons); @@ -3038,6 +3038,8 @@ EXPORT_SYMBOL(vc_resize); EXPORT_SYMBOL(fg_console); EXPORT_SYMBOL(console_blank_hook); +EXPORT_SYMBOL(hide_cursor); +EXPORT_SYMBOL(reset_terminal); #ifdef CONFIG_VT EXPORT_SYMBOL(vt_cons); #endif diff -ruN linux-2.4.23-pre6/drivers/char/keyboard.c linux-2.4.23-pre6-swsusp/drivers/char/keyboard.c --- linux-2.4.23-pre6/drivers/char/keyboard.c 2003-10-05 04:16:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/char/keyboard.c 2003-10-05 03:45:22.000000000 +0900 @@ -32,6 +32,10 @@ #include #include #include +#ifdef CONFIG_SOFTWARE_SUSPEND +#include +#include +#endif #include #include @@ -152,7 +156,7 @@ struct pt_regs * kbd_pt_regs; #ifdef CONFIG_MAGIC_SYSRQ -static int sysrq_pressed; +int sysrq_pressed; /* Made non static so swsusp can reset on resume */ #endif static struct pm_dev *pm_kbd; @@ -263,6 +267,13 @@ } else rep = test_and_set_bit(keycode, key_down); +#ifdef CONFIG_KDB + if (!up_flag && (keycode == E1_PAUSE) && kdb_on) { + kdb(KDB_REASON_KEYBOARD, 0, kbd_pt_regs); + return; + } +#endif /* CONFIG_KDB */ + #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ if (keycode == SYSRQ_KEY) { sysrq_pressed = !up_flag; @@ -275,6 +286,63 @@ } #endif +#ifdef CONFIG_SOFTWARE_SUSPEND + if (!up_flag && (software_suspend_state == SOFTWARE_SUSPEND_RUNNING)) { + extern void prepare_status(int printalways, int clearbar, const char *fmt, ...); + extern unsigned long swsusp_action; + extern void request_abort_suspend(void); + switch (keycode) { + case 60: + case 1: + /* Abort suspend */ + if (TEST_ACTION_STATE(SUSPEND_CAN_CANCEL)) + request_abort_suspend(); + break; +#ifdef CONFIG_SOFTWARE_SUSPEND_DEBUG + case 101: + case 119: + /* During suspend, toggle pausing with Pause or Break if kdb active */ + swsusp_action ^= (1 << SUSPEND_PAUSE); + prepare_status(1, 0, "Pausing %s.\n", + TEST_ACTION_STATE(SUSPEND_PAUSE) ? "enabled" : "disabled"); + break; + case 19: + /* Otherwise, if R pressed, toggle rebooting */ + swsusp_action ^= (1 << SUSPEND_REBOOT); + prepare_status(1, 0, "Rebooting %s.\n", + TEST_ACTION_STATE(SUSPEND_REBOOT) ? "enabled" : "disabled"); + break; + case 38: + /* Otherwise, if L pressed, toggle logging everything */ + swsusp_action ^= (1 << SUSPEND_LOGALL); + prepare_status(1, 0, "Logging all output %s.\n", + TEST_ACTION_STATE(SUSPEND_LOGALL) ? "enabled" : "disabled"); + break; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + console_loglevel = ((keycode - 1)); + break; + case 11: + console_loglevel = 0; + break; + } + if ((keycode != 42) && (keycode != 58)) + goto out; +#else + } + if (keycode != 42) + goto out; +#endif + } +#endif + if (kbd->kbdmode == VC_MEDIUMRAW) { /* soon keycodes will require more than one byte */ put_queue(keycode + up_flag); diff -ruN linux-2.4.23-pre6/drivers/char/pc_keyb.c linux-2.4.23-pre6-swsusp/drivers/char/pc_keyb.c --- linux-2.4.23-pre6/drivers/char/pc_keyb.c 2002-11-29 08:53:12.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/char/pc_keyb.c 2003-10-05 03:42:25.000000000 +0900 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -1105,11 +1106,13 @@ DECLARE_WAITQUEUE(wait, current); ssize_t i = count; unsigned char c; + DECLARE_SWSUSP_LOCAL_VAR; if (queue_empty()) { if (file->f_flags & O_NONBLOCK) return -EAGAIN; add_wait_queue(&queue->proc_list, &wait); + SWSUSP_ACTIVITY_PAUSING; repeat: set_current_state(TASK_INTERRUPTIBLE); if (queue_empty() && !signal_pending(current)) { @@ -1117,6 +1120,7 @@ goto repeat; } current->state = TASK_RUNNING; + SWSUSP_ACTIVITY_RESTARTING(0); remove_wait_queue(&queue->proc_list, &wait); } while (i > 0 && !queue_empty()) { diff -ruN linux-2.4.23-pre6/drivers/char/sysrq.c linux-2.4.23-pre6-swsusp/drivers/char/sysrq.c --- linux-2.4.23-pre6/drivers/char/sysrq.c 2003-08-25 20:44:41.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/char/sysrq.c 2003-10-05 03:42:25.000000000 +0900 @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -47,7 +48,8 @@ int i; i = key - '0'; console_loglevel = 7; - printk("Loglevel set to %d\n", i); + if (!suspend_task) + printk("Loglevel set to %d\n", i); console_loglevel = i; } static struct sysrq_key_op sysrq_loglevel_op = { @@ -137,8 +139,19 @@ static void go_sync(struct super_block *sb, int remount_flag) { int orig_loglevel; + +#ifdef CONFIG_SOFTWARE_SUSPEND + if (suspend_task) { + printk(KERN_INFO "Not %sing device %s. Suspend may have used memory with dirty data!", + remount_flag ? "remount" : "sync", + kdevname(sb->s_dev)); + return; + } +#endif + orig_loglevel = console_loglevel; console_loglevel = 7; + printk(KERN_INFO "%sing device %s ... ", remount_flag ? "Remount" : "Sync", kdevname(sb->s_dev)); @@ -442,7 +455,8 @@ return; orig_log_level = console_loglevel; - console_loglevel = 7; + if (!suspend_task) /* Not if nice display on */ + console_loglevel = 7; printk(KERN_INFO "SysRq : "); op_p = __sysrq_get_key_op(key); diff -ruN linux-2.4.23-pre6/drivers/char/tty_io.c linux-2.4.23-pre6-swsusp/drivers/char/tty_io.c --- linux-2.4.23-pre6/drivers/char/tty_io.c 2003-10-05 04:16:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/char/tty_io.c 2003-10-05 03:45:22.000000000 +0900 @@ -90,6 +90,7 @@ #include #include #include +#include #include #include @@ -655,6 +656,7 @@ int i; struct tty_struct * tty; struct inode *inode; + DECLARE_SWSUSP_LOCAL_VAR; /* Can't seek (pread) on ttys. */ if (ppos != &file->f_pos) @@ -683,6 +685,7 @@ return -ERESTARTSYS; } #endif + SWSUSP_ACTIVITY_PAUSING; /* read_chan or equiv shouldn't stop a suspend */ lock_kernel(); if (tty->ldisc.read) i = (tty->ldisc.read)(tty,file,buf,count); @@ -691,6 +694,7 @@ unlock_kernel(); if (i > 0) inode->i_atime = CURRENT_TIME; + SWSUSP_ACTIVITY_RESTARTING(0); return i; } diff -ruN linux-2.4.23-pre6/drivers/ide/ide-disk.c linux-2.4.23-pre6-swsusp/drivers/ide/ide-disk.c --- linux-2.4.23-pre6/drivers/ide/ide-disk.c 2003-06-13 23:51:33.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/ide/ide-disk.c 2003-10-05 03:42:25.000000000 +0900 @@ -60,6 +60,7 @@ #include #include #include +#include #define _IDE_DISK @@ -1866,64 +1867,93 @@ return ide_stopped; } -int ide_disks_busy(void) +int ide_disks_busy(int no_warning) { int i; - for (i=0; ihandler) && (hwgroup->handler != panic_box)) - return 1; - } + + for (i=0; ihandler) && (hwgroup->handler != panic_box)) { + if(!no_warning) /* busy ide disks is not an error */ + printk("ide_disks_busy: %6s: handler not null: %p\n", + ide_hwifs[i].name,hwgroup->handler); + return 1; + } + } return 0; } void ide_disk_suspend(void) { - int i; - while (ide_disks_busy()) { - printk("*"); + int i, drivenum = 0; + ide_drive_t *drive; + + if (driver_blocked) + return; + + i=1; + while (ide_disks_busy(i++)) { schedule(); + i &= (unsigned int)((1<<21)-1); /* CBD: we print a warning only after a great number of errors, no need to frighten the newbie ;-) */ } - for (i=0; ihandler_save = hwgroup->handler; - hwgroup->handler = panic_box; + + /* Ensure caches are purged too (derived from module unload) - Nigel Cunningham */ + while ((drive = ide_scan_devices(ide_disk, idedisk_driver.name, + &idedisk_driver, drivenum)) != NULL) { + if ((drive->id->command_set_1 & 0x20) && drive->id->cfs_enable_1 & 0x20) { + if (do_idedisk_flushcache(drive)) + printk(KERN_ERR "Failed!"); + } + drivenum++; } + driver_blocked = 1; - if (ide_disks_busy()) + + for (i=0; ihandler = panic_box; + hwgroup->busy = 1; + } +#if 1 + if (ide_disks_busy(0)) panic("How did you get that request through?!"); +#endif } -/* unsuspend and resume should be equal in the ideal world */ - -void ide_disk_unsuspend(void) +void ide_disk_unsuspend(int resume) { int i; - for (i=0; ihandler = NULL; /* hwgroup->handler_save; */ - hwgroup->handler_save = NULL; - } - driver_blocked = 0; -} -void ide_disk_resume(void) -{ - int i; - for (i=0; ihandler != panic_box) - panic("Handler was not set to panic?"); - hwgroup->handler_save = NULL; - hwgroup->handler = NULL; - } + for (i=0; ihandler != panic_box) + printk(KERN_ERR "ide_disk_unsuspend: %6s: Handler was not set to panic? %p", + ide_hwifs[i].name,hwgroup->handler); + hwgroup->handler = NULL; + hwgroup->busy = 0; +#if 0 /* CBD: not working on my configs. Necessary for others? */ + if(resume) { + printk("ide_disk_unsuspend: %6s: reinit drive %p", + ide_hwifs[i].name,hwgroup->drive); + ide_reinit_drive(hwgroup->drive); + } +#endif + } driver_blocked = 0; } diff -ruN linux-2.4.23-pre6/drivers/ide/ide-io.c linux-2.4.23-pre6-swsusp/drivers/ide/ide-io.c --- linux-2.4.23-pre6/drivers/ide/ide-io.c 2003-10-05 04:16:38.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/ide/ide-io.c 2003-10-05 03:45:22.000000000 +0900 @@ -735,6 +735,7 @@ /* --BenH: made non-static as ide-pmac.c uses it to kick the hwgroup back * into life on wakeup from machine sleep. */ + void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) { ide_drive_t *drive; diff -ruN linux-2.4.23-pre6/drivers/md/md.c linux-2.4.23-pre6-swsusp/drivers/md/md.c --- linux-2.4.23-pre6/drivers/md/md.c 2003-08-25 20:44:42.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/md/md.c 2003-10-05 03:42:25.000000000 +0900 @@ -3425,7 +3425,6 @@ struct md_list_head *tmp; unsigned long last_check; - err = down_interruptible(&mddev->resync_sem); if (err) goto out_nolock; @@ -3588,6 +3587,8 @@ mdp_disk_t *spare; struct md_list_head *tmp; + current->flags |= PF_SYNCTHREAD; + printk(KERN_INFO "md: recovery thread got woken up ...\n"); restart: ITERATE_MDDEV(mddev,tmp) { @@ -3797,6 +3798,15 @@ detected_devices[dev_cnt++] = dev; } +void md_autostart_arrays(void) +{ + struct md_list_head *tmp; + mddev_t *mddev; + + autostart_arrays(); + ITERATE_MDDEV(mddev, tmp) + restart_array(mddev); +} static void autostart_arrays(void) { @@ -4127,4 +4137,5 @@ MD_EXPORT_SYMBOL(mddev_map); MD_EXPORT_SYMBOL(md_check_ordering); MD_EXPORT_SYMBOL(get_spare); +MD_EXPORT_SYMBOL(md_autostart_arrays); MODULE_LICENSE("GPL"); diff -ruN linux-2.4.23-pre6/drivers/md/raid1.c linux-2.4.23-pre6-swsusp/drivers/md/raid1.c --- linux-2.4.23-pre6/drivers/md/raid1.c 2003-06-13 23:51:34.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/md/raid1.c 2003-10-05 03:42:25.000000000 +0900 @@ -1162,6 +1162,7 @@ if (mddev->sb_dirty) md_update_sb(mddev); + current->flags |= PF_SYNCTHREAD; for (;;) { md_spin_lock_irqsave(&retry_list_lock, flags); @@ -1286,6 +1287,8 @@ raid1_conf_t *conf = data; mddev_t *mddev = conf->mddev; + current->flags |= PF_SYNCTHREAD; + if (!conf->resync_mirrors) return; if (conf->resync_mirrors == 2) diff -ruN linux-2.4.23-pre6/drivers/md/raid5.c linux-2.4.23-pre6-swsusp/drivers/md/raid5.c --- linux-2.4.23-pre6/drivers/md/raid5.c 2003-08-25 20:44:42.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/md/raid5.c 2003-10-05 03:42:25.000000000 +0900 @@ -1299,6 +1299,8 @@ PRINTK("+++ raid5d active\n"); + current->flags |= PF_SYNCTHREAD; + handled = 0; if (mddev->sb_dirty) @@ -1348,6 +1350,8 @@ raid5_conf_t *conf = data; mddev_t *mddev = conf->mddev; + current->flags |= PF_SYNCTHREAD; + if (!conf->resync_parity) return; if (conf->resync_parity == 2) diff -ruN linux-2.4.23-pre6/drivers/net/8139too.c linux-2.4.23-pre6-swsusp/drivers/net/8139too.c --- linux-2.4.23-pre6/drivers/net/8139too.c 2003-10-05 04:16:38.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/net/8139too.c 2003-10-05 03:45:22.000000000 +0900 @@ -110,6 +110,7 @@ #include #include #include +#include #include #include @@ -1593,6 +1594,8 @@ while (1) { timeout = next_tick; do { + if (current->flags & PF_FREEZE) + refrigerator(PF_SYNCTHREAD); timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout); } while (!signal_pending (current) && (timeout > 0)); @@ -2479,6 +2482,9 @@ pci_set_power_state (pdev, 3); pci_save_state (pdev, tp->pci_state); + pci_set_power_state (pdev, 3); + pci_save_state (pdev, tp->pci_state); + spin_unlock_irqrestore (&tp->lock, flags); return 0; } diff -ruN linux-2.4.23-pre6/drivers/net/eepro100.c linux-2.4.23-pre6-swsusp/drivers/net/eepro100.c --- linux-2.4.23-pre6/drivers/net/eepro100.c 2003-08-25 20:44:42.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/net/eepro100.c 2003-10-05 03:42:25.000000000 +0900 @@ -529,6 +529,8 @@ static int eepro100_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static void eepro100_remove_one (struct pci_dev *pdev); +static int eepro100_suspend (struct pci_dev *pdev, u32 state); +static int eepro100_resume (struct pci_dev *pdev); static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len); static int mdio_read(struct net_device *dev, int phy_id, int location); diff -ruN linux-2.4.23-pre6/drivers/net/via-rhine.c linux-2.4.23-pre6-swsusp/drivers/net/via-rhine.c --- linux-2.4.23-pre6/drivers/net/via-rhine.c 2003-10-05 04:16:38.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/net/via-rhine.c 2003-10-05 03:45:23.000000000 +0900 @@ -1891,12 +1891,40 @@ pci_set_drvdata(pdev, NULL); } +#ifdef CONFIG_PM +static int via_rhine_suspend(struct pci_dev *pdev, u32 state) +{ + printk("Suspending via_rhine...\n"); +#if 0 + via_rhine_remove_one(pdev); +#endif + return 0; +} + +static int via_rhine_resume(struct pci_dev *pdev) +{ + long ioaddr; + + printk("Resuming via_rhine...\n"); +#if 1 + ioaddr = pci_resource_start (pdev, 0); + /* Reset the chip. */ + writew(CmdReset, ioaddr + ChipCmd); +#endif + return 0; +} +#endif + static struct pci_driver via_rhine_driver = { .name = "via-rhine", .id_table = via_rhine_pci_tbl, .probe = via_rhine_init_one, .remove = __devexit_p(via_rhine_remove_one), +#ifdef CONFIG_PM + .suspend = via_rhine_suspend, + .resume = via_rhine_resume +#endif }; diff -ruN linux-2.4.23-pre6/drivers/usb/host/usb-ohci.c linux-2.4.23-pre6-swsusp/drivers/usb/host/usb-ohci.c --- linux-2.4.23-pre6/drivers/usb/host/usb-ohci.c 2003-08-25 20:44:42.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/usb/host/usb-ohci.c 2003-10-05 03:42:25.000000000 +0900 @@ -65,9 +65,13 @@ #include #include #include +#include #include /* for in_interrupt() */ #undef DEBUG #include +#ifdef CONFIG_SOFTWARE_SUSPEND +#include +#endif #include #include @@ -107,6 +111,9 @@ static LIST_HEAD (ohci_hcd_list); static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED; +#ifdef CONFIG_SOFTWARE_SUSPEND +static ohci_t *ohci_save = NULL; +#endif /* CONFIG_SOFTWARE_SUSPEND */ /*-------------------------------------------------------------------------*/ @@ -2580,6 +2587,14 @@ int temp; int i; +#ifdef CONFIG_SOFTWARE_SUSPEND + /* dont do anything till we're out of a software suspend */ + if (suspend_task) { + ohci_save = ohci; + return; + } +#endif /* CONFIG_SOFTWARE_SUSPEND */ + if (ohci->pci_latency) pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency); @@ -2938,23 +2953,49 @@ }; +#ifdef CONFIG_SOFTWARE_SUSPEND +static struct notifier_block ohci_resume_notifier; +#endif /* CONFIG_SOFTWARE_SUSPEND */ + /*-------------------------------------------------------------------------*/ static int __init ohci_hcd_init (void) { - return pci_module_init (&ohci_pci_driver); + int retval = pci_module_init (&ohci_pci_driver); +#ifdef CONFIG_SOFTWARE_SUSPEND + if (!retval) + register_resume_notifier(&ohci_resume_notifier); +#endif /* CONFIG_SOFTWARE_SUSPEND */ + return retval; } /*-------------------------------------------------------------------------*/ static void __exit ohci_hcd_cleanup (void) { +#ifdef CONFIG_SOFTWARE_SUSPEND + unregister_resume_notifier(&ohci_resume_notifier); +#endif /* CONFIG_SOFTWARE_SUSPEND */ pci_unregister_driver (&ohci_pci_driver); } module_init (ohci_hcd_init); module_exit (ohci_hcd_cleanup); +#ifdef CONFIG_SOFTWARE_SUSPEND +static int ohci_swsusp_resume(struct notifier_block *self, unsigned long v, void *vp) +{ + if (ohci_save) { + hc_restart(ohci_save); + ohci_save = NULL; + } + return 0; +} + +static struct notifier_block ohci_resume_notifier = { + .notifier_call = ohci_swsusp_resume, +}; +#endif /* CONFIG_SOFTWARE_SUSPEND */ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); diff -ruN linux-2.4.23-pre6/drivers/usb/hub.c linux-2.4.23-pre6-swsusp/drivers/usb/hub.c --- linux-2.4.23-pre6/drivers/usb/hub.c 2003-08-25 20:44:42.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/usb/hub.c 2003-10-05 03:42:25.000000000 +0900 @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef CONFIG_USB_DEBUG #define DEBUG #else @@ -919,6 +920,8 @@ do { usb_hub_events(); wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); + if (current->flags & PF_FREEZE) + refrigerator(PF_SYNCTHREAD); } while (!signal_pending(current)); dbg("usb_hub_thread exiting"); diff -ruN linux-2.4.23-pre6/drivers/usb/storage/usb.c linux-2.4.23-pre6-swsusp/drivers/usb/storage/usb.c --- linux-2.4.23-pre6/drivers/usb/storage/usb.c 2003-08-25 20:44:42.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/drivers/usb/storage/usb.c 2003-10-05 03:42:25.000000000 +0900 @@ -319,6 +319,7 @@ */ exit_files(current); current->files = init_task.files; + current->flags |= PF_SYNCTHREAD; atomic_inc(¤t->files->count); daemonize(); reparent_to_init(); diff -ruN linux-2.4.23-pre6/fs/buffer.c linux-2.4.23-pre6-swsusp/fs/buffer.c --- linux-2.4.23-pre6/fs/buffer.c 2003-10-05 04:16:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/buffer.c 2003-10-05 03:45:24.000000000 +0900 @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include #include @@ -80,7 +82,7 @@ static unsigned long size_buffers_type[NR_LIST]; static struct buffer_head * unused_list; -static int nr_unused_buffer_heads; +int nr_unused_buffer_heads; static spinlock_t unused_list_lock = SPIN_LOCK_UNLOCKED; static DECLARE_WAIT_QUEUE_HEAD(buffer_wait); @@ -208,7 +210,7 @@ * return without it! */ #define NRSYNC (32) -static int write_some_buffers(kdev_t dev) +int write_some_buffers(kdev_t dev) { struct buffer_head *next; struct buffer_head *array[NRSYNC]; @@ -222,6 +224,8 @@ struct buffer_head * bh = next; next = bh->b_next_free; + if (current->flags & PF_FREEZE) + return 0; if (dev != NODEV && bh->b_dev != dev) continue; if (test_and_set_bit(BH_Lock, &bh->b_state)) @@ -247,14 +251,11 @@ return 0; } -/* - * Write out all buffers on the dirty list. - */ static void write_unlocked_buffers(kdev_t dev) { do spin_lock(&lru_list_lock); - while (write_some_buffers(dev)); + while ((!(current->flags & PF_FREEZE)) && write_some_buffers(dev)); } /* @@ -274,6 +275,9 @@ struct buffer_head *bh = next; next = bh->b_next_free; + if (current->flags & PF_FREEZE) + return 0; + if (!buffer_locked(bh)) { if (refile) __refile_buffer(bh); @@ -284,7 +288,7 @@ get_bh(bh); spin_unlock(&lru_list_lock); - wait_on_buffer (bh); + wait_on_buffer(bh); put_bh(bh); return -EAGAIN; } @@ -296,7 +300,7 @@ { do { spin_lock(&lru_list_lock); - } while (wait_for_buffers(dev, index, refile)); + } while ((!(current->flags & PF_FREEZE)) && wait_for_buffers(dev, index, refile)); return 0; } @@ -310,6 +314,11 @@ * We will ultimately want to put these in a separate list, but for * now we search all of the lists for dirty buffers. */ + +/* If the current process (esp kupdated) is being put in the fridge, we + * drop out of this early. (This means we can suspend without waiting + * for fsync to finish!) + */ int sync_buffers(kdev_t dev, int wait) { int err = 0; @@ -376,9 +385,18 @@ fsync_dev(dev); } +/* + * When trying to freeze processes (for Software Suspend), + * we want to put new attempts at syncing on hold until + * resume time, and wait for current attempts to finish. + */ asmlinkage long sys_sync(void) { + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); fsync_dev(0); + SWSUSP_ACTIVITY_END; return 0; } @@ -417,6 +435,9 @@ struct dentry * dentry; struct inode * inode; int ret, err; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); ret = -EBADF; file = fget(fd); @@ -446,6 +467,7 @@ out_putf: fput(file); out: + SWSUSP_ACTIVITY_END; return ret; } @@ -476,6 +498,9 @@ struct file * file; struct inode *inode; int ret; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); ret = -EBADF; file = fget(fd); @@ -489,6 +514,7 @@ fput(file); out: + SWSUSP_ACTIVITY_END; return ret; } @@ -746,7 +772,8 @@ { balance_dirty(); wakeup_bdflush(); - try_to_free_pages(GFP_NOIO); + if (likely(suspend_task != current->pid)) + try_to_free_pages(GFP_NOIO); run_task_queue(&tq_disk); yield(); } @@ -758,7 +785,7 @@ bh->b_private = private; } -static void end_buffer_io_async(struct buffer_head * bh, int uptodate) +void end_buffer_io_async(struct buffer_head * bh, int uptodate) { static spinlock_t page_uptodate_lock = SPIN_LOCK_UNLOCKED; unsigned long flags; @@ -1047,6 +1074,7 @@ write_some_buffers(NODEV); } } + EXPORT_SYMBOL(balance_dirty); inline void __mark_dirty(struct buffer_head *bh) @@ -1081,7 +1109,7 @@ * A buffer may need to be moved from one buffer list to another * (e.g. in case it is not shared any more). Handle this. */ -static void __refile_buffer(struct buffer_head *bh) +void __refile_buffer(struct buffer_head *bh) { int dispose = BUF_CLEAN; if (buffer_locked(bh)) @@ -1157,7 +1185,7 @@ { if (unlikely(buffer_attached(bh))) BUG(); - if (nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS) { + if ((nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS)) { kmem_cache_free(bh_cachep, bh); } else { bh->b_dev = B_FREE; @@ -1182,6 +1210,13 @@ * Reserve NR_RESERVED buffer heads for async IO requests to avoid * no-buffer-head deadlock. Return NULL on failure; waiting for * buffer heads is now handled in create_buffers(). + * + * If, however, we are trying to start a suspend, any allocation can + * be asynchronous - it might not return until after resume. This is + * because we want to be able to ensure we don't have dirty buffers + * getting over-written by the normal suspend process and then written + * to disk. We thus block buffer allocations, write the dirty data and + * then unblock allocations after freezing processes. */ struct buffer_head * get_unused_buffer_head(int async) { @@ -1248,7 +1283,11 @@ * The async flag is used to differentiate async IO (paging, swapping) * from ordinary buffer allocations, and only async requests are allowed * to sleep waiting for buffer heads. + * + * If however swsusp is starting, all requests are async so that we can + * ensure data integrity - some might not return until after resume. */ + static struct buffer_head * create_buffers(struct page * page, unsigned long size, int async) { struct buffer_head *bh, *head; @@ -1304,15 +1343,20 @@ if (!async) return NULL; - /* We're _really_ low on memory. Now we just - * wait for old buffer heads to become free due to - * finishing IO. Since this is an async request and - * the reserve list is empty, we're sure there are - * async buffer heads in use. + /* We're _really_ low on memory or in swsusp and not + * wanting to make our image inconsistent by allocating + * extra pages. Now we just wait for old buffer heads + * to become free due to finishing IO. Since this is + * an async request and the reserve list is empty, + * we're sure there are async buffer heads in use. */ run_task_queue(&tq_disk); free_more_memory(); +#ifdef CONFIG_SOFTWARE_SUSPEND + if (suspend_task == current->pid) + cleanup_finished_swsusp_io(); +#endif goto try_again; } @@ -1414,6 +1458,11 @@ /* FIXME: create_buffers should fail if there's no enough memory */ head = create_buffers(page, blocksize, 1); + + /* Head only NULL if swsusp is running - shouldn't happen on this path */ + if (!head) + BUG(); + if (page->buffers) BUG(); @@ -2403,7 +2452,8 @@ panic("brw_page: page not locked for I/O"); if (!page->buffers) - create_empty_buffers(page, dev, size); + create_empty_buffers(page, dev, size); + head = bh = page->buffers; /* Stage 1: lock all the buffers */ @@ -2498,7 +2548,12 @@ goto failed; } - bh = create_buffers(page, size, 0); +#ifdef CONFIG_SOFTWARE_SUSPEND + if (suspend_task == current->pid) + bh = create_buffers(page, size, 1); + else +#endif + bh = create_buffers(page, size, 0); if (!bh) goto failed; link_dev_buffers(page, bh); @@ -2866,9 +2921,11 @@ * otherwise there would be no way of ensuring that these quantities ever * get written back. Ideally, we would have a timestamp on the inodes * and superblocks so that we could write back only the old ones as well + * + * Not static so it can be used during swsusp process freezing. */ -static int sync_old_buffers(void) +int sync_old_buffers(void) { lock_kernel(); sync_unlocked_inodes(); @@ -2882,6 +2939,8 @@ bh = lru_list[BUF_DIRTY]; if (!bh || time_before(jiffies, bh->b_flushtime)) break; + if (current->flags & PF_FREEZE) + break; if (write_some_buffers(NODEV)) continue; return 0; @@ -2967,6 +3026,7 @@ tsk->session = 1; tsk->pgrp = 1; strcpy(tsk->comm, "bdflush"); + current->flags |= PF_SYNCTHREAD; /* avoid getting signals */ spin_lock_irq(&tsk->sigmask_lock); @@ -2989,6 +3049,9 @@ */ for (;;) { int ndirty = bdf_prm.b_un.ndirty; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); CHECK_EMERGENCY_SYNC @@ -2998,6 +3061,10 @@ break; ndirty -= NRSYNC; } + SWSUSP_ACTIVITY_END; + + if (unlikely(current->flags & PF_FREEZE)) + refrigerator(PF_SYNCTHREAD); if (ndirty > 0 || bdflush_stop()) interruptible_sleep_on(&bdflush_wait); } @@ -3017,6 +3084,7 @@ tsk->session = 1; tsk->pgrp = 1; strcpy(tsk->comm, "kupdated"); + current->flags |= PF_SYNCTHREAD; /* sigstop and sigcont will stop and wakeup kupdate */ spin_lock_irq(&tsk->sigmask_lock); @@ -3028,8 +3096,12 @@ complete((struct completion *)startup); for (;;) { + DECLARE_SWSUSP_LOCAL_VAR; + /* update interval */ interval = bdf_prm.b_un.interval; + if (unlikely(current->flags & PF_FREEZE)) + refrigerator(PF_SYNCTHREAD); if (interval) { tsk->state = TASK_INTERRUPTIBLE; schedule_timeout(interval); @@ -3054,8 +3126,10 @@ #ifdef DEBUG printk(KERN_DEBUG "kupdate() activated...\n"); #endif + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); sync_old_buffers(); run_task_queue(&tq_disk); + SWSUSP_ACTIVITY_END; } } diff -ruN linux-2.4.23-pre6/fs/dcache.c linux-2.4.23-pre6-swsusp/fs/dcache.c --- linux-2.4.23-pre6/fs/dcache.c 2003-06-13 23:51:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/dcache.c 2003-10-05 03:42:25.000000000 +0900 @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -1022,10 +1023,13 @@ struct vfsmount *pwdmnt, *rootmnt; struct dentry *pwd, *root; char *page = (char *) __get_free_page(GFP_USER); + DECLARE_SWSUSP_LOCAL_VAR; if (!page) return -ENOMEM; + SWSUSP_ACTIVITY_START(0); + read_lock(¤t->fs->lock); pwdmnt = mntget(current->fs->pwdmnt); pwd = dget(current->fs->pwd); @@ -1063,6 +1067,9 @@ dput(root); mntput(rootmnt); free_page((unsigned long) page); + + SWSUSP_ACTIVITY_END; + return error; } diff -ruN linux-2.4.23-pre6/fs/devfs/base.c linux-2.4.23-pre6-swsusp/fs/devfs/base.c --- linux-2.4.23-pre6/fs/devfs/base.c 2002-11-29 08:53:15.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/devfs/base.c 2003-10-05 03:42:25.000000000 +0900 @@ -652,6 +652,7 @@ #include #include #include +#include #include #include @@ -3318,6 +3319,7 @@ struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->u.generic_sbp; struct devfsd_notify_struct *info = fs_info->devfsd_info; DECLARE_WAITQUEUE (wait, current); + DECLARE_SWSUSP_LOCAL_VAR; /* Can't seek (pread) on this device */ if (ppos != &file->f_pos) return -ESPIPE; @@ -3326,6 +3328,7 @@ info->major = 0; info->minor = 0; /* Block for a new entry */ + SWSUSP_ACTIVITY_PAUSING; set_current_state (TASK_INTERRUPTIBLE); add_wait_queue (&fs_info->devfsd_wait_queue, &wait); while ( devfsd_queue_empty (fs_info) ) @@ -3338,12 +3341,14 @@ { remove_wait_queue (&fs_info->devfsd_wait_queue, &wait); __set_current_state (TASK_RUNNING); + SWSUSP_ACTIVITY_RESTARTING(0); return -EINTR; } set_current_state (TASK_INTERRUPTIBLE); } remove_wait_queue (&fs_info->devfsd_wait_queue, &wait); __set_current_state (TASK_RUNNING); + SWSUSP_ACTIVITY_RESTARTING(0); /* Now play with the data */ ival = atomic_read (&fs_info->devfsd_overrun_count); info->overrun_count = ival; diff -ruN linux-2.4.23-pre6/fs/exec.c linux-2.4.23-pre6-swsusp/fs/exec.c --- linux-2.4.23-pre6/fs/exec.c 2003-10-05 04:16:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/exec.c 2003-10-05 03:54:46.000000000 +0900 @@ -39,6 +39,7 @@ #include #define __NO_VERSION__ #include +#include #include #include @@ -112,6 +113,9 @@ struct file * file; struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); error = user_path_walk(library, &nd); if (error) @@ -151,6 +155,7 @@ } fput(file); out: + SWSUSP_ACTIVITY_END; return error; exit: path_release(&nd); @@ -908,12 +913,17 @@ struct file *file; int retval; int i; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); file = open_exec(filename); retval = PTR_ERR(file); - if (IS_ERR(file)) + if (IS_ERR(file)) { + SWSUSP_ACTIVITY_END; return retval; + } bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); @@ -926,12 +936,14 @@ if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) { allow_write_access(file); fput(file); + SWSUSP_ACTIVITY_END; return bprm.argc; } if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) { allow_write_access(file); fput(file); + SWSUSP_ACTIVITY_END; return bprm.envc; } @@ -953,9 +965,11 @@ goto out; retval = search_binary_handler(&bprm,regs); - if (retval >= 0) + if (retval >= 0) { /* execve success */ + SWSUSP_ACTIVITY_END; return retval; + } out: /* Something went wrong, return the inode and free the argument pages*/ @@ -969,6 +983,7 @@ __free_page(page); } + SWSUSP_ACTIVITY_END; return retval; } @@ -1106,6 +1121,9 @@ struct inode * inode; int retval = 0; int fsuid = current->fsuid; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); lock_kernel(); binfmt = current->binfmt; @@ -1148,5 +1166,7 @@ if (fsuid != current->fsuid) current->fsuid = fsuid; unlock_kernel(); + SWSUSP_ACTIVITY_END; + return retval; } diff -ruN linux-2.4.23-pre6/fs/fcntl.c linux-2.4.23-pre6-swsusp/fs/fcntl.c --- linux-2.4.23-pre6/fs/fcntl.c 2002-11-29 08:53:15.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/fcntl.c 2003-10-05 03:42:25.000000000 +0900 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -140,6 +141,9 @@ int err = -EBADF; struct file * file, *tofree; struct files_struct * files = current->files; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); write_lock(&files->file_lock); if (!(file = fcheck(oldfd))) @@ -178,6 +182,7 @@ filp_close(tofree, files); err = newfd; out: + SWSUSP_ACTIVITY_END; return err; out_unlock: write_unlock(&files->file_lock); @@ -193,9 +198,12 @@ { int ret = -EBADF; struct file * file = fget(fildes); + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); if (file) ret = dupfd(file, 0); + SWSUSP_ACTIVITY_END; return ret; } @@ -339,7 +347,9 @@ { struct file * filp; long err = -EBADF; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); filp = fget(fd); if (!filp) goto out; @@ -348,6 +358,7 @@ fput(filp); out: + SWSUSP_ACTIVITY_END; return err; } @@ -356,7 +367,9 @@ { struct file * filp; long err; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); err = -EBADF; filp = fget(fd); if (!filp) @@ -378,6 +391,7 @@ } fput(filp); out: + SWSUSP_ACTIVITY_END; return err; } #endif diff -ruN linux-2.4.23-pre6/fs/inode.c linux-2.4.23-pre6-swsusp/fs/inode.c --- linux-2.4.23-pre6/fs/inode.c 2003-10-05 04:16:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/inode.c 2003-10-05 03:45:24.000000000 +0900 @@ -356,7 +356,7 @@ void sync_inodes_sb(struct super_block *sb) { spin_lock(&inode_lock); - while (!list_empty(&sb->s_dirty)||!list_empty(&sb->s_locked_inodes)) { + while ((!list_empty(&sb->s_dirty)||!list_empty(&sb->s_locked_inodes)) && (!(current->flags & PF_FREEZE))) { sync_list(&sb->s_dirty); wait_on_locked(&sb->s_locked_inodes); } diff -ruN linux-2.4.23-pre6/fs/jbd/commit.c linux-2.4.23-pre6-swsusp/fs/jbd/commit.c --- linux-2.4.23-pre6/fs/jbd/commit.c 2003-06-13 23:51:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/jbd/commit.c 2003-10-05 03:42:25.000000000 +0900 @@ -20,6 +20,7 @@ #include #include #include +#include extern spinlock_t journal_datalist_lock; diff -ruN linux-2.4.23-pre6/fs/jbd/journal.c linux-2.4.23-pre6-swsusp/fs/jbd/journal.c --- linux-2.4.23-pre6/fs/jbd/journal.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/jbd/journal.c 2003-10-05 03:42:25.000000000 +0900 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -199,6 +200,7 @@ journal_t *journal = (journal_t *) arg; transaction_t *transaction; struct timer_list timer; + DECLARE_SWSUSP_LOCAL_VAR; current_journal = journal; @@ -211,6 +213,10 @@ spin_unlock_irq(¤t->sigmask_lock); sprintf(current->comm, "kjournald"); + current->flags |= PF_SYNCTHREAD; + + SWSUSP_THREAD_FLAGS_RESET; + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); /* Set up an interval timer which can be used to trigger a commit wakeup after the commit interval expires */ @@ -247,7 +253,9 @@ } wake_up(&journal->j_wait_done_commit); + SWSUSP_ACTIVITY_PAUSING; interruptible_sleep_on(&journal->j_wait_commit); + SWSUSP_ACTIVITY_RESTARTING(PF_SYNCTHREAD); jbd_debug(1, "kjournald wakes\n"); @@ -264,6 +272,7 @@ del_timer_sync(journal->j_commit_timer); } + SWSUSP_ACTIVITY_END; list_del(&journal->j_all_journals); journal->j_task = NULL; diff -ruN linux-2.4.23-pre6/fs/jffs/intrep.c linux-2.4.23-pre6-swsusp/fs/jffs/intrep.c --- linux-2.4.23-pre6/fs/jffs/intrep.c 2003-06-13 23:51:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/jffs/intrep.c 2003-10-05 03:42:25.000000000 +0900 @@ -3341,6 +3341,7 @@ long erased; int result = 0; D1(int i = 1); + DECLARE_SWSUSP_LOCAL_VAR; c->gc_task = current; @@ -3355,6 +3356,9 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); strcpy(current->comm, "jffs_gcd"); + current->flags |= PF_SYNCTHREAD; + + SWSUSP_THREAD_FLAGS_RESET; D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): Starting infinite loop.\n")); @@ -3399,6 +3403,7 @@ } } + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): collecting.\n")); @@ -3435,5 +3440,6 @@ gc_end: D3(printk (KERN_NOTICE "g_c_thread(): up biglock\n")); up(&fmc->biglock); + SWSUSP_ACTIVITY_END; } /* for (;;) */ } /* jffs_garbage_collect_thread() */ diff -ruN linux-2.4.23-pre6/fs/jfs/jfs_logmgr.c linux-2.4.23-pre6-swsusp/fs/jfs/jfs_logmgr.c --- linux-2.4.23-pre6/fs/jfs/jfs_logmgr.c 2003-10-05 04:16:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/jfs/jfs_logmgr.c 2003-10-05 03:45:24.000000000 +0900 @@ -65,6 +65,7 @@ #include #include #include +#include #include "jfs_incore.h" #include "jfs_filsys.h" #include "jfs_metapage.h" @@ -2175,12 +2176,16 @@ int jfsIOWait(void *arg) { struct lbuf *bp; + DECLARE_SWSUSP_LOCAL_VAR; lock_kernel(); daemonize(); current->tty = NULL; strcpy(current->comm, "jfsIO"); + current->flags |= PF_SYNCTHREAD; + SWSUSP_THREAD_FLAGS_RESET; + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); unlock_kernel(); @@ -2205,13 +2210,16 @@ add_wait_queue(&jfs_IO_thread_wait, &wq); set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irq(&log_redrive_lock); + SWSUSP_ACTIVITY_PAUSING; schedule(); + SWSUSP_ACTIVITY_RESTARTING(PF_SYNCTHREAD); current->state = TASK_RUNNING; remove_wait_queue(&jfs_IO_thread_wait, &wq); } while (!jfs_stop_threads); jfs_info("jfsIOWait being killed!"); complete(&jfsIOwait); + SWSUSP_ACTIVITY_END; return 0; } diff -ruN linux-2.4.23-pre6/fs/jfs/jfs_txnmgr.c linux-2.4.23-pre6-swsusp/fs/jfs/jfs_txnmgr.c --- linux-2.4.23-pre6/fs/jfs/jfs_txnmgr.c 2003-10-05 04:16:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/jfs/jfs_txnmgr.c 2003-10-05 03:45:24.000000000 +0900 @@ -47,6 +47,7 @@ #include #include #include +#include #include "jfs_incore.h" #include "jfs_filsys.h" #include "jfs_metapage.h" @@ -2759,12 +2760,17 @@ int WorkDone; struct tblock *tblk; unsigned long flags; + DECLARE_SWSUSP_LOCAL_VAR; lock_kernel(); daemonize(); current->tty = NULL; strcpy(current->comm, "jfsCommit"); + current->flags |= PF_SYNCTHREAD; + + SWSUSP_THREAD_FLAGS_RESET; + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); unlock_kernel(); @@ -2810,7 +2816,9 @@ * We can be running indefinately if other processors * are adding transactions to this list */ + SWSUSP_ACTIVITY_PAUSING; cond_resched(); + SWSUSP_ACTIVITY_RESTARTING(PF_SYNCTHREAD); LAZY_LOCK(flags); } @@ -2820,11 +2828,14 @@ add_wait_queue(&jfs_commit_thread_wait, &wq); set_current_state(TASK_INTERRUPTIBLE); LAZY_UNLOCK(flags); + SWSUSP_ACTIVITY_PAUSING; schedule(); + SWSUSP_ACTIVITY_RESTARTING(PF_SYNCTHREAD); current->state = TASK_RUNNING; remove_wait_queue(&jfs_commit_thread_wait, &wq); } while (!jfs_stop_threads); + SWSUSP_ACTIVITY_END; if (TxAnchor.unlock_queue) jfs_err("jfs_lazycommit being killed w/pending transactions!"); else @@ -2961,12 +2972,16 @@ struct jfs_inode_info *jfs_ip; int rc; tid_t tid; + DECLARE_SWSUSP_LOCAL_VAR; lock_kernel(); daemonize(); current->tty = NULL; strcpy(current->comm, "jfsSync"); + current->flags |= PF_SYNCTHREAD; + SWSUSP_THREAD_FLAGS_RESET; + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); unlock_kernel(); @@ -3032,11 +3047,14 @@ add_wait_queue(&jfs_sync_thread_wait, &wq); set_current_state(TASK_INTERRUPTIBLE); TXN_UNLOCK(); + SWSUSP_ACTIVITY_PAUSING; schedule(); + SWSUSP_ACTIVITY_RESTARTING(PF_SYNCTHREAD); current->state = TASK_RUNNING; remove_wait_queue(&jfs_sync_thread_wait, &wq); } while (!jfs_stop_threads); + SWSUSP_ACTIVITY_END; jfs_info("jfs_sync being killed"); complete(&jfsIOwait); return 0; diff -ruN linux-2.4.23-pre6/fs/lockd/clntlock.c linux-2.4.23-pre6-swsusp/fs/lockd/clntlock.c --- linux-2.4.23-pre6/fs/lockd/clntlock.c 2001-10-02 05:45:47.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/lockd/clntlock.c 2003-10-05 03:42:25.000000000 +0900 @@ -17,6 +17,7 @@ #include #include #include +#include #define NLMDBG_FACILITY NLMDBG_CLIENT @@ -200,6 +201,7 @@ struct list_head *tmp; struct file_lock *fl; struct inode *inode; + DECLARE_SWSUSP_LOCAL_VAR; daemonize(); reparent_to_init(); @@ -207,6 +209,11 @@ "%s-reclaim", host->h_name); + current->flags |= PF_SYNCTHREAD; + + SWSUSP_THREAD_FLAGS_RESET; + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); + /* This one ensures that our parent doesn't terminate while the * reclaim is in progress */ lock_kernel(); @@ -248,6 +255,7 @@ lockd_down(); unlock_kernel(); MOD_DEC_USE_COUNT; + SWSUSP_ACTIVITY_END; return 0; } diff -ruN linux-2.4.23-pre6/fs/lockd/clntproc.c linux-2.4.23-pre6-swsusp/fs/lockd/clntproc.c --- linux-2.4.23-pre6/fs/lockd/clntproc.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/lockd/clntproc.c 2003-10-05 03:42:38.000000000 +0900 @@ -17,6 +17,7 @@ #include #include #include +#include #define NLMDBG_FACILITY NLMDBG_CLIENT #define NLMCLNT_GRACE_WAIT (5*HZ) @@ -243,6 +244,7 @@ struct file *filp = argp->lock.fl.fl_file; struct rpc_message msg; int status; + DECLARE_SWSUSP_LOCAL_VAR; dprintk("lockd: call procedure %s on %s\n", nlm_procname(proc), host->h_name); @@ -257,7 +259,9 @@ do { if (host->h_reclaiming && !argp->reclaim) { + SWSUSP_ACTIVITY_PAUSING; interruptible_sleep_on(&host->h_gracewait); + SWSUSP_ACTIVITY_RESTARTING(PF_SYNCTHREAD); continue; } @@ -298,7 +302,9 @@ } /* Back off a little and try again */ + SWSUSP_ACTIVITY_PAUSING; interruptible_sleep_on_timeout(&host->h_gracewait, 15*HZ); + SWSUSP_ACTIVITY_RESTARTING(PF_SYNCTHREAD); /* When the lock requested by F_SETLKW isn't available, we will wait until the request can be satisfied. If diff -ruN linux-2.4.23-pre6/fs/lockd/svc.c linux-2.4.23-pre6-swsusp/fs/lockd/svc.c --- linux-2.4.23-pre6/fs/lockd/svc.c 2003-06-13 23:51:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/lockd/svc.c 2003-10-05 03:42:25.000000000 +0900 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -81,6 +82,7 @@ struct svc_serv *serv = rqstp->rq_server; int err = 0; unsigned long grace_period_expire; + DECLARE_SWSUSP_LOCAL_VAR; /* Lock module and set up kernel thread */ MOD_INC_USE_COUNT; @@ -95,6 +97,10 @@ daemonize(); reparent_to_init(); sprintf(current->comm, "lockd"); + current->flags |= PF_SYNCTHREAD; + + SWSUSP_THREAD_FLAGS_RESET; + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); /* Process request with signals blocked. */ spin_lock_irq(¤t->sigmask_lock); @@ -121,7 +127,11 @@ while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { long timeout = MAX_SCHEDULE_TIMEOUT; - if (signalled()) { + if (current->flags & PF_FREEZE) { + dprintk("Now suspending lockd\n"); + refrigerator(PF_SYNCTHREAD); + dprintk("Now resuming lockd\n"); + } else if (signalled()) { spin_lock_irq(¤t->sigmask_lock); flush_signals(current); spin_unlock_irq(¤t->sigmask_lock); diff -ruN linux-2.4.23-pre6/fs/locks.c linux-2.4.23-pre6-swsusp/fs/locks.c --- linux-2.4.23-pre6/fs/locks.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/locks.c 2003-10-05 03:42:25.000000000 +0900 @@ -122,6 +122,7 @@ #include #include #include +#include #include #include @@ -1382,6 +1383,9 @@ { struct file *filp; int error, type; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); error = -EBADF; filp = fget(fd); @@ -1409,6 +1413,7 @@ out_putf: fput(filp); out: + SWSUSP_ACTIVITY_END; return error; } diff -ruN linux-2.4.23-pre6/fs/namei.c linux-2.4.23-pre6-swsusp/fs/namei.c --- linux-2.4.23-pre6/fs/namei.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/namei.c 2003-10-05 03:42:25.000000000 +0900 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -1267,12 +1268,18 @@ char * tmp; struct dentry * dentry; struct nameidata nd; + DECLARE_SWSUSP_LOCAL_VAR; if (S_ISDIR(mode)) return -EPERM; + + SWSUSP_ACTIVITY_START(0); + tmp = getname(filename); - if (IS_ERR(tmp)) + if (IS_ERR(tmp)) { + SWSUSP_ACTIVITY_END; return PTR_ERR(tmp); + } error = path_lookup(tmp, LOOKUP_PARENT, &nd); if (error) @@ -1302,6 +1309,7 @@ out: putname(tmp); + SWSUSP_ACTIVITY_END; return error; } @@ -1335,7 +1343,9 @@ { int error = 0; char * tmp; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); tmp = getname(pathname); error = PTR_ERR(tmp); if (!IS_ERR(tmp)) { @@ -1358,6 +1368,7 @@ putname(tmp); } + SWSUSP_ACTIVITY_END; return error; } @@ -1433,10 +1444,14 @@ char * name; struct dentry *dentry; struct nameidata nd; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); name = getname(pathname); - if(IS_ERR(name)) + if(IS_ERR(name)) { + SWSUSP_ACTIVITY_END; return PTR_ERR(name); + } error = path_lookup(name, LOOKUP_PARENT, &nd); if (error) @@ -1465,6 +1480,7 @@ path_release(&nd); exit: putname(name); + SWSUSP_ACTIVITY_END; return error; } @@ -1501,10 +1517,14 @@ char * name; struct dentry *dentry; struct nameidata nd; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); name = getname(pathname); - if(IS_ERR(name)) + if(IS_ERR(name)) { + SWSUSP_ACTIVITY_END; return PTR_ERR(name); + } error = path_lookup(name, LOOKUP_PARENT, &nd); if (error) @@ -1529,6 +1549,7 @@ exit: putname(name); + SWSUSP_ACTIVITY_END; return error; slashes: @@ -1567,10 +1588,14 @@ int error = 0; char * from; char * to; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); from = getname(oldname); - if(IS_ERR(from)) + if(IS_ERR(from)) { + SWSUSP_ACTIVITY_END; return PTR_ERR(from); + } to = getname(newname); error = PTR_ERR(to); if (!IS_ERR(to)) { @@ -1592,6 +1617,7 @@ putname(to); } putname(from); + SWSUSP_ACTIVITY_END; return error; } @@ -1648,7 +1674,9 @@ { int error; char * to; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); to = getname(newname); error = PTR_ERR(to); if (!IS_ERR(to)) { @@ -1678,6 +1706,7 @@ exit: putname(to); } + SWSUSP_ACTIVITY_END; return error; } @@ -1921,10 +1950,14 @@ int error; char * from; char * to; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); from = getname(oldname); - if(IS_ERR(from)) + if(IS_ERR(from)) { + SWSUSP_ACTIVITY_END; return PTR_ERR(from); + } to = getname(newname); error = PTR_ERR(to); if (!IS_ERR(to)) { @@ -1932,6 +1965,7 @@ putname(to); } putname(from); + SWSUSP_ACTIVITY_END; return error; } diff -ruN linux-2.4.23-pre6/fs/namespace.c linux-2.4.23-pre6-swsusp/fs/namespace.c --- linux-2.4.23-pre6/fs/namespace.c 2003-10-05 04:16:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/namespace.c 2003-10-05 03:45:24.000000000 +0900 @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -365,7 +366,9 @@ { struct nameidata nd; int retval; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); retval = __user_walk(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd); if (retval) goto out; @@ -383,6 +386,7 @@ dput_and_out: path_release(&nd); out: + SWSUSP_ACTIVITY_END; return retval; } @@ -831,10 +835,14 @@ unsigned long type_page; unsigned long dev_page; char *dir_page; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); retval = copy_mount_options (type, &type_page); - if (retval < 0) + if (retval < 0) { + SWSUSP_ACTIVITY_END; return retval; + } dir_page = getname(dir_name); retval = PTR_ERR(dir_page); @@ -861,6 +869,7 @@ putname(dir_page); out1: free_page(type_page); + SWSUSP_ACTIVITY_END; return retval; } @@ -905,10 +914,12 @@ struct vfsmount *tmp; struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; if (!capable(CAP_SYS_ADMIN)) return -EPERM; + SWSUSP_ACTIVITY_START(0); lock_kernel(); error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd); @@ -978,6 +989,7 @@ path_release(&new_nd); out0: unlock_kernel(); + SWSUSP_ACTIVITY_END; return error; out3: spin_unlock(&dcache_lock); diff -ruN linux-2.4.23-pre6/fs/nfsd/nfssvc.c linux-2.4.23-pre6-swsusp/fs/nfsd/nfssvc.c --- linux-2.4.23-pre6/fs/nfsd/nfssvc.c 2002-11-29 08:53:15.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/nfsd/nfssvc.c 2003-10-05 03:42:25.000000000 +0900 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -157,6 +158,7 @@ struct svc_serv *serv = rqstp->rq_server; int err; struct nfsd_list me; + DECLARE_SWSUSP_LOCAL_VAR; /* Lock module and set up kernel thread */ MOD_INC_USE_COUNT; @@ -164,6 +166,10 @@ daemonize(); sprintf(current->comm, "nfsd"); current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; + current->flags |= PF_SYNCTHREAD; + + SWSUSP_THREAD_FLAGS_RESET; + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); nfsdstats.th_cnt++; /* Let svc_process check client's authentication. */ @@ -251,6 +257,7 @@ /* Release module */ MOD_DEC_USE_COUNT; + SWSUSP_ACTIVITY_END; } static int diff -ruN linux-2.4.23-pre6/fs/open.c linux-2.4.23-pre6-swsusp/fs/open.c --- linux-2.4.23-pre6/fs/open.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/open.c 2003-10-05 03:42:25.000000000 +0900 @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -41,7 +42,9 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = user_path_walk(path, &nd); if (!error) { struct statfs tmp; @@ -50,6 +53,7 @@ error = -EFAULT; path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -58,7 +62,9 @@ struct file * file; struct statfs tmp; int error; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = -EBADF; file = fget(fd); if (!file) @@ -68,6 +74,7 @@ error = -EFAULT; fput(file); out: + SWSUSP_ACTIVITY_END; return error; } @@ -120,7 +127,9 @@ struct nameidata nd; struct inode * inode; int error; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = -EINVAL; if (length < 0) /* sorry, but loff_t says... */ goto out; @@ -172,6 +181,7 @@ dput_and_out: path_release(&nd); out: + SWSUSP_ACTIVITY_END; return error; } @@ -187,7 +197,9 @@ struct dentry *dentry; struct file * file; int error; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = -EINVAL; if (length < 0) goto out; @@ -221,6 +233,7 @@ out_putf: fput(file); out: + SWSUSP_ACTIVITY_END; return error; } @@ -261,7 +274,9 @@ struct nameidata nd; struct inode * inode; struct iattr newattrs; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = user_path_walk(filename, &nd); if (error) goto out; @@ -290,6 +305,7 @@ dput_and_out: path_release(&nd); out: + SWSUSP_ACTIVITY_END; return error; } @@ -305,7 +321,9 @@ struct nameidata nd; struct inode * inode; struct iattr newattrs; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = user_path_walk(filename, &nd); if (error) @@ -335,6 +353,7 @@ dput_and_out: path_release(&nd); out: + SWSUSP_ACTIVITY_END; return error; } @@ -349,10 +368,12 @@ int old_fsuid, old_fsgid; kernel_cap_t old_cap; int res; + DECLARE_SWSUSP_LOCAL_VAR; if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; + SWSUSP_ACTIVITY_START(0); old_fsuid = current->fsuid; old_fsgid = current->fsgid; old_cap = current->cap_effective; @@ -380,6 +401,7 @@ current->fsgid = old_fsgid; current->cap_effective = old_cap; + SWSUSP_ACTIVITY_END; return res; } @@ -387,7 +409,9 @@ { int error; struct nameidata nd; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); if (error) goto out; @@ -401,6 +425,7 @@ dput_and_out: path_release(&nd); out: + SWSUSP_ACTIVITY_END; return error; } @@ -411,7 +436,9 @@ struct inode *inode; struct vfsmount *mnt; int error; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = -EBADF; file = fget(fd); if (!file) @@ -431,6 +458,7 @@ out_putf: fput(file); out: + SWSUSP_ACTIVITY_END; return error; } @@ -438,7 +466,9 @@ { int error; struct nameidata nd; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); if (error) @@ -458,6 +488,7 @@ dput_and_out: path_release(&nd); out: + SWSUSP_ACTIVITY_END; return error; } @@ -468,7 +499,9 @@ struct file * file; int err = -EBADF; struct iattr newattrs; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); file = fget(fd); if (!file) goto out; @@ -491,6 +524,7 @@ out_putf: fput(file); out: + SWSUSP_ACTIVITY_END; return err; } @@ -500,7 +534,9 @@ struct inode * inode; int error; struct iattr newattrs; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = user_path_walk(filename, &nd); if (error) goto out; @@ -523,6 +559,7 @@ dput_and_out: path_release(&nd); out: + SWSUSP_ACTIVITY_END; return error; } @@ -590,12 +627,15 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = user_path_walk(filename, &nd); if (!error) { error = chown_common(nd.dentry, user, group); path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -603,12 +643,15 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); error = user_path_walk_link(filename, &nd); if (!error) { error = chown_common(nd.dentry, user, group); path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -617,12 +660,15 @@ { struct file * file; int error = -EBADF; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); file = fget(fd); if (file) { error = chown_common(file->f_dentry, user, group); fput(file); } + SWSUSP_ACTIVITY_END; return error; } @@ -786,6 +832,9 @@ { char * tmp; int fd, error; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); #if BITS_PER_LONG != 32 flags |= O_LARGEFILE; @@ -804,6 +853,7 @@ out: putname(tmp); } + SWSUSP_ACTIVITY_END; return fd; out_error: @@ -858,7 +908,11 @@ { struct file * filp; struct files_struct *files = current->files; + unsigned long has_fridge_wait = (current->flags & PF_FRIDGE_WAIT); + DECLARE_SWSUSP_LOCAL_VAR; + if (!has_fridge_wait) + SWSUSP_ACTIVITY_START(0); write_lock(&files->file_lock); if (fd >= files->max_fds) goto out_unlock; @@ -869,10 +923,14 @@ FD_CLR(fd, files->close_on_exec); __put_unused_fd(files, fd); write_unlock(&files->file_lock); + if (!has_fridge_wait) + SWSUSP_ACTIVITY_END; return filp_close(filp, files); out_unlock: write_unlock(&files->file_lock); + if (!has_fridge_wait) + SWSUSP_ACTIVITY_END; return -EBADF; } diff -ruN linux-2.4.23-pre6/fs/pipe.c linux-2.4.23-pre6-swsusp/fs/pipe.c --- linux-2.4.23-pre6/fs/pipe.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/pipe.c 2003-10-05 03:42:25.000000000 +0900 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -27,12 +28,16 @@ void pipe_wait(struct inode * inode) { DECLARE_WAITQUEUE(wait, current); + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_PAUSING; current->state = TASK_INTERRUPTIBLE; add_wait_queue(PIPE_WAIT(*inode), &wait); up(PIPE_SEM(*inode)); schedule(); remove_wait_queue(PIPE_WAIT(*inode), &wait); current->state = TASK_RUNNING; + SWSUSP_ACTIVITY_RESTARTING(0); down(PIPE_SEM(*inode)); } diff -ruN linux-2.4.23-pre6/fs/proc/generic.c linux-2.4.23-pre6-swsusp/fs/proc/generic.c --- linux-2.4.23-pre6/fs/proc/generic.c 2003-10-05 04:16:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/proc/generic.c 2003-10-05 03:45:24.000000000 +0900 @@ -14,6 +14,7 @@ #include #include #include +#include #define __NO_VERSION__ #include #include @@ -126,6 +127,8 @@ { struct inode *inode = file->f_dentry->d_inode; struct proc_dir_entry * dp; + ssize_t result; + DECLARE_SWSUSP_LOCAL_VAR; dp = (struct proc_dir_entry *) inode->u.generic_ip; @@ -133,7 +136,10 @@ return -EIO; /* FIXME: does this routine need ppos? probably... */ - return dp->write_proc(file, buffer, count, dp->data); + SWSUSP_ACTIVITY_PAUSING; /* Might be initiating suspend */ + result = dp->write_proc(file, buffer, count, dp->data); + SWSUSP_ACTIVITY_RESTARTING(0); + return result; } diff -ruN linux-2.4.23-pre6/fs/proc/kmsg.c linux-2.4.23-pre6-swsusp/fs/proc/kmsg.c --- linux-2.4.23-pre6/fs/proc/kmsg.c 2001-09-17 13:22:40.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/proc/kmsg.c 2003-10-05 03:42:25.000000000 +0900 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -32,7 +33,13 @@ static ssize_t kmsg_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - return do_syslog(2,buf,count); + ssize_t size; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_PAUSING; + size = do_syslog(2,buf,count); + SWSUSP_ACTIVITY_RESTARTING(0); + return size; } static unsigned int kmsg_poll(struct file *file, poll_table * wait) diff -ruN linux-2.4.23-pre6/fs/read_write.c linux-2.4.23-pre6-swsusp/fs/read_write.c --- linux-2.4.23-pre6/fs/read_write.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/read_write.c 2003-10-05 03:42:25.000000000 +0900 @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -109,6 +110,9 @@ { off_t retval; struct file * file; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); retval = -EBADF; file = fget(fd); @@ -123,6 +127,7 @@ } fput(file); bad: + SWSUSP_ACTIVITY_END; return retval; } @@ -134,6 +139,9 @@ int retval; struct file * file; loff_t offset; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); retval = -EBADF; file = fget(fd); @@ -155,6 +163,7 @@ out_putf: fput(file); bad: + SWSUSP_ACTIVITY_END; return retval; } #endif @@ -163,6 +172,9 @@ { ssize_t ret; struct file * file; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); ret = -EBADF; file = fget(fd); @@ -181,6 +193,7 @@ dnotify_parent(file->f_dentry, DN_ACCESS); fput(file); } + SWSUSP_ACTIVITY_END; return ret; } @@ -188,6 +201,9 @@ { ssize_t ret; struct file * file; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); ret = -EBADF; file = fget(fd); @@ -207,6 +223,7 @@ dnotify_parent(file->f_dentry, DN_MODIFY); fput(file); } + SWSUSP_ACTIVITY_END; return ret; } @@ -331,7 +348,9 @@ { struct file * file; ssize_t ret; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); ret = -EBADF; file = fget(fd); @@ -343,6 +362,7 @@ fput(file); bad_file: + SWSUSP_ACTIVITY_END; return ret; } @@ -351,7 +371,9 @@ { struct file * file; ssize_t ret; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); ret = -EBADF; file = fget(fd); @@ -363,6 +385,7 @@ fput(file); bad_file: + SWSUSP_ACTIVITY_END; return ret; } @@ -376,6 +399,9 @@ ssize_t ret; struct file * file; ssize_t (*read)(struct file *, char *, size_t, loff_t *); + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); ret = -EBADF; file = fget(fd); @@ -398,6 +424,7 @@ out: fput(file); bad_file: + SWSUSP_ACTIVITY_END; return ret; } @@ -407,6 +434,9 @@ ssize_t ret; struct file * file; ssize_t (*write)(struct file *, const char *, size_t, loff_t *); + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); ret = -EBADF; file = fget(fd); @@ -430,5 +460,6 @@ out: fput(file); bad_file: + SWSUSP_ACTIVITY_END; return ret; } diff -ruN linux-2.4.23-pre6/fs/reiserfs/journal.c linux-2.4.23-pre6-swsusp/fs/reiserfs/journal.c --- linux-2.4.23-pre6/fs/reiserfs/journal.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/reiserfs/journal.c 2003-10-05 03:42:25.000000000 +0900 @@ -58,6 +58,7 @@ #include #include #include +#include /* the number of mounted filesystems. This is used to decide when to ** start and kill the commit thread @@ -1886,6 +1887,8 @@ */ static int reiserfs_journal_commit_thread(void *nullp) { + DECLARE_SWSUSP_LOCAL_VAR; + daemonize() ; spin_lock_irq(¤t->sigmask_lock); @@ -1893,7 +1896,10 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); + SWSUSP_THREAD_FLAGS_RESET; + SWSUSP_ACTIVITY_START(PF_SYNCTHREAD); sprintf(current->comm, "kreiserfsd") ; + current->flags |= PF_SYNCTHREAD; lock_kernel() ; while(1) { @@ -1906,10 +1912,13 @@ run_task_queue(&reiserfs_commit_thread_tq) ; break ; } + SWSUSP_ACTIVITY_PAUSING; wake_up(&reiserfs_commit_thread_done) ; interruptible_sleep_on_timeout(&reiserfs_commit_thread_wait, 5 * HZ) ; + SWSUSP_ACTIVITY_RESTARTING(PF_SYNCTHREAD); } unlock_kernel() ; + SWSUSP_ACTIVITY_END; wake_up(&reiserfs_commit_thread_done) ; return 0 ; } diff -ruN linux-2.4.23-pre6/fs/stat.c linux-2.4.23-pre6-swsusp/fs/stat.c --- linux-2.4.23-pre6/fs/stat.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/stat.c 2003-10-05 03:42:25.000000000 +0900 @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -138,6 +139,9 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); error = user_path_walk(filename, &nd); if (!error) { @@ -146,6 +150,7 @@ error = cp_old_stat(nd.dentry->d_inode, statbuf); path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } #endif @@ -154,6 +159,9 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); error = user_path_walk(filename, &nd); if (!error) { @@ -162,6 +170,7 @@ error = cp_new_stat(nd.dentry->d_inode, statbuf); path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -175,6 +184,9 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); error = user_path_walk_link(filename, &nd); if (!error) { @@ -183,6 +195,7 @@ error = cp_old_stat(nd.dentry->d_inode, statbuf); path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -192,6 +205,9 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); error = user_path_walk_link(filename, &nd); if (!error) { @@ -200,6 +216,7 @@ error = cp_new_stat(nd.dentry->d_inode, statbuf); path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -213,6 +230,9 @@ { struct file * f; int err = -EBADF; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); f = fget(fd); if (f) { @@ -223,6 +243,7 @@ err = cp_old_stat(dentry->d_inode, statbuf); fput(f); } + SWSUSP_ACTIVITY_END; return err; } @@ -232,6 +253,9 @@ { struct file * f; int err = -EBADF; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); f = fget(fd); if (f) { @@ -242,6 +266,7 @@ err = cp_new_stat(dentry->d_inode, statbuf); fput(f); } + SWSUSP_ACTIVITY_END; return err; } @@ -249,10 +274,13 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; if (bufsiz <= 0) return -EINVAL; + SWSUSP_ACTIVITY_START(0); + error = user_path_walk_link(path, &nd); if (!error) { struct inode * inode = nd.dentry->d_inode; @@ -265,6 +293,7 @@ } path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -335,6 +364,9 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); error = user_path_walk(filename, &nd); if (!error) { @@ -343,6 +375,7 @@ error = cp_new_stat64(nd.dentry->d_inode, statbuf); path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -350,6 +383,9 @@ { struct nameidata nd; int error; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); error = user_path_walk_link(filename, &nd); if (!error) { @@ -358,6 +394,7 @@ error = cp_new_stat64(nd.dentry->d_inode, statbuf); path_release(&nd); } + SWSUSP_ACTIVITY_END; return error; } @@ -365,6 +402,9 @@ { struct file * f; int err = -EBADF; + DECLARE_SWSUSP_LOCAL_VAR; + + SWSUSP_ACTIVITY_START(0); f = fget(fd); if (f) { @@ -375,6 +415,7 @@ err = cp_new_stat64(dentry->d_inode, statbuf); fput(f); } + SWSUSP_ACTIVITY_END; return err; } diff -ruN linux-2.4.23-pre6/fs/super.c linux-2.4.23-pre6-swsusp/fs/super.c --- linux-2.4.23-pre6/fs/super.c 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/fs/super.c 2003-10-05 03:42:25.000000000 +0900 @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -518,7 +519,9 @@ struct ustat tmp; struct statfs sbuf; int err = -EINVAL; + DECLARE_SWSUSP_LOCAL_VAR; + SWSUSP_ACTIVITY_START(0); s = get_super(to_kdev_t(dev)); if (s == NULL) goto out; @@ -533,6 +536,7 @@ err = copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0; out: + SWSUSP_ACTIVITY_END; return err; } diff -ruN linux-2.4.23-pre6/include/asm/a.out.h linux-2.4.23-pre6-swsusp/include/asm/a.out.h --- linux-2.4.23-pre6/include/asm/a.out.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/a.out.h 1995-06-17 03:33:06.000000000 +0900 @@ -0,0 +1,26 @@ +#ifndef __I386_A_OUT_H__ +#define __I386_A_OUT_H__ + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#ifdef __KERNEL__ + +#define STACK_TOP TASK_SIZE + +#endif + +#endif /* __A_OUT_GNU_H__ */ diff -ruN linux-2.4.23-pre6/include/asm/acpi.h linux-2.4.23-pre6-swsusp/include/asm/acpi.h --- linux-2.4.23-pre6/include/asm/acpi.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/acpi.h 2003-10-05 03:45:24.000000000 +0900 @@ -0,0 +1,181 @@ +/* + * asm-i386/acpi.h + * + * Copyright (C) 2001 Paul Diefenbaugh + * Copyright (C) 2001 Patrick Mochel + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifndef _ASM_ACPI_H +#define _ASM_ACPI_H + +#ifdef __KERNEL__ + +#define COMPILER_DEPENDENT_INT64 long long +#define COMPILER_DEPENDENT_UINT64 unsigned long long + +/* + * Calling conventions: + * + * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) + * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_INTERNAL_XFACE - Internal ACPI interfaces + * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces + */ +#define ACPI_SYSTEM_XFACE +#define ACPI_EXTERNAL_XFACE +#define ACPI_INTERNAL_XFACE +#define ACPI_INTERNAL_VAR_XFACE + +/* Asm macros */ + +#define ACPI_ASM_MACROS +#define BREAKPOINT3 +#define ACPI_DISABLE_IRQS() __cli() +#define ACPI_ENABLE_IRQS() __sti() +#define ACPI_FLUSH_CPU_CACHE() wbinvd() + +/* + * A brief explanation as GNU inline assembly is a bit hairy + * %0 is the output parameter in EAX ("=a") + * %1 and %2 are the input parameters in ECX ("c") + * and an immediate value ("i") respectively + * All actual register references are preceded with "%%" as in "%%edx" + * Immediate values in the assembly are preceded by "$" as in "$0x1" + * The final asm parameter are the operation altered non-output registers. + */ +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + int dummy; \ + asm("1: movl (%1),%%eax;" \ + "movl %%eax,%%edx;" \ + "andl %2,%%edx;" \ + "btsl $0x1,%%edx;" \ + "adcl $0x0,%%edx;" \ + "lock; cmpxchgl %%edx,(%1);" \ + "jnz 1b;" \ + "cmpb $0x3,%%dl;" \ + "sbbl %%eax,%%eax" \ + :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ + } while(0) + +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + int dummy; \ + asm("1: movl (%1),%%eax;" \ + "movl %%eax,%%edx;" \ + "andl %2,%%edx;" \ + "lock; cmpxchgl %%edx,(%1);" \ + "jnz 1b;" \ + "andl $0x1,%%eax" \ + :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ + } while(0) + + +/* + * Math helper asm macros + */ +#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ + asm("divl %2;" \ + :"=a"(q32), "=d"(r32) \ + :"r"(d32), \ + "0"(n_lo), "1"(n_hi)) + + +#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ + asm("shrl $1,%2;" \ + "rcrl $1,%3;" \ + :"=r"(n_hi), "=r"(n_lo) \ + :"0"(n_hi), "1"(n_lo)) + + +#ifdef CONFIG_ACPI_BOOT +extern int acpi_lapic; +extern int acpi_ioapic; + + +/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ +#define FIX_ACPI_PAGES 4 + +#ifdef CONFIG_X86_IO_APIC +extern int skip_ioapic_setup; + +static inline void disable_ioapic_setup(void) +{ + skip_ioapic_setup = 1; +} + +static inline int ioapic_setup_disabled(void) +{ + return skip_ioapic_setup; +} + +#else +static inline void disable_ioapic_setup(void) +{ } + +#endif + +#else /* CONFIG_ACPI_BOOT */ +# define acpi_lapic 0 +# define acpi_ioapic 0 + +#endif + +#ifdef CONFIG_ACPI_SLEEP + +extern unsigned long saved_eip; +extern unsigned long saved_esp; +extern unsigned long saved_ebp; +extern unsigned long saved_ebx; +extern unsigned long saved_esi; +extern unsigned long saved_edi; + +static inline void acpi_save_register_state(unsigned long return_point) +{ + saved_eip = return_point; + asm volatile ("movl %%esp,(%0)" : "=m" (saved_esp)); + asm volatile ("movl %%ebp,(%0)" : "=m" (saved_ebp)); + asm volatile ("movl %%ebx,(%0)" : "=m" (saved_ebx)); + asm volatile ("movl %%edi,(%0)" : "=m" (saved_edi)); + asm volatile ("movl %%esi,(%0)" : "=m" (saved_esi)); +} + +#define acpi_restore_register_state() do {} while (0) + + +/* routines for saving/restoring kernel state */ +extern int acpi_save_state_mem(void); +extern int acpi_save_state_disk(void); +extern void acpi_restore_state_mem(void); + +extern unsigned long acpi_wakeup_address; + +extern void do_suspend_lowlevel_s4bios(int resume); + +/* early initialization routine */ +extern void acpi_reserve_bootmem(void); + +#endif /*CONFIG_ACPI_SLEEP*/ + + +#endif /*__KERNEL__*/ + +#endif /*_ASM_ACPI_H*/ diff -ruN linux-2.4.23-pre6/include/asm/apic.h linux-2.4.23-pre6-swsusp/include/asm/apic.h --- linux-2.4.23-pre6/include/asm/apic.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/apic.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,99 @@ +#ifndef __ASM_APIC_H +#define __ASM_APIC_H + +#include +#include +#include +#include + +#ifdef CONFIG_X86_LOCAL_APIC + +#define APIC_DEBUG 0 + +#if APIC_DEBUG +#define Dprintk(x...) printk(x) +#else +#define Dprintk(x...) +#endif + +/* + * Basic functions accessing APICs. + */ + +static __inline void apic_write(unsigned long reg, unsigned long v) +{ + *((volatile unsigned long *)(APIC_BASE+reg)) = v; +} + +static __inline void apic_write_atomic(unsigned long reg, unsigned long v) +{ + xchg((volatile unsigned long *)(APIC_BASE+reg), v); +} + +static __inline unsigned long apic_read(unsigned long reg) +{ + return *((volatile unsigned long *)(APIC_BASE+reg)); +} + +static __inline__ void apic_wait_icr_idle(void) +{ + do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY ); +} + +#ifdef CONFIG_X86_GOOD_APIC +# define FORCE_READ_AROUND_WRITE 0 +# define apic_read_around(x) +# define apic_write_around(x,y) apic_write((x),(y)) +#else +# define FORCE_READ_AROUND_WRITE 1 +# define apic_read_around(x) apic_read(x) +# define apic_write_around(x,y) apic_write_atomic((x),(y)) +#endif + +static inline void ack_APIC_irq(void) +{ + /* + * ack_APIC_irq() actually gets compiled as a single instruction: + * - a single rmw on Pentium/82489DX + * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC) + * ... yummie. + */ + + /* Docs say use 0 for future compatibility */ + apic_write_around(APIC_EOI, 0); +} + +extern int get_maxlvt(void); +extern void clear_local_APIC(void); +extern void connect_bsp_APIC (void); +extern void disconnect_bsp_APIC (void); +extern void disable_local_APIC (void); +extern int verify_local_APIC (void); +extern void cache_APIC_registers (void); +extern void sync_Arb_IDs (void); +extern void init_bsp_APIC (void); +extern void setup_local_APIC (void); +extern void init_apic_mappings (void); +extern void smp_local_timer_interrupt (struct pt_regs * regs); +extern void setup_APIC_clocks (void); +extern void setup_apic_nmi_watchdog (void); +extern inline void nmi_watchdog_tick (struct pt_regs * regs); +extern int APIC_init_uniprocessor (void); +extern void disable_APIC_timer(void); +extern void enable_APIC_timer(void); + +extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback); +extern void apic_pm_unregister(struct pm_dev*); + +extern unsigned int apic_timer_irqs [NR_CPUS]; +extern int check_nmi_watchdog (void); + +extern unsigned int nmi_watchdog; +#define NMI_NONE 0 +#define NMI_IO_APIC 1 +#define NMI_LOCAL_APIC 2 +#define NMI_INVALID 3 + +#endif /* CONFIG_X86_LOCAL_APIC */ + +#endif /* __ASM_APIC_H */ diff -ruN linux-2.4.23-pre6/include/asm/apicdef.h linux-2.4.23-pre6-swsusp/include/asm/apicdef.h --- linux-2.4.23-pre6/include/asm/apicdef.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/apicdef.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,379 @@ +#ifndef __ASM_APICDEF_H +#define __ASM_APICDEF_H + +/* + * Constants for various Intel APICs. (local APIC, IOAPIC, etc.) + * + * Alan Cox , 1995. + * Ingo Molnar , 1999, 2000 + */ + +#define APIC_DEFAULT_PHYS_BASE 0xfee00000 + +#define APIC_ID 0x20 +#define APIC_ID_MASK (0x0F<<24) +#define GET_APIC_ID(x) (((x)>>24)&0x0F) +#define APIC_LVR 0x30 +#define APIC_LVR_MASK 0xFF00FF +#define GET_APIC_VERSION(x) ((x)&0xFF) +#define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF) +#define APIC_INTEGRATED(x) ((x)&0xF0) +#define APIC_XAPIC_SUPPORT(x) ((x)>=0x14) +#define APIC_TASKPRI 0x80 +#define APIC_TPRI_MASK 0xFF +#define APIC_ARBPRI 0x90 +#define APIC_ARBPRI_MASK 0xFF +#define APIC_PROCPRI 0xA0 +#define APIC_EOI 0xB0 +#define APIC_EIO_ACK 0x0 /* Write this to the EOI register */ +#define APIC_RRR 0xC0 +#define APIC_LDR 0xD0 +#define APIC_LDR_MASK (0xFF<<24) +#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF) +#define SET_APIC_LOGICAL_ID(x) (((x)<<24)) +#define APIC_ALL_CPUS 0xFF +#define APIC_DFR 0xE0 +#define APIC_DFR_CLUSTER 0x0FFFFFFFul /* Clustered */ +#define APIC_DFR_FLAT 0xFFFFFFFFul /* Flat mode */ +#define APIC_SPIV 0xF0 +#define APIC_SPIV_FOCUS_DISABLED (1<<9) +#define APIC_SPIV_APIC_ENABLED (1<<8) +#define APIC_ISR 0x100 +#define APIC_TMR 0x180 +#define APIC_IRR 0x200 +#define APIC_ESR 0x280 +#define APIC_ESR_SEND_CS 0x00001 +#define APIC_ESR_RECV_CS 0x00002 +#define APIC_ESR_SEND_ACC 0x00004 +#define APIC_ESR_RECV_ACC 0x00008 +#define APIC_ESR_SENDILL 0x00020 +#define APIC_ESR_RECVILL 0x00040 +#define APIC_ESR_ILLREGA 0x00080 +#define APIC_ICR 0x300 +#define APIC_DEST_SELF 0x40000 +#define APIC_DEST_ALLINC 0x80000 +#define APIC_DEST_ALLBUT 0xC0000 +#define APIC_ICR_RR_MASK 0x30000 +#define APIC_ICR_RR_INVALID 0x00000 +#define APIC_ICR_RR_INPROG 0x10000 +#define APIC_ICR_RR_VALID 0x20000 +#define APIC_INT_LEVELTRIG 0x08000 +#define APIC_INT_ASSERT 0x04000 +#define APIC_ICR_BUSY 0x01000 +#define APIC_DEST_PHYSICAL 0x00000 +#define APIC_DEST_LOGICAL 0x00800 +#define APIC_DM_FIXED 0x00000 +#define APIC_DM_LOWEST 0x00100 +#define APIC_DM_SMI 0x00200 +#define APIC_DM_REMRD 0x00300 +#define APIC_DM_NMI 0x00400 +#define APIC_DM_INIT 0x00500 +#define APIC_DM_STARTUP 0x00600 +#define APIC_DM_EXTINT 0x00700 +#define APIC_VECTOR_MASK 0x000FF +#define APIC_ICR2 0x310 +#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF) +#define SET_APIC_DEST_FIELD(x) ((x)<<24) +#define APIC_LVTT 0x320 +#define APIC_LVTPC 0x340 +#define APIC_LVT0 0x350 +#define APIC_LVT_TIMER_BASE_MASK (0x3<<18) +#define GET_APIC_TIMER_BASE(x) (((x)>>18)&0x3) +#define SET_APIC_TIMER_BASE(x) (((x)<<18)) +#define APIC_TIMER_BASE_CLKIN 0x0 +#define APIC_TIMER_BASE_TMBASE 0x1 +#define APIC_TIMER_BASE_DIV 0x2 +#define APIC_LVT_TIMER_PERIODIC (1<<17) +#define APIC_LVT_MASKED (1<<16) +#define APIC_LVT_LEVEL_TRIGGER (1<<15) +#define APIC_LVT_REMOTE_IRR (1<<14) +#define APIC_INPUT_POLARITY (1<<13) +#define APIC_SEND_PENDING (1<<12) +#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) +#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) +#define APIC_MODE_FIXED 0x0 +#define APIC_MODE_NMI 0x4 +#define APIC_MODE_EXINT 0x7 +#define APIC_LVT1 0x360 +#define APIC_LVTERR 0x370 +#define APIC_TMICT 0x380 +#define APIC_TMCCT 0x390 +#define APIC_TDCR 0x3E0 +#define APIC_TDR_DIV_TMBASE (1<<2) +#define APIC_TDR_DIV_1 0xB +#define APIC_TDR_DIV_2 0x0 +#define APIC_TDR_DIV_4 0x1 +#define APIC_TDR_DIV_8 0x2 +#define APIC_TDR_DIV_16 0x3 +#define APIC_TDR_DIV_32 0x8 +#define APIC_TDR_DIV_64 0x9 +#define APIC_TDR_DIV_128 0xA + +#define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) + +#ifdef CONFIG_X86_CLUSTERED_APIC +#define MAX_IO_APICS 32 +#else +#define MAX_IO_APICS 8 +#endif + + +/* + * The broadcast ID is 0xF for old APICs and 0xFF for xAPICs. SAPICs + * don't broadcast (yet?), but if they did, they might use 0xFFFF. + */ +#define APIC_BROADCAST_ID_XAPIC (0xFF) +#define APIC_BROADCAST_ID_APIC (0x0F) + +/* + * the local APIC register structure, memory mapped. Not terribly well + * tested, but we might eventually use this one in the future - the + * problem why we cannot use it right now is the P5 APIC, it has an + * errata which cannot take 8-bit reads and writes, only 32-bit ones ... + */ +#define u32 unsigned int + +#define lapic ((volatile struct local_apic *)APIC_BASE) + +struct local_apic { + +/*000*/ struct { u32 __reserved[4]; } __reserved_01; + +/*010*/ struct { u32 __reserved[4]; } __reserved_02; + +/*020*/ struct { /* APIC ID Register */ + u32 __reserved_1 : 24, + phys_apic_id : 4, + __reserved_2 : 4; + u32 __reserved[3]; + } id; + +/*030*/ const + struct { /* APIC Version Register */ + u32 version : 8, + __reserved_1 : 8, + max_lvt : 8, + __reserved_2 : 8; + u32 __reserved[3]; + } version; + +/*040*/ struct { u32 __reserved[4]; } __reserved_03; + +/*050*/ struct { u32 __reserved[4]; } __reserved_04; + +/*060*/ struct { u32 __reserved[4]; } __reserved_05; + +/*070*/ struct { u32 __reserved[4]; } __reserved_06; + +/*080*/ struct { /* Task Priority Register */ + u32 priority : 8, + __reserved_1 : 24; + u32 __reserved_2[3]; + } tpr; + +/*090*/ const + struct { /* Arbitration Priority Register */ + u32 priority : 8, + __reserved_1 : 24; + u32 __reserved_2[3]; + } apr; + +/*0A0*/ const + struct { /* Processor Priority Register */ + u32 priority : 8, + __reserved_1 : 24; + u32 __reserved_2[3]; + } ppr; + +/*0B0*/ struct { /* End Of Interrupt Register */ + u32 eoi; + u32 __reserved[3]; + } eoi; + +/*0C0*/ struct { u32 __reserved[4]; } __reserved_07; + +/*0D0*/ struct { /* Logical Destination Register */ + u32 __reserved_1 : 24, + logical_dest : 8; + u32 __reserved_2[3]; + } ldr; + +/*0E0*/ struct { /* Destination Format Register */ + u32 __reserved_1 : 28, + model : 4; + u32 __reserved_2[3]; + } dfr; + +/*0F0*/ struct { /* Spurious Interrupt Vector Register */ + u32 spurious_vector : 8, + apic_enabled : 1, + focus_cpu : 1, + __reserved_2 : 22; + u32 __reserved_3[3]; + } svr; + +/*100*/ struct { /* In Service Register */ +/*170*/ u32 bitfield; + u32 __reserved[3]; + } isr [8]; + +/*180*/ struct { /* Trigger Mode Register */ +/*1F0*/ u32 bitfield; + u32 __reserved[3]; + } tmr [8]; + +/*200*/ struct { /* Interrupt Request Register */ +/*270*/ u32 bitfield; + u32 __reserved[3]; + } irr [8]; + +/*280*/ union { /* Error Status Register */ + struct { + u32 send_cs_error : 1, + receive_cs_error : 1, + send_accept_error : 1, + receive_accept_error : 1, + __reserved_1 : 1, + send_illegal_vector : 1, + receive_illegal_vector : 1, + illegal_register_address : 1, + __reserved_2 : 24; + u32 __reserved_3[3]; + } error_bits; + struct { + u32 errors; + u32 __reserved_3[3]; + } all_errors; + } esr; + +/*290*/ struct { u32 __reserved[4]; } __reserved_08; + +/*2A0*/ struct { u32 __reserved[4]; } __reserved_09; + +/*2B0*/ struct { u32 __reserved[4]; } __reserved_10; + +/*2C0*/ struct { u32 __reserved[4]; } __reserved_11; + +/*2D0*/ struct { u32 __reserved[4]; } __reserved_12; + +/*2E0*/ struct { u32 __reserved[4]; } __reserved_13; + +/*2F0*/ struct { u32 __reserved[4]; } __reserved_14; + +/*300*/ struct { /* Interrupt Command Register 1 */ + u32 vector : 8, + delivery_mode : 3, + destination_mode : 1, + delivery_status : 1, + __reserved_1 : 1, + level : 1, + trigger : 1, + __reserved_2 : 2, + shorthand : 2, + __reserved_3 : 12; + u32 __reserved_4[3]; + } icr1; + +/*310*/ struct { /* Interrupt Command Register 2 */ + union { + u32 __reserved_1 : 24, + phys_dest : 4, + __reserved_2 : 4; + u32 __reserved_3 : 24, + logical_dest : 8; + } dest; + u32 __reserved_4[3]; + } icr2; + +/*320*/ struct { /* LVT - Timer */ + u32 vector : 8, + __reserved_1 : 4, + delivery_status : 1, + __reserved_2 : 3, + mask : 1, + timer_mode : 1, + __reserved_3 : 14; + u32 __reserved_4[3]; + } lvt_timer; + +/*330*/ struct { u32 __reserved[4]; } __reserved_15; + +/*340*/ struct { /* LVT - Performance Counter */ + u32 vector : 8, + delivery_mode : 3, + __reserved_1 : 1, + delivery_status : 1, + __reserved_2 : 3, + mask : 1, + __reserved_3 : 15; + u32 __reserved_4[3]; + } lvt_pc; + +/*350*/ struct { /* LVT - LINT0 */ + u32 vector : 8, + delivery_mode : 3, + __reserved_1 : 1, + delivery_status : 1, + polarity : 1, + remote_irr : 1, + trigger : 1, + mask : 1, + __reserved_2 : 15; + u32 __reserved_3[3]; + } lvt_lint0; + +/*360*/ struct { /* LVT - LINT1 */ + u32 vector : 8, + delivery_mode : 3, + __reserved_1 : 1, + delivery_status : 1, + polarity : 1, + remote_irr : 1, + trigger : 1, + mask : 1, + __reserved_2 : 15; + u32 __reserved_3[3]; + } lvt_lint1; + +/*370*/ struct { /* LVT - Error */ + u32 vector : 8, + __reserved_1 : 4, + delivery_status : 1, + __reserved_2 : 3, + mask : 1, + __reserved_3 : 15; + u32 __reserved_4[3]; + } lvt_error; + +/*380*/ struct { /* Timer Initial Count Register */ + u32 initial_count; + u32 __reserved_2[3]; + } timer_icr; + +/*390*/ const + struct { /* Timer Current Count Register */ + u32 curr_count; + u32 __reserved_2[3]; + } timer_ccr; + +/*3A0*/ struct { u32 __reserved[4]; } __reserved_16; + +/*3B0*/ struct { u32 __reserved[4]; } __reserved_17; + +/*3C0*/ struct { u32 __reserved[4]; } __reserved_18; + +/*3D0*/ struct { u32 __reserved[4]; } __reserved_19; + +/*3E0*/ struct { /* Timer Divide Configuration Register */ + u32 divisor : 4, + __reserved_1 : 28; + u32 __reserved_2[3]; + } timer_dcr; + +/*3F0*/ struct { u32 __reserved[4]; } __reserved_20; + +} __attribute__ ((packed)); + +#undef u32 + +#endif diff -ruN linux-2.4.23-pre6/include/asm/atomic.h linux-2.4.23-pre6-swsusp/include/asm/atomic.h --- linux-2.4.23-pre6/include/asm/atomic.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/atomic.h 2001-11-23 04:46:18.000000000 +0900 @@ -0,0 +1,204 @@ +#ifndef __ARCH_I386_ATOMIC__ +#define __ARCH_I386_ATOMIC__ + +#include + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +#ifdef CONFIG_SMP +#define LOCK "lock ; " +#else +#define LOCK "" +#endif + +/* + * 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. + */ +typedef struct { volatile int counter; } atomic_t; + +#define ATOMIC_INIT(i) { (i) } + +/** + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define atomic_read(v) ((v)->counter) + +/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define atomic_set(v,i) (((v)->counter) = (i)) + +/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v. Note that the guaranteed useful range + * of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_add(int i, atomic_t *v) +{ + __asm__ __volatile__( + LOCK "addl %1,%0" + :"=m" (v->counter) + :"ir" (i), "m" (v->counter)); +} + +/** + * atomic_sub - subtract the atomic variable + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_sub(int i, atomic_t *v) +{ + __asm__ __volatile__( + LOCK "subl %1,%0" + :"=m" (v->counter) + :"ir" (i), "m" (v->counter)); +} + +/** + * atomic_sub_and_test - subtract value from variable and test result + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v and returns + * true if the result is zero, or false for all + * other cases. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ int atomic_sub_and_test(int i, atomic_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "subl %2,%0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"ir" (i), "m" (v->counter) : "memory"); + return c; +} + +/** + * atomic_inc - increment atomic variable + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_inc(atomic_t *v) +{ + __asm__ __volatile__( + LOCK "incl %0" + :"=m" (v->counter) + :"m" (v->counter)); +} + +/** + * atomic_dec - decrement atomic variable + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_dec(atomic_t *v) +{ + __asm__ __volatile__( + LOCK "decl %0" + :"=m" (v->counter) + :"m" (v->counter)); +} + +/** + * atomic_dec_and_test - decrement and test + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1 and + * returns true if the result is 0, or false for all other + * cases. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ int atomic_dec_and_test(atomic_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "decl %0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"m" (v->counter) : "memory"); + return c != 0; +} + +/** + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ int atomic_inc_and_test(atomic_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "incl %0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"m" (v->counter) : "memory"); + return c != 0; +} + +/** + * atomic_add_negative - add and test if negative + * @v: pointer of type atomic_t + * @i: integer value to add + * + * Atomically adds @i to @v and returns true + * if the result is negative, or false when + * result is greater than or equal to zero. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ int atomic_add_negative(int i, atomic_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "addl %2,%0; sets %1" + :"=m" (v->counter), "=qm" (c) + :"ir" (i), "m" (v->counter) : "memory"); + return c; +} + +/* These are x86-specific, used by some header files */ +#define atomic_clear_mask(mask, addr) \ +__asm__ __volatile__(LOCK "andl %0,%1" \ +: : "r" (~(mask)),"m" (*addr) : "memory") + +#define atomic_set_mask(mask, addr) \ +__asm__ __volatile__(LOCK "orl %0,%1" \ +: : "r" (mask),"m" (*addr) : "memory") + +/* Atomic operations are already serializing on x86 */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#endif diff -ruN linux-2.4.23-pre6/include/asm/bitops.h linux-2.4.23-pre6-swsusp/include/asm/bitops.h --- linux-2.4.23-pre6/include/asm/bitops.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/bitops.h 2003-10-05 03:42:25.000000000 +0900 @@ -0,0 +1,390 @@ +#ifndef _I386_BITOPS_H +#define _I386_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +#include + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#ifdef CONFIG_SMP +#define LOCK_PREFIX "lock ; " +#else +#define LOCK_PREFIX "" +#endif + +#define ADDR (*(volatile long *) addr) + +/** + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * This function is atomic and may not be reordered. See __set_bit() + * if you do not require the atomic guarantees. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * __set_bit - Set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike set_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __set_bit(int nr, volatile void * addr) +{ + __asm__( + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and may not be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static __inline__ void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +/** + * __change_bit - Toggle a bit in memory + * @nr: the bit to change + * @addr: the address to start counting from + * + * Unlike change_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * change_bit - Toggle a bit in memory + * @nr: Bit to change + * @addr: Address to start counting from + * + * change_bit() is atomic and may not be reordered. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/** + * test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to clear + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to clear + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/* WARNING: non atomic and it can be reordered! */ +static __inline__ int __test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * test_and_change_bit - Change a bit and return its new value + * @nr: Bit to change + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +#if 0 /* Fool kernel-doc since it doesn't do macros yet */ +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static int test_bit(int nr, const volatile void * addr); +#endif + +static __inline__ int constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int variable_test_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (ADDR),"Ir" (nr)); + return oldbit; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + +/** + * find_first_zero_bit - find the first zero bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first zero bit, not the number of the byte + * containing a bit. + */ +static __inline__ int find_first_zero_bit(void * addr, unsigned size) +{ + int d0, d1, d2; + int res; + + if (!size) + return 0; + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + return res; +} + +/** + * find_next_zero_bit - find the first zero bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/** + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +static __inline__ unsigned long ffz(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} + +/* + * fls: find last bit set. + */ + +#define fls(x) generic_fls(x) + +#ifdef __KERNEL__ + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static __inline__ int ffs(int x) +{ + int r; + + __asm__("bsfl %1,%0\n\t" + "jnz 1f\n\t" + "movl $-1,%0\n" + "1:" : "=r" (r) : "rm" (x)); + return r+1; +} + +/** + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif /* __KERNEL__ */ + +#ifdef __KERNEL__ + +#define ext2_set_bit __test_and_set_bit +#define ext2_clear_bit __test_and_clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr) +#define minix_set_bit(nr,addr) __set_bit(nr,addr) +#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +#endif /* __KERNEL__ */ + +#endif /* _I386_BITOPS_H */ diff -ruN linux-2.4.23-pre6/include/asm/boot.h linux-2.4.23-pre6-swsusp/include/asm/boot.h --- linux-2.4.23-pre6/include/asm/boot.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/boot.h 1997-04-17 06:15:00.000000000 +0900 @@ -0,0 +1,15 @@ +#ifndef _LINUX_BOOT_H +#define _LINUX_BOOT_H + +/* Don't touch these, unless you really know what you're doing. */ +#define DEF_INITSEG 0x9000 +#define DEF_SYSSEG 0x1000 +#define DEF_SETUPSEG 0x9020 +#define DEF_SYSSIZE 0x7F00 + +/* Internal svga startup constants */ +#define NORMAL_VGA 0xffff /* 80x25 mode */ +#define EXTENDED_VGA 0xfffe /* 80x50 mode */ +#define ASK_VGA 0xfffd /* ask for it at bootup */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/bugs.h linux-2.4.23-pre6-swsusp/include/asm/bugs.h --- linux-2.4.23-pre6/include/asm/bugs.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/bugs.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,220 @@ +/* + * include/asm-i386/bugs.h + * + * Copyright (C) 1994 Linus Torvalds + * + * Cyrix stuff, June 1998 by: + * - Rafael R. Reilova (moved everything from head.S), + * + * - Channing Corn (tests & fixes), + * - Andrew D. Balsa (code cleanup). + * + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 + */ + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +#include +#include +#include +#include + +static int __init no_halt(char *s) +{ + boot_cpu_data.hlt_works_ok = 0; + return 1; +} + +__setup("no-hlt", no_halt); + +static int __init mca_pentium(char *s) +{ + mca_pentium_flag = 1; + return 1; +} + +__setup("mca-pentium", mca_pentium); + +static int __init no_387(char *s) +{ + boot_cpu_data.hard_math = 0; + write_cr0(0xE | read_cr0()); + return 1; +} + +__setup("no387", no_387); + +static double __initdata x = 4195835.0; +static double __initdata y = 3145727.0; + +/* + * This used to check for exceptions.. + * However, it turns out that to support that, + * the XMM trap handlers basically had to + * be buggy. So let's have a correct XMM trap + * handler, and forget about printing out + * some status at boot. + * + * We should really only care about bugs here + * anyway. Not features. + */ +static void __init check_fpu(void) +{ + if (!boot_cpu_data.hard_math) { +#ifndef CONFIG_MATH_EMULATION + printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); + printk(KERN_EMERG "Giving up.\n"); + for (;;) ; +#endif + return; + } + +/* Enable FXSR and company _before_ testing for FP problems. */ + /* + * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned. + */ + if (offsetof(struct task_struct, thread.i387.fxsave) & 15) { + extern void __buggy_fxsr_alignment(void); + __buggy_fxsr_alignment(); + } + if (cpu_has_fxsr) { + printk(KERN_INFO "Enabling fast FPU save and restore... "); + set_in_cr4(X86_CR4_OSFXSR); + printk("done.\n"); + } + if (cpu_has_xmm) { + printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... "); + set_in_cr4(X86_CR4_OSXMMEXCPT); + printk("done.\n"); + } + + /* Test for the divl bug.. */ + __asm__("fninit\n\t" + "fldl %1\n\t" + "fdivl %2\n\t" + "fmull %2\n\t" + "fldl %1\n\t" + "fsubp %%st,%%st(1)\n\t" + "fistpl %0\n\t" + "fwait\n\t" + "fninit" + : "=m" (*&boot_cpu_data.fdiv_bug) + : "m" (*&x), "m" (*&y)); + if (boot_cpu_data.fdiv_bug) + printk("Hmm, FPU with FDIV bug.\n"); +} + +static void __init check_hlt(void) +{ + printk(KERN_INFO "Checking 'hlt' instruction... "); + if (!boot_cpu_data.hlt_works_ok) { + printk("disabled\n"); + return; + } + __asm__ __volatile__("hlt ; hlt ; hlt ; hlt"); + printk("OK.\n"); +} + +/* + * Most 386 processors have a bug where a POPAD can lock the + * machine even from user space. + */ + +static void __init check_popad(void) +{ +#ifndef CONFIG_X86_POPAD_OK + int res, inp = (int) &res; + + printk(KERN_INFO "Checking for popad bug... "); + __asm__ __volatile__( + "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " + : "=&a" (res) + : "d" (inp) + : "ecx", "edi" ); + /* If this fails, it means that any user program may lock the CPU hard. Too bad. */ + if (res != 12345678) printk( "Buggy.\n" ); + else printk( "OK.\n" ); +#endif +} + +/* + * Check whether we are able to run this kernel safely on SMP. + * + * - In order to run on a i386, we need to be compiled for i386 + * (for due to lack of "invlpg" and working WP on a i386) + * - In order to run on anything without a TSC, we need to be + * compiled for a i486. + * - In order to support the local APIC on a buggy Pentium machine, + * we need to be compiled with CONFIG_X86_GOOD_APIC disabled, + * which happens implicitly if compiled for a Pentium or lower + * (unless an advanced selection of CPU features is used) as an + * otherwise config implies a properly working local APIC without + * the need to do extra reads from the APIC. +*/ + +static void __init check_config(void) +{ +/* + * We'd better not be a i386 if we're configured to use some + * i486+ only features! (WP works in supervisor mode and the + * new "invlpg" and "bswap" instructions) + */ +#if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_BSWAP) + if (boot_cpu_data.x86 == 3) + panic("Kernel requires i486+ for 'invlpg' and other features"); +#endif + +/* + * If we configured ourselves for a TSC, we'd better have one! + */ +#ifdef CONFIG_X86_TSC + if (!cpu_has_tsc) + panic("Kernel compiled for Pentium+, requires TSC feature!"); +#endif + +/* + * If we configured ourselves for PGE, we'd better have it. + */ +#ifdef CONFIG_X86_PGE + if (!cpu_has_pge) + panic("Kernel compiled for PPro+, requires PGE feature!"); +#endif + +/* + * If we were told we had a good local APIC, check for buggy Pentia, + * i.e. all B steppings and the C2 stepping of P54C when using their + * integrated APIC (see 11AP erratum in "Pentium Processor + * Specification Update"). + */ +#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC) + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL + && test_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability) + && boot_cpu_data.x86 == 5 + && boot_cpu_data.x86_model == 2 + && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11)) + panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!"); +#endif +} + +static void __init check_bugs(void) +{ + extern void __init boot_init_fpu(void); + + identify_cpu(&boot_cpu_data); + boot_init_fpu(); +#ifndef CONFIG_SMP + printk("CPU: "); + print_cpu_info(&boot_cpu_data); +#endif + check_config(); + check_fpu(); + check_hlt(); + check_popad(); + system_utsname.machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); +} diff -ruN linux-2.4.23-pre6/include/asm/byteorder.h linux-2.4.23-pre6-swsusp/include/asm/byteorder.h --- linux-2.4.23-pre6/include/asm/byteorder.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/byteorder.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,67 @@ +#ifndef _I386_BYTEORDER_H +#define _I386_BYTEORDER_H + +#include + +#ifdef __GNUC__ + +/* For avoiding bswap on i386 */ +#ifdef __KERNEL__ +#include +#endif + +static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +{ +#ifdef CONFIG_X86_BSWAP + __asm__("bswap %0" : "=r" (x) : "0" (x)); +#else + __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %b0,%h0" /* swap higher bytes */ + :"=q" (x) + : "0" (x)); +#endif + return x; +} + +/* gcc should generate this for open coded C now too. May be worth switching to + it because inline assembly cannot be scheduled. -AK */ +static __inline__ __const__ __u16 ___arch__swab16(__u16 x) +{ + __asm__("xchgb %b0,%h0" /* swap bytes */ + : "=q" (x) + : "0" (x)); + return x; +} + + +static inline __u64 ___arch__swab64(__u64 val) +{ + union { + struct { __u32 a,b; } s; + __u64 u; + } v; + v.u = val; +#ifdef CONFIG_X86_BSWAP + asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r" (v.s.a), "=r" (v.s.b) + : "0" (v.s.a), "1" (v.s.b)); +#else + v.s.a = ___arch__swab32(v.s.a); + v.s.b = ___arch__swab32(v.s.b); + asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); +#endif + return v.u; +} + +#define __arch__swab64(x) ___arch__swab64(x) +#define __arch__swab32(x) ___arch__swab32(x) +#define __arch__swab16(x) ___arch__swab16(x) + +#define __BYTEORDER_HAS_U64__ + +#endif /* __GNUC__ */ + +#include + +#endif /* _I386_BYTEORDER_H */ diff -ruN linux-2.4.23-pre6/include/asm/cache.h linux-2.4.23-pre6-swsusp/include/asm/cache.h --- linux-2.4.23-pre6/include/asm/cache.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/cache.h 2001-11-23 04:46:18.000000000 +0900 @@ -0,0 +1,13 @@ +/* + * include/asm-i386/cache.h + */ +#ifndef __ARCH_I386_CACHE_H +#define __ARCH_I386_CACHE_H + +#include + +/* L1 cache line size */ +#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/checksum.h linux-2.4.23-pre6-swsusp/include/asm/checksum.h --- linux-2.4.23-pre6/include/asm/checksum.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/checksum.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,195 @@ +#ifndef _I386_CHECKSUM_H +#define _I386_CHECKSUM_H + + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +asmlinkage unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums, and handles user-space pointer exceptions correctly, when needed. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum, + int *src_err_ptr, int *dst_err_ptr); + +/* + * Note: when you get a NULL pointer exception here this means someone + * passed in an incorrect kernel address to one of these functions. + * + * If you use these functions directly please don't forget the + * verify_area(). + */ +static __inline__ +unsigned int csum_partial_copy_nocheck ( const char *src, char *dst, + int len, int sum) +{ + return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL); +} + +static __inline__ +unsigned int csum_partial_copy_from_user ( const char *src, char *dst, + int len, int sum, int *err_ptr) +{ + return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL); +} + +/* + * These are the old (and unsafe) way of doing checksums, a warning message will be + * printed if they are used and an exeption occurs. + * + * these functions should go away after some time. + */ + +#define csum_partial_copy_fromuser csum_partial_copy +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum); + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + * By Jorge Cwik , adapted for linux by + * Arnt Gulbrandsen. + */ +static inline unsigned short ip_fast_csum(unsigned char * iph, + unsigned int ihl) +{ + unsigned int sum; + + __asm__ __volatile__( + "movl (%1), %0 ;\n" + "subl $4, %2 ;\n" + "jbe 2f ;\n" + "addl 4(%1), %0 ;\n" + "adcl 8(%1), %0 ;\n" + "adcl 12(%1), %0 ;\n" +"1: adcl 16(%1), %0 ;\n" + "lea 4(%1), %1 ;\n" + "decl %2 ;\n" + "jne 1b ;\n" + "adcl $0, %0 ;\n" + "movl %0, %2 ;\n" + "shrl $16, %0 ;\n" + "addw %w2, %w0 ;\n" + "adcl $0, %0 ;\n" + "notl %0 ;\n" +"2: ;\n" + /* Since the input registers which are loaded with iph and ipl + are modified, we must also specify them as outputs, or gcc + will assume they contain their original values. */ + : "=r" (sum), "=r" (iph), "=r" (ihl) + : "1" (iph), "2" (ihl)); + return(sum); +} + +/* + * Fold a partial checksum + */ + +static inline unsigned int csum_fold(unsigned int sum) +{ + __asm__( + "addl %1, %0 ;\n" + "adcl $0xffff, %0 ;\n" + : "=r" (sum) + : "r" (sum << 16), "0" (sum & 0xffff0000) + ); + return (~sum) >> 16; +} + +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) +{ + __asm__( + "addl %1, %0 ;\n" + "adcl %2, %0 ;\n" + "adcl %3, %0 ;\n" + "adcl $0, %0 ;\n" + : "=r" (sum) + : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum)); + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline unsigned short ip_compute_csum(unsigned char * buff, int len) +{ + return csum_fold (csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u32 len, + unsigned short proto, + unsigned int sum) +{ + __asm__( + "addl 0(%1), %0 ;\n" + "adcl 4(%1), %0 ;\n" + "adcl 8(%1), %0 ;\n" + "adcl 12(%1), %0 ;\n" + "adcl 0(%2), %0 ;\n" + "adcl 4(%2), %0 ;\n" + "adcl 8(%2), %0 ;\n" + "adcl 12(%2), %0 ;\n" + "adcl %3, %0 ;\n" + "adcl %4, %0 ;\n" + "adcl $0, %0 ;\n" + : "=&r" (sum) + : "r" (saddr), "r" (daddr), + "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); + + return csum_fold(sum); +} + +/* + * Copy and checksum to user + */ +#define HAVE_CSUM_COPY_USER +static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst, + int len, int sum, int *err_ptr) +{ + if (access_ok(VERIFY_WRITE, dst, len)) + return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr); + + if (len) + *err_ptr = -EFAULT; + + return -1; /* invalid checksum */ +} + +#endif diff -ruN linux-2.4.23-pre6/include/asm/cobalt.h linux-2.4.23-pre6-swsusp/include/asm/cobalt.h --- linux-2.4.23-pre6/include/asm/cobalt.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/cobalt.h 2001-07-27 05:41:22.000000000 +0900 @@ -0,0 +1,117 @@ +#include +#ifndef __I386_COBALT_H +#define __I386_COBALT_H + +/* + * Cobalt is the system ASIC on the SGI 320 and 540 Visual Workstations + */ + +#define CO_CPU_PHYS 0xc2000000 +#define CO_APIC_PHYS 0xc4000000 + +/* see set_fixmap() and asm/fixmap.h */ +#define CO_CPU_VADDR (fix_to_virt(FIX_CO_CPU)) +#define CO_APIC_VADDR (fix_to_virt(FIX_CO_APIC)) + +/* Cobalt CPU registers -- relative to CO_CPU_VADDR, use co_cpu_*() */ +#define CO_CPU_REV 0x08 +#define CO_CPU_CTRL 0x10 +#define CO_CPU_STAT 0x20 +#define CO_CPU_TIMEVAL 0x30 + +/* CO_CPU_CTRL bits */ +#define CO_CTRL_TIMERUN 0x04 /* 0 == disabled */ +#define CO_CTRL_TIMEMASK 0x08 /* 0 == unmasked */ + +/* CO_CPU_STATUS bits */ +#define CO_STAT_TIMEINTR 0x02 /* (r) 1 == int pend, (w) 0 == clear */ + +/* CO_CPU_TIMEVAL value */ +#define CO_TIME_HZ 100000000 /* Cobalt core rate */ + +/* Cobalt APIC registers -- relative to CO_APIC_VADDR, use co_apic_*() */ +#define CO_APIC_HI(n) (((n) * 0x10) + 4) +#define CO_APIC_LO(n) ((n) * 0x10) +#define CO_APIC_ID 0x0ffc + +/* CO_APIC_ID bits */ +#define CO_APIC_ENABLE 0x00000100 + +/* CO_APIC_LO bits */ +#define CO_APIC_LEVEL 0x08000 /* 0 = edge */ + +/* + * Where things are physically wired to Cobalt + * #defines with no board ___ are common to all (thus far) + */ +#define CO_APIC_0_5_IDE0 5 +#define CO_APIC_0_5_SERIAL 13 /* XXX not really...h/w bug! */ +#define CO_APIC_0_5_PARLL 4 +#define CO_APIC_0_5_FLOPPY 6 + +#define CO_APIC_0_6_IDE0 4 +#define CO_APIC_0_6_USB 7 /* PIIX4 USB */ + +#define CO_APIC_1_2_IDE0 4 + +#define CO_APIC_0_5_IDE1 2 +#define CO_APIC_0_6_IDE1 2 + +/* XXX */ +#define CO_APIC_IDE0 CO_APIC_0_5_IDE0 +#define CO_APIC_IDE1 CO_APIC_0_5_IDE1 +#define CO_APIC_SERIAL CO_APIC_0_5_SERIAL +/* XXX */ + +#define CO_APIC_ENET 3 /* Lithium PCI Bridge A, Device 3 */ +#define CO_APIC_8259 12 /* serial, floppy, par-l-l, audio */ + +#define CO_APIC_VIDOUT0 16 +#define CO_APIC_VIDOUT1 17 +#define CO_APIC_VIDIN0 18 +#define CO_APIC_VIDIN1 19 + +#define CO_APIC_CPU 28 /* Timer and Cache interrupt */ + +/* + * This is the "irq" arg to request_irq(), just a unique cookie. + */ +#define CO_IRQ_TIMER 0 +#define CO_IRQ_ENET 3 +#define CO_IRQ_SERIAL 4 +#define CO_IRQ_FLOPPY 6 /* Same as drivers/block/floppy.c:FLOPPY_IRQ */ +#define CO_IRQ_PARLL 7 +#define CO_IRQ_POWER 9 +#define CO_IRQ_IDE 14 +#define CO_IRQ_8259 12 + +#ifdef CONFIG_X86_VISWS_APIC +static __inline void co_cpu_write(unsigned long reg, unsigned long v) +{ + *((volatile unsigned long *)(CO_CPU_VADDR+reg))=v; +} + +static __inline unsigned long co_cpu_read(unsigned long reg) +{ + return *((volatile unsigned long *)(CO_CPU_VADDR+reg)); +} + +static __inline void co_apic_write(unsigned long reg, unsigned long v) +{ + *((volatile unsigned long *)(CO_APIC_VADDR+reg))=v; +} + +static __inline unsigned long co_apic_read(unsigned long reg) +{ + return *((volatile unsigned long *)(CO_APIC_VADDR+reg)); +} +#endif + +extern char visws_board_type; + +#define VISWS_320 0 +#define VISWS_540 1 + +extern char visws_board_rev; + +#endif diff -ruN linux-2.4.23-pre6/include/asm/cpufeature.h linux-2.4.23-pre6-swsusp/include/asm/cpufeature.h --- linux-2.4.23-pre6/include/asm/cpufeature.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/cpufeature.h 2003-10-05 03:45:24.000000000 +0900 @@ -0,0 +1,112 @@ +/* + * cpufeature.h + * + * Defines x86 CPU feature bits + */ + +#ifndef __ASM_I386_CPUFEATURE_H +#define __ASM_I386_CPUFEATURE_H + +/* Sample usage: CPU_FEATURE_P(cpu.x86_capability, FPU) */ +#define CPU_FEATURE_P(CAP, FEATURE) test_bit(CAP, X86_FEATURE_##FEATURE ##_BIT) + +#define NCAPINTS 6 /* Currently we have 6 32-bit words worth of info */ + +/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ +#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ +#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */ +#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */ +#define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */ +#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */ +#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */ +#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */ +#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */ +#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */ +#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */ +#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */ +#define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */ +#define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */ +#define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */ +#define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ +#define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */ +#define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ +#define X86_FEATURE_PN (0*32+18) /* Processor serial number */ +#define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */ +#define X86_FEATURE_DTES (0*32+21) /* Debug Trace Store */ +#define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ +#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ +#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */ + /* of FPU context), and CR4.OSFXSR available */ +#define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */ +#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */ +#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */ +#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */ +#define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */ +#define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */ + +/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ +/* Don't duplicate feature flags which are redundant with Intel! */ +#define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */ +#define X86_FEATURE_MP (1*32+19) /* MP Capable. */ +#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ +#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ +#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ +#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */ + +/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ +#define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */ +#define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */ +#define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */ + +/* Other features, Linux-defined mapping, word 3 */ +/* This range is used for feature bits which conflict or are synthesized */ +#define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */ +#define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */ +#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */ +#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ +/* cpu types for specific tunings: */ +#define X86_FEATURE_K8 (3*32+ 4) /* Opteron, Athlon64 */ +#define X86_FEATURE_K7 (3*32+ 5) /* Athlon */ +#define X86_FEATURE_P3 (3*32+ 6) /* P3 */ +#define X86_FEATURE_P4 (3*32+ 7) /* P4 */ + +/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ +#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */ + +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ +#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */ + + +#define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) +#define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) + +#define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) +#define cpu_has_vme boot_cpu_has(X86_FEATURE_VME) +#define cpu_has_de boot_cpu_has(X86_FEATURE_DE) +#define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE) +#define cpu_has_pse36 boot_cpu_has(X86_FEATURE_PSE36) +#define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC) +#define cpu_has_pae boot_cpu_has(X86_FEATURE_PAE) +#define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE) +#define cpu_has_sse2 boot_cpu_has(X86_FEATURE_XMM2) +#define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC) +#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP) +#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR) +#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX) +#define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR) +#define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) +#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) +#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP) +#define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR) +#define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR) +#define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR) +#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE) + +#endif /* __ASM_I386_CPUFEATURE_H */ + +/* + * Local Variables: + * mode:c + * comment-column:42 + * End: + */ diff -ruN linux-2.4.23-pre6/include/asm/current.h linux-2.4.23-pre6-swsusp/include/asm/current.h --- linux-2.4.23-pre6/include/asm/current.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/current.h 1998-08-15 08:35:22.000000000 +0900 @@ -0,0 +1,15 @@ +#ifndef _I386_CURRENT_H +#define _I386_CURRENT_H + +struct task_struct; + +static inline struct task_struct * get_current(void) +{ + struct task_struct *current; + __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL)); + return current; + } + +#define current get_current() + +#endif /* !(_I386_CURRENT_H) */ diff -ruN linux-2.4.23-pre6/include/asm/debugreg.h linux-2.4.23-pre6-swsusp/include/asm/debugreg.h --- linux-2.4.23-pre6/include/asm/debugreg.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/debugreg.h 1998-08-01 04:53:37.000000000 +0900 @@ -0,0 +1,64 @@ +#ifndef _I386_DEBUGREG_H +#define _I386_DEBUGREG_H + + +/* Indicate the register numbers for a number of the specific + debug registers. Registers 0-3 contain the addresses we wish to trap on */ +#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */ +#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */ + +#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */ +#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */ + +/* Define a few things for the status register. We can use this to determine + which debugging register was responsible for the trap. The other bits + are either reserved or not of interest to us. */ + +#define DR_TRAP0 (0x1) /* db0 */ +#define DR_TRAP1 (0x2) /* db1 */ +#define DR_TRAP2 (0x4) /* db2 */ +#define DR_TRAP3 (0x8) /* db3 */ + +#define DR_STEP (0x4000) /* single-step */ +#define DR_SWITCH (0x8000) /* task switch */ + +/* Now define a bunch of things for manipulating the control register. + The top two bytes of the control register consist of 4 fields of 4 + bits - each field corresponds to one of the four debug registers, + and indicates what types of access we trap on, and how large the data + field is that we are looking at */ + +#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */ +#define DR_CONTROL_SIZE 4 /* 4 control bits per register */ + +#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */ +#define DR_RW_WRITE (0x1) +#define DR_RW_READ (0x3) + +#define DR_LEN_1 (0x0) /* Settings for data length to trap on */ +#define DR_LEN_2 (0x4) +#define DR_LEN_4 (0xC) + +/* The low byte to the control register determine which registers are + enabled. There are 4 fields of two bits. One bit is "local", meaning + that the processor will reset the bit after a task switch and the other + is global meaning that we have to explicitly reset the bit. With linux, + you can use either one, since we explicitly zero the register when we enter + kernel mode. */ + +#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */ +#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */ +#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */ + +#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */ +#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */ + +/* The second byte to the control register has a few special things. + We can slow the instruction pipeline for instructions coming via the + gdt or the ldt if we want to. I am not sure why this is an advantage */ + +#define DR_CONTROL_RESERVED (0xFC00) /* Reserved by Intel */ +#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */ +#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/delay.h linux-2.4.23-pre6-swsusp/include/asm/delay.h --- linux-2.4.23-pre6/include/asm/delay.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/delay.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,26 @@ +#ifndef _I386_DELAY_H +#define _I386_DELAY_H + +/* + * Copyright (C) 1993 Linus Torvalds + * + * Delay routines calling functions in arch/i386/lib/delay.c + */ + +extern void __bad_udelay(void); +extern void __bad_ndelay(void); + +extern void __udelay(unsigned long usecs); +extern void __ndelay(unsigned long nsecs); +extern void __const_udelay(unsigned long usecs); +extern void __delay(unsigned long loops); + +#define udelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \ + __udelay(n)) + +#define ndelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ + __ndelay(n)) + +#endif /* defined(_I386_DELAY_H) */ diff -ruN linux-2.4.23-pre6/include/asm/desc.h linux-2.4.23-pre6-swsusp/include/asm/desc.h --- linux-2.4.23-pre6/include/asm/desc.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/desc.h 2001-07-27 05:40:32.000000000 +0900 @@ -0,0 +1,99 @@ +#ifndef __ARCH_DESC_H +#define __ARCH_DESC_H + +#include + +/* + * The layout of the GDT under Linux: + * + * 0 - null + * 1 - not used + * 2 - kernel code segment + * 3 - kernel data segment + * 4 - user code segment <-- new cacheline + * 5 - user data segment + * 6 - not used + * 7 - not used + * 8 - APM BIOS support <-- new cacheline + * 9 - APM BIOS support + * 10 - APM BIOS support + * 11 - APM BIOS support + * + * The TSS+LDT descriptors are spread out a bit so that every CPU + * has an exclusive cacheline for the per-CPU TSS and LDT: + * + * 12 - CPU#0 TSS <-- new cacheline + * 13 - CPU#0 LDT + * 14 - not used + * 15 - not used + * 16 - CPU#1 TSS <-- new cacheline + * 17 - CPU#1 LDT + * 18 - not used + * 19 - not used + * ... NR_CPUS per-CPU TSS+LDT's if on SMP + * + * Entry into gdt where to find first TSS. + */ +#define __FIRST_TSS_ENTRY 12 +#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY+1) + +#define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY) +#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY) + +#ifndef __ASSEMBLY__ +struct desc_struct { + unsigned long a,b; +}; + +extern struct desc_struct gdt_table[]; +extern struct desc_struct *idt, *gdt; + +struct Xgt_desc_struct { + unsigned short size; + unsigned long address __attribute__((packed)); +}; + +#define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2)) +#define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2)) + +#define load_TR(n) __asm__ __volatile__("ltr %%ax"::"a" (__TSS(n)<<3)) + +#define __load_LDT(n) __asm__ __volatile__("lldt %%ax"::"a" (__LDT(n)<<3)) + +/* + * This is the ldt that every process will get unless we need + * something other than this. + */ +extern struct desc_struct default_ldt[]; +extern void set_intr_gate(unsigned int irq, void * addr); +extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size); +extern void set_tss_desc(unsigned int n, void *addr); + +static inline void clear_LDT(void) +{ + int cpu = smp_processor_id(); + set_ldt_desc(cpu, &default_ldt[0], 5); + __load_LDT(cpu); +} + +/* + * load one particular LDT into the current CPU + */ +static inline void load_LDT (struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + void *segments = mm->context.segments; + int count = LDT_ENTRIES; + + if (!segments) { + segments = &default_ldt[0]; + count = 5; + } + + set_ldt_desc(cpu, segments, count); + __load_LDT(cpu); +} + +#endif /* !__ASSEMBLY__ */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/div64.h linux-2.4.23-pre6-swsusp/include/asm/div64.h --- linux-2.4.23-pre6/include/asm/div64.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/div64.h 1999-11-09 08:58:38.000000000 +0900 @@ -0,0 +1,17 @@ +#ifndef __I386_DIV64 +#define __I386_DIV64 + +#define do_div(n,base) ({ \ + unsigned long __upper, __low, __high, __mod; \ + asm("":"=a" (__low), "=d" (__high):"A" (n)); \ + __upper = __high; \ + if (__high) { \ + __upper = __high % (base); \ + __high = __high / (base); \ + } \ + asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (base), "0" (__low), "1" (__upper)); \ + asm("":"=A" (n):"a" (__low),"d" (__high)); \ + __mod; \ +}) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/dma.h linux-2.4.23-pre6-swsusp/include/asm/dma.h --- linux-2.4.23-pre6/include/asm/dma.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/dma.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,298 @@ +/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +#ifndef _ASM_DMA_H +#define _ASM_DMA_H + +#include +#include /* And spinlocks */ +#include /* need byte IO */ +#include + + +#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER +#define dma_outb outb_p +#else +#define dma_outb outb +#endif + +#define dma_inb inb + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + +/* The maximum address that we can perform a DMA transfer to on this platform */ +#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG 0x08 /* command register (w) */ +#define DMA1_STAT_REG 0x08 /* status register (r) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ +#define DMA1_MODE_REG 0x0B /* mode register (w) */ +#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ + +#define DMA2_CMD_REG 0xD0 /* command register (w) */ +#define DMA2_STAT_REG 0xD0 /* status register (r) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ +#define DMA2_MODE_REG 0xD6 /* mode register (w) */ +#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +#define DMA_ADDR_0 0x00 /* DMA address registers */ +#define DMA_ADDR_1 0x02 +#define DMA_ADDR_2 0x04 +#define DMA_ADDR_3 0x06 +#define DMA_ADDR_4 0xC0 +#define DMA_ADDR_5 0xC4 +#define DMA_ADDR_6 0xC8 +#define DMA_ADDR_7 0xCC + +#define DMA_CNT_0 0x01 /* DMA count registers */ +#define DMA_CNT_1 0x03 +#define DMA_CNT_2 0x05 +#define DMA_CNT_3 0x07 +#define DMA_CNT_4 0xC2 +#define DMA_CNT_5 0xC6 +#define DMA_CNT_6 0xCA +#define DMA_CNT_7 0xCE + +#define DMA_PAGE_0 0x87 /* DMA page registers */ +#define DMA_PAGE_1 0x83 +#define DMA_PAGE_2 0x81 +#define DMA_PAGE_3 0x82 +#define DMA_PAGE_5 0x8B +#define DMA_PAGE_6 0x89 +#define DMA_PAGE_7 0x8A + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +#define DMA_AUTOINIT 0x10 + + +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr, DMA1_MASK_REG); + else + dma_outb(dmanr & 3, DMA2_MASK_REG); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while holding the DMA lock ! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + switch(dmanr) { + case 0: + dma_outb(pagenr, DMA_PAGE_0); + break; + case 1: + dma_outb(pagenr, DMA_PAGE_1); + break; + case 2: + dma_outb(pagenr, DMA_PAGE_2); + break; + case 3: + dma_outb(pagenr, DMA_PAGE_3); + break; + case 5: + dma_outb(pagenr & 0xfe, DMA_PAGE_5); + break; + case 6: + dma_outb(pagenr & 0xfe, DMA_PAGE_6); + break; + case 7: + dma_outb(pagenr & 0xfe, DMA_PAGE_7); + break; + } +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + set_dma_page(dmanr, a>>16); + if (dmanr <= 3) { + dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* Set transfer size (max 64k for DMA0..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr<=3)? count : (count<<1); +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +/* From PCI */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif + +#endif /* _ASM_DMA_H */ diff -ruN linux-2.4.23-pre6/include/asm/e820.h linux-2.4.23-pre6-swsusp/include/asm/e820.h --- linux-2.4.23-pre6/include/asm/e820.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/e820.h 2000-08-19 01:30:51.000000000 +0900 @@ -0,0 +1,40 @@ +/* + * structures and definitions for the int 15, ax=e820 memory map + * scheme. + * + * In a nutshell, arch/i386/boot/setup.S populates a scratch table + * in the empty_zero_block that contains a list of usable address/size + * duples. In arch/i386/kernel/setup.c, this information is + * transferred into the e820map, and in arch/i386/mm/init.c, that + * new information is used to mark pages reserved or not. + * + */ +#ifndef __E820_HEADER +#define __E820_HEADER + +#define E820MAP 0x2d0 /* our map */ +#define E820MAX 32 /* number of entries in E820MAP */ +#define E820NR 0x1e8 /* # entries in E820MAP */ + +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */ +#define E820_NVS 4 + +#define HIGH_MEMORY (1024*1024) + +#ifndef __ASSEMBLY__ + +struct e820map { + int nr_map; + struct e820entry { + unsigned long long addr; /* start of memory segment */ + unsigned long long size; /* size of memory segment */ + unsigned long type; /* type of memory segment */ + } map[E820MAX]; +}; + +extern struct e820map e820; +#endif/*!__ASSEMBLY__*/ + +#endif/*__E820_HEADER*/ diff -ruN linux-2.4.23-pre6/include/asm/elf.h linux-2.4.23-pre6-swsusp/include/asm/elf.h --- linux-2.4.23-pre6/include/asm/elf.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/elf.h 2001-11-23 04:48:29.000000000 +0900 @@ -0,0 +1,104 @@ +#ifndef __ASMi386_ELF_H +#define __ASMi386_ELF_H + +/* + * ELF register definitions.. + */ + +#include +#include + +#include + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_i387_struct elf_fpregset_t; +typedef struct user_fxsr_struct elf_fpxregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) \ + (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_386 + +/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx + contains a pointer to a function which might be registered using `atexit'. + This provides a mean for the dynamic linker to call DT_FINI functions for + shared libraries that have been loaded before the code runs. + + A value of 0 tells we have no such handler. + + We might as well make sure everything else is cleared too (except for %esp), + just to make things more deterministic. + */ +#define ELF_PLAT_INIT(_r) do { \ + _r->ebx = 0; _r->ecx = 0; _r->edx = 0; \ + _r->esi = 0; _r->edi = 0; _r->ebp = 0; \ + _r->eax = 0; \ +} while (0) + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) + +/* Wow, the "main" arch needs arch dependent functions too.. :) */ + +/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is + now struct_user_regs, they are different) */ + +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ + pr_reg[0] = regs->ebx; \ + pr_reg[1] = regs->ecx; \ + pr_reg[2] = regs->edx; \ + pr_reg[3] = regs->esi; \ + pr_reg[4] = regs->edi; \ + pr_reg[5] = regs->ebp; \ + pr_reg[6] = regs->eax; \ + pr_reg[7] = regs->xds; \ + pr_reg[8] = regs->xes; \ + /* fake once used fs and gs selectors? */ \ + pr_reg[9] = regs->xds; /* was fs and __fs */ \ + pr_reg[10] = regs->xds; /* was gs and __gs */ \ + pr_reg[11] = regs->orig_eax; \ + pr_reg[12] = regs->eip; \ + pr_reg[13] = regs->xcs; \ + pr_reg[14] = regs->eflags; \ + pr_reg[15] = regs->esp; \ + pr_reg[16] = regs->xss; + +/* This yields a mask that user programs can use to figure out what + instruction set this CPU supports. This could be done in user space, + but it's not easy, and we've already done it here. */ + +#define ELF_HWCAP (boot_cpu_data.x86_capability[0]) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. + + For the moment, we have only optimizations for the Intel generations, + but that could change... */ + +#define ELF_PLATFORM (system_utsname.machine) + +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) +#endif + +#endif diff -ruN linux-2.4.23-pre6/include/asm/errno.h linux-2.4.23-pre6-swsusp/include/asm/errno.h --- linux-2.4.23-pre6/include/asm/errno.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/errno.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,132 @@ +#ifndef _I386_ERRNO_H +#define _I386_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/fcntl.h linux-2.4.23-pre6-swsusp/include/asm/fcntl.h --- linux-2.4.23-pre6/include/asm/fcntl.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/fcntl.h 2001-09-18 05:16:30.000000000 +0900 @@ -0,0 +1,87 @@ +#ifndef _I386_FCNTL_H +#define _I386_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define FASYNC 020000 /* fcntl, for BSD compatibility */ +#define O_DIRECT 040000 /* direct disk access hint */ +#define O_LARGEFILE 0100000 +#define O_DIRECTORY 0200000 /* must be a directory */ +#define O_NOFOLLOW 0400000 /* don't follow links */ + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get close_on_exec */ +#define F_SETFD 2 /* set/clear close_on_exec */ +#define F_GETFL 3 /* get file->f_flags */ +#define F_SETFL 4 /* set file->f_flags */ +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ +#define F_SETSIG 10 /* for sockets. */ +#define F_GETSIG 11 /* for sockets. */ + +#define F_GETLK64 12 /* using 'struct flock64' */ +#define F_SETLK64 13 +#define F_SETLKW64 14 + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* for leases */ +#define F_INPROGRESS 16 + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +#define LOCK_MAND 32 /* This is a mandatory flock */ +#define LOCK_READ 64 /* ... Which allows concurrent read operations */ +#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */ +#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +struct flock64 { + short l_type; + short l_whence; + loff_t l_start; + loff_t l_len; + pid_t l_pid; +}; + +#define F_LINUX_SPECIFIC_BASE 1024 + +#endif diff -ruN linux-2.4.23-pre6/include/asm/fixmap.h linux-2.4.23-pre6-swsusp/include/asm/fixmap.h --- linux-2.4.23-pre6/include/asm/fixmap.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/fixmap.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,134 @@ +/* + * fixmap.h: compile-time virtual memory allocation + * + * This file is subject to 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) 1998 Ingo Molnar + * + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 + */ + +#ifndef _ASM_FIXMAP_H +#define _ASM_FIXMAP_H + +#include +#include +#include +#include +#include +#ifdef CONFIG_HIGHMEM +#include +#include +#endif + +/* + * Here we define all the compile-time 'special' virtual + * addresses. The point is to have a constant address at + * compile time, but to set the physical address only + * in the boot process. We allocate these special addresses + * from the end of virtual memory (0xfffff000) backwards. + * Also this lets us do fail-safe vmalloc(), we + * can guarantee that these special addresses and + * vmalloc()-ed addresses never overlap. + * + * these 'compile-time allocated' memory buffers are + * fixed-size 4k pages. (or larger if used with an increment + * highger than 1) use fixmap_set(idx,phys) to associate + * physical memory with fixmap indices. + * + * TLB entries of such buffers will not be flushed across + * task switches. + */ + +/* + * on UP currently we will have no trace of the fixmap mechanizm, + * no page table allocations, etc. This might change in the + * future, say framebuffers for the console driver(s) could be + * fix-mapped? + */ +enum fixed_addresses { +#ifdef CONFIG_X86_LOCAL_APIC + FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ +#endif +#ifdef CONFIG_X86_IO_APIC + FIX_IO_APIC_BASE_0, + FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, +#endif +#ifdef CONFIG_X86_VISWS_APIC + FIX_CO_CPU, /* Cobalt timer */ + FIX_CO_APIC, /* Cobalt APIC Redirection Table */ + FIX_LI_PCIA, /* Lithium PCI Bridge A */ + FIX_LI_PCIB, /* Lithium PCI Bridge B */ +#endif +#ifndef CONFIG_X86_F00F_WORKS_OK + FIX_F00F, +#endif +#ifdef CONFIG_X86_SUMMIT + FIX_CYCLONE_TIMER, /*cyclone timer register*/ +#endif +#ifdef CONFIG_HIGHMEM + FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ + FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, +#endif +#ifdef CONFIG_ACPI_BOOT + FIX_ACPI_BEGIN, + FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, +#endif + __end_of_permanent_fixed_addresses, + /* temporary boot-time mappings, used before ioremap() is functional */ +#define NR_FIX_BTMAPS 16 + FIX_BTMAP_END = __end_of_permanent_fixed_addresses, + FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1, + __end_of_fixed_addresses +}; + +extern void __set_fixmap (enum fixed_addresses idx, + unsigned long phys, pgprot_t flags); + +#define set_fixmap(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL) +/* + * Some hardware wants to get fixmapped without caching. + */ +#define set_fixmap_nocache(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) +/* + * used by vmalloc.c. + * + * Leave one empty page between vmalloc'ed areas and + * the start of the fixmap, and leave one page empty + * at the top of mem.. + */ +#define FIXADDR_TOP (0xffffe000UL) +#define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) +#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) + +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) + +extern void __this_fixmap_does_not_exist(void); + +/* + * 'index to address' translation. If anyone tries to use the idx + * directly without tranlation, we catch the bug with a NULL-deference + * kernel oops. Illegal ranges of incoming indices are caught too. + */ +static inline unsigned long fix_to_virt(const unsigned int idx) +{ + /* + * this branch gets completely eliminated after inlining, + * except when someone tries to use fixaddr indices in an + * illegal way. (such as mixing up address types or using + * out-of-range indices). + * + * If it doesn't get removed, the linker will complain + * loudly with a reasonably clear error message.. + */ + if (idx >= __end_of_fixed_addresses) + __this_fixmap_does_not_exist(); + + return __fix_to_virt(idx); +} + +#endif diff -ruN linux-2.4.23-pre6/include/asm/floppy.h linux-2.4.23-pre6-swsusp/include/asm/floppy.h --- linux-2.4.23-pre6/include/asm/floppy.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/floppy.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,320 @@ +/* + * Architecture specific parts of the Floppy driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 + */ +#ifndef __ASM_I386_FLOPPY_H +#define __ASM_I386_FLOPPY_H + +#include + + +/* + * The DMA channel used by the floppy controller cannot access data at + * addresses >= 16MB + * + * Went back to the 1MB limit, as some people had problems with the floppy + * driver otherwise. It doesn't matter much for performance anyway, as most + * floppy accesses go through the track buffer. + */ +#define _CROSS_64KB(a,s,vdma) \ +(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)) + +#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1) + + +#define SW fd_routine[use_virtual_dma&1] +#define CSW fd_routine[can_use_virtual_dma & 1] + + +#define fd_inb(port) inb_p(port) +#define fd_outb(port,value) outb_p(port,value) + +#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy") +#define fd_free_dma() CSW._free_dma(FLOPPY_DMA) +#define fd_enable_irq() enable_irq(FLOPPY_IRQ) +#define fd_disable_irq() disable_irq(FLOPPY_IRQ) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) +#define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA) +#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size) +#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io) + +#define FLOPPY_CAN_FALLBACK_ON_NODMA + +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) +{ + register unsigned char st; + +#undef TRACE_FLPY_INT +#define NO_FLOPPY_ASSEMBLER + +#ifdef TRACE_FLPY_INT + static int calls=0; + static int bytes=0; + static int dma_wait=0; +#endif + if(!doing_pdma) { + floppy_interrupt(irq, dev_id, regs); + return; + } + +#ifdef TRACE_FLPY_INT + if(!calls) + bytes = virtual_dma_count; +#endif + +#ifndef NO_FLOPPY_ASSEMBLER + __asm__ ( + "testl %1,%1" + "je 3f" +"1: inb %w4,%b0" + "andb $160,%b0" + "cmpb $160,%b0" + "jne 2f" + "incw %w4" + "testl %3,%3" + "jne 4f" + "inb %w4,%b0" + "movb %0,(%2)" + "jmp 5f" +"4: movb (%2),%0" + "outb %b0,%w4" +"5: decw %w4" + "outb %0,$0x80" + "decl %1" + "incl %2" + "testl %1,%1" + "jne 1b" +"3: inb %w4,%b0" +"2: " + : "=a" ((char) st), + "=c" ((long) virtual_dma_count), + "=S" ((long) virtual_dma_addr) + : "b" ((long) virtual_dma_mode), + "d" ((short) virtual_dma_port+4), + "1" ((long) virtual_dma_count), + "2" ((long) virtual_dma_addr)); +#else + { + register int lcount; + register char *lptr; + + st = 1; + for(lcount=virtual_dma_count, lptr=virtual_dma_addr; + lcount; lcount--, lptr++) { + st=inb(virtual_dma_port+4) & 0xa0 ; + if(st != 0xa0) + break; + if(virtual_dma_mode) + outb_p(*lptr, virtual_dma_port+5); + else + *lptr = inb_p(virtual_dma_port+5); + } + virtual_dma_count = lcount; + virtual_dma_addr = lptr; + st = inb(virtual_dma_port+4); + } +#endif + +#ifdef TRACE_FLPY_INT + calls++; +#endif + if(st == 0x20) + return; + if(!(st & 0x20)) { + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; +#ifdef TRACE_FLPY_INT + printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", + virtual_dma_count, virtual_dma_residue, calls, bytes, + dma_wait); + calls = 0; + dma_wait=0; +#endif + doing_pdma = 0; + floppy_interrupt(irq, dev_id, regs); + return; + } +#ifdef TRACE_FLPY_INT + if(!virtual_dma_count) + dma_wait++; +#endif +} + +static void fd_disable_dma(void) +{ + if(! (can_use_virtual_dma & 1)) + disable_dma(FLOPPY_DMA); + doing_pdma = 0; + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; +} + +static int vdma_request_dma(unsigned int dmanr, const char * device_id) +{ + return 0; +} + +static void vdma_nop(unsigned int dummy) +{ +} + + +static int vdma_get_dma_residue(unsigned int dummy) +{ + return virtual_dma_count + virtual_dma_residue; +} + + +static int fd_request_irq(void) +{ + if(can_use_virtual_dma) + return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT, + "floppy", NULL); + else + return request_irq(FLOPPY_IRQ, floppy_interrupt, + SA_INTERRUPT|SA_SAMPLE_RANDOM, + "floppy", NULL); + +} + +static unsigned long dma_mem_alloc(unsigned long size) +{ + return __get_dma_pages(GFP_KERNEL,get_order(size)); +} + + +static unsigned long vdma_mem_alloc(unsigned long size) +{ + return (unsigned long) vmalloc(size); + +} + +#define nodma_mem_alloc(size) vdma_mem_alloc(size) + +static void _fd_dma_mem_free(unsigned long addr, unsigned long size) +{ + if((unsigned int) addr >= (unsigned int) high_memory) + return vfree((void *)addr); + else + free_pages(addr, get_order(size)); +} + +#define fd_dma_mem_free(addr, size) _fd_dma_mem_free(addr, size) + +static void _fd_chose_dma_mode(char *addr, unsigned long size) +{ + if(can_use_virtual_dma == 2) { + if((unsigned int) addr >= (unsigned int) high_memory || + virt_to_bus(addr) >= 0x1000000 || + _CROSS_64KB(addr, size, 0)) + use_virtual_dma = 1; + else + use_virtual_dma = 0; + } else { + use_virtual_dma = can_use_virtual_dma & 1; + } +} + +#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size) + + +static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) +{ + doing_pdma = 1; + virtual_dma_port = io; + virtual_dma_mode = (mode == DMA_MODE_WRITE); + virtual_dma_addr = addr; + virtual_dma_count = size; + virtual_dma_residue = 0; + return 0; +} + +static int hard_dma_setup(char *addr, unsigned long size, int mode, int io) +{ +#ifdef FLOPPY_SANITY_CHECK + if (CROSS_64KB(addr, size)) { + printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size); + return -1; + } +#endif + /* actual, physical DMA */ + doing_pdma = 0; + clear_dma_ff(FLOPPY_DMA); + set_dma_mode(FLOPPY_DMA,mode); + set_dma_addr(FLOPPY_DMA,virt_to_bus(addr)); + set_dma_count(FLOPPY_DMA,size); + enable_dma(FLOPPY_DMA); + return 0; +} + +struct fd_routine_l { + int (*_request_dma)(unsigned int dmanr, const char * device_id); + void (*_free_dma)(unsigned int dmanr); + int (*_get_dma_residue)(unsigned int dummy); + unsigned long (*_dma_mem_alloc) (unsigned long size); + int (*_dma_setup)(char *addr, unsigned long size, int mode, int io); +} fd_routine[] = { + { + request_dma, + free_dma, + get_dma_residue, + dma_mem_alloc, + hard_dma_setup + }, + { + vdma_request_dma, + vdma_nop, + vdma_get_dma_residue, + vdma_mem_alloc, + vdma_dma_setup + } +}; + + +static int FDC1 = 0x3f0; +static int FDC2 = -1; + +/* + * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock + * is needed to prevent corrupted CMOS RAM in case "insmod floppy" + * coincides with another rtc CMOS user. Paul G. + */ +#define FLOPPY0_TYPE ({ \ + unsigned long flags; \ + unsigned char val; \ + spin_lock_irqsave(&rtc_lock, flags); \ + val = (CMOS_READ(0x10) >> 4) & 15; \ + spin_unlock_irqrestore(&rtc_lock, flags); \ + val; \ +}) + +#define FLOPPY1_TYPE ({ \ + unsigned long flags; \ + unsigned char val; \ + spin_lock_irqsave(&rtc_lock, flags); \ + val = CMOS_READ(0x10) & 15; \ + spin_unlock_irqrestore(&rtc_lock, flags); \ + val; \ +}) + +#define N_FDC 2 +#define N_DRIVE 8 + +#define FLOPPY_MOTOR_MASK 0xf0 + +#define AUTO_DMA + +#define EXTRA_FLOPPY_PARAMS + +#endif /* __ASM_I386_FLOPPY_H */ diff -ruN linux-2.4.23-pre6/include/asm/hardirq.h linux-2.4.23-pre6-swsusp/include/asm/hardirq.h --- linux-2.4.23-pre6/include/asm/hardirq.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/hardirq.h 2003-10-05 03:45:24.000000000 +0900 @@ -0,0 +1,93 @@ +#ifndef __ASM_HARDIRQ_H +#define __ASM_HARDIRQ_H + +#include +#include +#include + +/* assembly code in softirq.h is sensitive to the offsets of these fields */ +typedef struct { + unsigned int __softirq_pending; + unsigned int __local_irq_count; + unsigned int __local_bh_count; + unsigned int __syscall_count; + struct task_struct * __ksoftirqd_task; /* waitqueue is too large */ + unsigned int __nmi_count; /* arch dependent */ +} ____cacheline_aligned irq_cpustat_t; + +#include /* Standard mappings for irq_cpustat_t above */ + +/* + * Are we in an interrupt context? Either doing bottom half + * or hardware interrupt processing? + */ +#define in_interrupt() ({ int __cpu = smp_processor_id(); \ + (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) + +#define in_irq() (local_irq_count(smp_processor_id()) != 0) + +#ifndef CONFIG_SMP + +#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 synchronize_irq() barrier() + +#else + +#include +#include + +extern unsigned char global_irq_holder; +extern unsigned volatile long global_irq_lock; /* long for set_bit -RR */ + +static inline int irqs_running (void) +{ + int i; + + for (i = 0; i < smp_num_cpus; i++) + if (local_irq_count(i)) + return 1; + return 0; +} + +static inline void release_irqlock(int cpu) +{ + /* if we didn't own the irq lock, just ignore.. */ + if (global_irq_holder == (unsigned char) cpu) { + global_irq_holder = NO_PROC_ID; + clear_bit(0,&global_irq_lock); + } +} + +static inline void irq_enter(int cpu, int irq) +{ + ++local_irq_count(cpu); + + smp_mb(); + + while (test_bit(0,&global_irq_lock)) { + cpu_relax(); + } +} + +static inline void irq_exit(int cpu, int irq) +{ + --local_irq_count(cpu); +} + +static inline int hardirq_trylock(int cpu) +{ + return !local_irq_count(cpu) && !test_bit(0,&global_irq_lock); +} + +#define hardirq_endlock(cpu) do { } while (0) + +extern void synchronize_irq(void); + +#endif /* CONFIG_SMP */ + +#endif /* __ASM_HARDIRQ_H */ diff -ruN linux-2.4.23-pre6/include/asm/hdreg.h linux-2.4.23-pre6-swsusp/include/asm/hdreg.h --- linux-2.4.23-pre6/include/asm/hdreg.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/hdreg.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,13 @@ +/* + * linux/include/asm-i386/hdreg.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +#ifndef __ASMi386_HDREG_H +#define __ASMi386_HDREG_H + +//typedef unsigned short ide_ioreg_t; +typedef unsigned long ide_ioreg_t; + +#endif /* __ASMi386_HDREG_H */ diff -ruN linux-2.4.23-pre6/include/asm/highmem.h linux-2.4.23-pre6-swsusp/include/asm/highmem.h --- linux-2.4.23-pre6/include/asm/highmem.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/highmem.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,132 @@ +/* + * highmem.h: virtual kernel memory mappings for high memory + * + * Used in CONFIG_HIGHMEM systems for memory pages which + * are not addressable by direct kernel virtual addresses. + * + * Copyright (C) 1999 Gerhard Wichert, Siemens AG + * Gerhard.Wichert@pdb.siemens.de + * + * + * Redesigned the x86 32-bit VM architecture to deal with + * up to 16 Terabyte physical memory. With current x86 CPUs + * we now support up to 64 Gigabytes physical RAM. + * + * Copyright (C) 1999 Ingo Molnar + */ + +#ifndef _ASM_HIGHMEM_H +#define _ASM_HIGHMEM_H + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_DEBUG_HIGHMEM +#define HIGHMEM_DEBUG 1 +#else +#define HIGHMEM_DEBUG 0 +#endif + +/* declarations for highmem.c */ +extern unsigned long highstart_pfn, highend_pfn; + +extern pte_t *kmap_pte; +extern pgprot_t kmap_prot; +extern pte_t *pkmap_page_table; + +extern void kmap_init(void) __init; + +/* + * Right now we initialize only a single pte table. It can be extended + * easily, subsequent pte tables have to be allocated in one physical + * chunk of RAM. + */ +#define PKMAP_BASE (0xfe000000UL) +#ifdef CONFIG_X86_PAE +#define LAST_PKMAP 512 +#else +#define LAST_PKMAP 1024 +#endif +#define LAST_PKMAP_MASK (LAST_PKMAP-1) +#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) + +extern void * FASTCALL(kmap_high(struct page *page, int nonblocking)); +extern void FASTCALL(kunmap_high(struct page *page)); + +#define kmap(page) __kmap(page, 0) +#define kmap_nonblock(page) __kmap(page, 1) + +static inline void *__kmap(struct page *page, int nonblocking) +{ + if (in_interrupt()) + out_of_line_bug(); + if (page < highmem_start_page) + return page_address(page); + return kmap_high(page, nonblocking); +} + +static inline void kunmap(struct page *page) +{ + if (in_interrupt()) + out_of_line_bug(); + if (page < highmem_start_page) + return; + kunmap_high(page); +} + +/* + * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap + * gives a more generic (and caching) interface. But kmap_atomic can + * be used in IRQ contexts, so in some (very limited) cases we need + * it. + */ +static inline void *kmap_atomic(struct page *page, enum km_type type) +{ + enum fixed_addresses idx; + unsigned long vaddr; + + if (page < highmem_start_page) + return page_address(page); + + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#if HIGHMEM_DEBUG + if (!pte_none(*(kmap_pte-idx))) + out_of_line_bug(); +#endif + set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + __flush_tlb_one(vaddr); + + return (void*) vaddr; +} + +static inline void kunmap_atomic(void *kvaddr, enum km_type type) +{ +#if HIGHMEM_DEBUG + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); + + if (vaddr < FIXADDR_START) // FIXME + return; + + if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) + out_of_line_bug(); + + /* + * force other mappings to Oops if they'll try to access + * this pte without first remap it + */ + pte_clear(kmap_pte-idx); + __flush_tlb_one(vaddr); +#endif +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_HIGHMEM_H */ diff -ruN linux-2.4.23-pre6/include/asm/hw_irq.h linux-2.4.23-pre6-swsusp/include/asm/hw_irq.h --- linux-2.4.23-pre6/include/asm/hw_irq.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/hw_irq.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,225 @@ +#ifndef _ASM_HW_IRQ_H +#define _ASM_HW_IRQ_H + +/* + * linux/include/asm/hw_irq.h + * + * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar + * + * moved some of the old arch/i386/kernel/irq.h to here. VY + * + * IRQ/IPI changes taken from work by Thomas Radke + * + */ + +#include +#include +#include + +/* + * IDT vectors usable for external interrupt sources start + * at 0x20: + */ +#define FIRST_EXTERNAL_VECTOR 0x20 + +#define SYSCALL_VECTOR 0x80 + +/* + * Vectors 0x20-0x2f are used for ISA interrupts. + */ + +/* + * Special IRQ vectors used by the SMP architecture, 0xf0-0xff + * + * some of the following vectors are 'rare', they are merged + * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. + * TLB, reschedule and local APIC vectors are performance-critical. + * + * Vectors 0xf0-0xfa are free (reserved for future Linux use). + */ +#define SPURIOUS_APIC_VECTOR 0xff +#define ERROR_APIC_VECTOR 0xfe +#define INVALIDATE_TLB_VECTOR 0xfd +#define RESCHEDULE_VECTOR 0xfc +#define CALL_FUNCTION_VECTOR 0xfb + +/* + * Local APIC timer IRQ vector is on a different priority level, + * to work around the 'lost local interrupt if more than 2 IRQ + * sources per level' errata. + */ +#define LOCAL_TIMER_VECTOR 0xef + +/* + * First APIC vector available to drivers: (vectors 0x30-0xee) + * we start at 0x31 to spread out vectors evenly between priority + * levels. (0x80 is the syscall vector) + */ +#define FIRST_DEVICE_VECTOR 0x31 +#define FIRST_SYSTEM_VECTOR 0xef + +extern int irq_vector[NR_IRQS]; +#define IO_APIC_VECTOR(irq) irq_vector[irq] + +/* + * Various low-level irq details needed by irq.c, process.c, + * time.c, io_apic.c and smp.c + * + * Interrupt entry/exit code at both C and assembly level + */ + +extern void mask_irq(unsigned int irq); +extern void unmask_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern void enable_8259A_irq(unsigned int irq); +extern int i8259A_irq_pending(unsigned int irq); +extern void make_8259A_irq(unsigned int irq); +extern void init_8259A(int aeoi); +extern void FASTCALL(send_IPI_self(int vector)); +extern void init_VISWS_APIC_irqs(void); +extern void setup_IO_APIC(void); +extern void disable_IO_APIC(void); +extern void print_IO_APIC(void); +extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); +extern void send_IPI(int dest, int vector); + +extern unsigned long io_apic_irqs; + +extern atomic_t irq_err_count; +extern atomic_t irq_mis_count; + +extern char _stext, _etext; + +#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) + +#define __STR(x) #x +#define STR(x) __STR(x) + +#define SAVE_ALL \ + "cld\n\t" \ + "pushl %es\n\t" \ + "pushl %ds\n\t" \ + "pushl %eax\n\t" \ + "pushl %ebp\n\t" \ + "pushl %edi\n\t" \ + "pushl %esi\n\t" \ + "pushl %edx\n\t" \ + "pushl %ecx\n\t" \ + "pushl %ebx\n\t" \ + "movl $" STR(__KERNEL_DS) ",%edx\n\t" \ + "movl %edx,%ds\n\t" \ + "movl %edx,%es\n\t" + +#define IRQ_NAME2(nr) nr##_interrupt(void) +#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) + +#define GET_CURRENT \ + "movl %esp, %ebx\n\t" \ + "andl $-8192, %ebx\n\t" + +/* + * SMP has a few special interrupts for IPI messages + */ + + /* there is a second layer of macro just to get the symbolic + name for the vector evaluated. This change is for RTLinux */ +#define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v) +#define XBUILD_SMP_INTERRUPT(x,v)\ +asmlinkage void x(void); \ +asmlinkage void call_##x(void); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(x) ":\n\t" \ + "pushl $"#v"-256\n\t" \ + SAVE_ALL \ + SYMBOL_NAME_STR(call_##x)":\n\t" \ + "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ + "jmp ret_from_intr\n"); + +#define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v) +#define XBUILD_SMP_TIMER_INTERRUPT(x,v) \ +asmlinkage void x(struct pt_regs * regs); \ +asmlinkage void call_##x(void); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(x) ":\n\t" \ + "pushl $"#v"-256\n\t" \ + SAVE_ALL \ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ + SYMBOL_NAME_STR(call_##x)":\n\t" \ + "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ + "addl $4,%esp\n\t" \ + "jmp ret_from_intr\n"); + +#define BUILD_COMMON_IRQ() \ +asmlinkage void call_do_IRQ(void); \ +__asm__( \ + "\n" __ALIGN_STR"\n" \ + "common_interrupt:\n\t" \ + SAVE_ALL \ + SYMBOL_NAME_STR(call_do_IRQ)":\n\t" \ + "call " SYMBOL_NAME_STR(do_IRQ) "\n\t" \ + "jmp ret_from_intr\n"); + +/* + * subtle. orig_eax is used by the signal code to distinct between + * system calls and interrupted 'random user-space'. Thus we have + * to put a negative value into orig_eax here. (the problem is that + * both system calls and IRQs want to have small integer numbers in + * orig_eax, and the syscall code has won the optimization conflict ;) + * + * Subtle as a pigs ear. VY + */ + +#define BUILD_IRQ(nr) \ +asmlinkage void IRQ_NAME(nr); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ + "pushl $"#nr"-256\n\t" \ + "jmp common_interrupt"); + +extern unsigned long prof_cpu_mask; +extern unsigned int * prof_buffer; +extern unsigned long prof_len; +extern unsigned long prof_shift; + +/* + * x86 profiling function, SMP safe. We might want to do this in + * assembly totally? + */ +static inline void x86_do_profile (unsigned long eip) +{ + if (!prof_buffer) + return; + + /* + * Only measure the CPUs specified by /proc/irq/prof_cpu_mask. + * (default is all CPUs.) + */ + if (!((1<>= prof_shift; + /* + * Don't ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (eip > prof_len-1) + eip = prof_len-1; + atomic_inc((atomic_t *)&prof_buffer[eip]); +} + +#if defined(CONFIG_X86_IO_APIC) +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { + if (IO_APIC_IRQ(i)) + send_IPI_self(IO_APIC_VECTOR(i)); +} +#else +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} +#endif + +#endif /* _ASM_HW_IRQ_H */ diff -ruN linux-2.4.23-pre6/include/asm/i387.h linux-2.4.23-pre6-swsusp/include/asm/i387.h --- linux-2.4.23-pre6/include/asm/i387.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/i387.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,89 @@ +/* + * include/asm-i386/i387.h + * + * Copyright (C) 1994 Linus Torvalds + * + * Pentium III FXSR, SSE support + * General FPU state handling cleanups + * Gareth Hughes , May 2000 + */ + +#ifndef __ASM_I386_I387_H +#define __ASM_I386_I387_H + +#include +#include +#include +#include + +extern void init_fpu(void); +/* + * FPU lazy state save handling... + */ +extern void save_init_fpu( struct task_struct *tsk ); +extern void restore_fpu( struct task_struct *tsk ); + +extern void kernel_fpu_begin(void); +#define kernel_fpu_end() stts() + + +#define unlazy_fpu( tsk ) do { \ + if ( tsk->flags & PF_USEDFPU ) \ + save_init_fpu( tsk ); \ +} while (0) + +#define clear_fpu( tsk ) do { \ + if ( tsk->flags & PF_USEDFPU ) { \ + asm volatile("fwait"); \ + tsk->flags &= ~PF_USEDFPU; \ + stts(); \ + } \ +} while (0) + +/* + * FPU state interaction... + */ +extern unsigned short get_fpu_cwd( struct task_struct *tsk ); +extern unsigned short get_fpu_swd( struct task_struct *tsk ); +extern unsigned short get_fpu_twd( struct task_struct *tsk ); +extern unsigned short get_fpu_mxcsr( struct task_struct *tsk ); + +extern void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd ); +extern void set_fpu_swd( struct task_struct *tsk, unsigned short swd ); +extern void set_fpu_twd( struct task_struct *tsk, unsigned short twd ); +extern void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr ); + +#define load_mxcsr( val ) do { \ + unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \ + asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); \ +} while (0) + +/* + * Signal frame handlers... + */ +extern int save_i387( struct _fpstate *buf ); +extern int restore_i387( struct _fpstate *buf ); + +/* + * ptrace request handers... + */ +extern int get_fpregs( struct user_i387_struct *buf, + struct task_struct *tsk ); +extern int set_fpregs( struct task_struct *tsk, + struct user_i387_struct *buf ); + +extern int get_fpxregs( struct user_fxsr_struct *buf, + struct task_struct *tsk ); +extern int set_fpxregs( struct task_struct *tsk, + struct user_fxsr_struct *buf ); +extern void load_empty_fpu(struct task_struct *); + +/* + * FPU state for core dumps... + */ +extern int dump_fpu( struct pt_regs *regs, + struct user_i387_struct *fpu ); +extern int dump_extended_fpu( struct pt_regs *regs, + struct user_fxsr_struct *fpu ); + +#endif /* __ASM_I386_I387_H */ diff -ruN linux-2.4.23-pre6/include/asm/ide.h linux-2.4.23-pre6-swsusp/include/asm/ide.h --- linux-2.4.23-pre6/include/asm/ide.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/ide.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,92 @@ +/* + * linux/include/asm-i386/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* + * This file contains the i386 architecture specific IDE code. + */ + +#ifndef __ASMi386_IDE_H +#define __ASMi386_IDE_H + +#ifdef __KERNEL__ + +#include + +#ifndef MAX_HWIFS +# ifdef CONFIG_BLK_DEV_IDEPCI +#define MAX_HWIFS 10 +# else +#define MAX_HWIFS 6 +# endif +#endif + +static __inline__ int ide_default_irq(ide_ioreg_t base) +{ + switch (base) { + case 0x1f0: return 14; + case 0x170: return 15; + case 0x1e8: return 11; + case 0x168: return 10; + case 0x1e0: return 8; + case 0x160: return 12; + default: + return 0; + } +} + +static __inline__ ide_ioreg_t ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + case 4: return 0x1e0; + case 5: return 0x160; + default: + return 0; + } +} + +static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static __inline__ void ide_init_default_hwifs(void) +{ +#ifndef CONFIG_BLK_DEV_IDEPCI + hw_regs_t hw; + int index; + + for(index = 0; index < MAX_HWIFS; index++) { + memset(&hw, 0, sizeof hw); + ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); + hw.irq = ide_default_irq(ide_default_io_base(index)); + ide_register_hw(&hw, NULL); + } +#endif /* CONFIG_BLK_DEV_IDEPCI */ +} + +#include + +#endif /* __KERNEL__ */ + +#endif /* __ASMi386_IDE_H */ diff -ruN linux-2.4.23-pre6/include/asm/init.h linux-2.4.23-pre6-swsusp/include/asm/init.h --- linux-2.4.23-pre6/include/asm/init.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/init.h 1999-08-04 02:27:39.000000000 +0900 @@ -0,0 +1 @@ +#error " should never be used - use instead" diff -ruN linux-2.4.23-pre6/include/asm/io.h linux-2.4.23-pre6-swsusp/include/asm/io.h --- linux-2.4.23-pre6/include/asm/io.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/io.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,430 @@ +#ifndef _ASM_IO_H +#define _ASM_IO_H + +#include + +/* + * This file contains the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl and the "string versions" of the same + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" + * versions of the single-IO instructions (inb_p/inw_p/..). + * + * This file is not meant to be obfuscating: it's just complicated + * to (a) handle it all in a way that makes gcc able to optimize it + * as well as possible and (b) trying to avoid writing the same thing + * over and over again with slight variations and possibly making a + * mistake somewhere. + */ + +/* + * Thanks to James van Artsdalen for a better timing-fix than + * the two short jumps: using outb's to a nonexistent port seems + * to guarantee better timings even on fast machines. + * + * On the other hand, I'd like to be sure of a non-existent port: + * I feel a bit unsafe about using 0x80 (should be safe, though) + * + * Linus + */ + + /* + * Bit simplified and optimized by Jan Hubicka + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999. + * + * isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added, + * isa_read[wl] and isa_write[wl] fixed + * - Arnaldo Carvalho de Melo + */ + +#define IO_SPACE_LIMIT 0xffff + +#define XQUAD_PORTIO_BASE 0xfe400000 +#define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */ +#define XQUAD_PORTIO_LEN 0x80000 /* Only remapping first 2 quads */ + +#ifdef __KERNEL__ + +#include + +/* + * Temporary debugging check to catch old code using + * unmapped ISA addresses. Will be removed in 2.4. + */ +#if CONFIG_DEBUG_IOVIRT + extern void *__io_virt_debug(unsigned long x, const char *file, int line); + extern unsigned long __io_phys_debug(unsigned long x, const char *file, int line); + #define __io_virt(x) __io_virt_debug((unsigned long)(x), __FILE__, __LINE__) +//#define __io_phys(x) __io_phys_debug((unsigned long)(x), __FILE__, __LINE__) +#else + #define __io_virt(x) ((void *)(x)) +//#define __io_phys(x) __pa(x) +#endif + +/** + * virt_to_phys - map virtual addresses to physical + * @address: address to remap + * + * The returned physical address is the physical (CPU) mapping for + * the memory address given. It is only valid to use this function on + * addresses directly mapped or allocated via kmalloc. + * + * This function does not give bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function + */ + +static inline unsigned long virt_to_phys(volatile void * address) +{ + return __pa(address); +} + +/** + * phys_to_virt - map physical address to virtual + * @address: address to remap + * + * The returned virtual address is a current CPU mapping for + * the memory address given. It is only valid to use this function on + * addresses that have a kernel mapping + * + * This function does not handle bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function + */ + +static inline void * phys_to_virt(unsigned long address) +{ + return __va(address); +} + +/* + * Change "struct page" to physical address. + */ +#ifdef CONFIG_HIGHMEM64G +#define page_to_phys(page) ((u64)(page - mem_map) << PAGE_SHIFT) +#else +#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) +#endif + +extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); + +/** + * ioremap - map bus memory into CPU space + * @offset: bus address of the memory + * @size: size of the resource to map + * + * ioremap performs a platform specific sequence of operations to + * make bus memory CPU accessible via the readb/readw/readl/writeb/ + * writew/writel functions and the other mmio helpers. The returned + * address is not guaranteed to be usable directly as a virtual + * address. + */ + +static inline void * ioremap (unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, 0); +} + +/** + * ioremap_nocache - map bus memory into CPU space + * @offset: bus address of the memory + * @size: size of the resource to map + * + * ioremap_nocache performs a platform specific sequence of operations to + * make bus memory CPU accessible via the readb/readw/readl/writeb/ + * writew/writel functions and the other mmio helpers. The returned + * address is not guaranteed to be usable directly as a virtual + * address. + * + * This version of ioremap ensures that the memory is marked uncachable + * on the CPU as well as honouring existing caching rules from things like + * the PCI bus. Note that there are other caches and buffers on many + * busses. In paticular driver authors should read up on PCI writes + * + * It's useful if some control registers are in such an area and + * write combining or read caching is not desirable: + */ + +static inline void * ioremap_nocache (unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, _PAGE_PCD); +} + +extern void iounmap(void *addr); + +/* + * bt_ioremap() and bt_iounmap() are for temporary early boot-time + * mappings, before the real ioremap() is functional. + * A boot-time mapping is currently limited to at most 16 pages. + */ +extern void *bt_ioremap(unsigned long offset, unsigned long size); +extern void bt_iounmap(void *addr, unsigned long size); + +/* + * IO bus memory addresses are also 1:1 with the physical address + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt +#define page_to_bus page_to_phys + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + */ + +#define readb(addr) (*(volatile unsigned char *) __io_virt(addr)) +#define readw(addr) (*(volatile unsigned short *) __io_virt(addr)) +#define readl(addr) (*(volatile unsigned int *) __io_virt(addr)) +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl + +#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) +#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) +#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel + +#define memset_io(a,b,c) __memset(__io_virt(a),(b),(c)) +#define memcpy_fromio(a,b,c) __memcpy((a),__io_virt(b),(c)) +#define memcpy_toio(a,b,c) __memcpy(__io_virt(a),(b),(c)) + +/* + * ISA space is 'always mapped' on a typical x86 system, no need to + * explicitly ioremap() it. The fact that the ISA IO space is mapped + * to PAGE_OFFSET is pure coincidence - it does not mean ISA values + * are physical addresses. The following constant pointer can be + * used as the IO-area pointer (it can be iounmapped as well, so the + * analogy with PCI is quite large): + */ +#define __ISA_IO_base ((char *)(PAGE_OFFSET)) + +#define isa_readb(a) readb(__ISA_IO_base + (a)) +#define isa_readw(a) readw(__ISA_IO_base + (a)) +#define isa_readl(a) readl(__ISA_IO_base + (a)) +#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a)) +#define isa_writew(w,a) writew(w,__ISA_IO_base + (a)) +#define isa_writel(l,a) writel(l,__ISA_IO_base + (a)) +#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c)) + + +/* + * Again, i386 does not require mem IO specific function. + */ + +#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d)) +#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(__ISA_IO_base + (b)),(c),(d)) + +/** + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the mmio address io_addr. This + * address should have been obtained by ioremap. + * Returns 1 on a match. + */ + +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +/** + * isa_check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the ISA mmio address io_addr. + * Returns 1 on a match. + * + * This function is deprecated. New drivers should use ioremap and + * check_signature. + */ + + +static inline int isa_check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (isa_readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +/* + * Cache management + * + * This needed for two cases + * 1. Out of order aware processors + * 2. Accidentally out of order processors (PPro errata #51) + */ + +#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE) + +static inline void flush_write_buffers(void) +{ + __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory"); +} + +#define dma_cache_inv(_start,_size) flush_write_buffers() +#define dma_cache_wback(_start,_size) flush_write_buffers() +#define dma_cache_wback_inv(_start,_size) flush_write_buffers() + +#else + +/* Nothing to do */ + +#define dma_cache_inv(_start,_size) do { } while (0) +#define dma_cache_wback(_start,_size) do { } while (0) +#define dma_cache_wback_inv(_start,_size) do { } while (0) +#define flush_write_buffers() + +#endif + +#endif /* __KERNEL__ */ + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" +#else +#define __SLOW_DOWN_IO "\noutb %%al,$0x80" +#endif + +#ifdef REALLY_SLOW_IO +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#else +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + +#ifdef CONFIG_MULTIQUAD +extern void *xquad_portio; /* Where the IO area was mapped */ +#endif /* CONFIG_MULTIQUAD */ + +/* + * Talk about misusing macros.. + */ +#define __OUT1(s,x) \ +static inline void out##s(unsigned x value, unsigned short port) { + +#define __OUT2(s,s1,s2) \ +__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" + +#if defined (CONFIG_MULTIQUAD) && !defined(STANDALONE) +#define __OUTQ(s,ss,x) /* Do the equivalent of the portio op on quads */ \ +static inline void out##ss(unsigned x value, unsigned short port) { \ + if (xquad_portio) \ + write##s(value, (unsigned long) xquad_portio + port); \ + else /* We're still in early boot, running on quad 0 */ \ + out##ss##_local(value, port); \ +} \ +static inline void out##ss##_quad(unsigned x value, unsigned short port, int quad) { \ + if (xquad_portio) \ + write##s(value, (unsigned long) xquad_portio + (XQUAD_PORTIO_QUAD*quad)\ + + port); \ +} + +#define __INQ(s,ss) /* Do the equivalent of the portio op on quads */ \ +static inline RETURN_TYPE in##ss(unsigned short port) { \ + if (xquad_portio) \ + return read##s((unsigned long) xquad_portio + port); \ + else /* We're still in early boot, running on quad 0 */ \ + return in##ss##_local(port); \ +} \ +static inline RETURN_TYPE in##ss##_quad(unsigned short port, int quad) { \ + if (xquad_portio) \ + return read##s((unsigned long) xquad_portio + (XQUAD_PORTIO_QUAD*quad)\ + + port); \ + else\ + return 0;\ +} +#endif /* CONFIG_MULTIQUAD && !STANDALONE */ + +#if !defined(CONFIG_MULTIQUAD) || defined(STANDALONE) +#define __OUT(s,s1,x) \ +__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ +__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} +#else +/* Make the default portio routines operate on quad 0 */ +#define __OUT(s,s1,x) \ +__OUT1(s##_local,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ +__OUT1(s##_p_local,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \ +__OUTQ(s,s,x) \ +__OUTQ(s,s##_p,x) +#endif /* !CONFIG_MULTIQUAD || STANDALONE */ + +#define __IN1(s) \ +static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; + +#define __IN2(s,s1,s2) \ +__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" + +#if !defined(CONFIG_MULTIQUAD) || defined(STANDALONE) +#define __IN(s,s1,i...) \ +__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } +#else +/* Make the default portio routines operate on quad 0 */ +#define __IN(s,s1,i...) \ +__IN1(s##_local) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__IN1(s##_p_local) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__INQ(s,s) \ +__INQ(s,s##_p) +#endif /* !CONFIG_MULTIQUAD || STANDALONE */ + +#define __INS(s) \ +static inline void ins##s(unsigned short port, void * addr, unsigned long count) \ +{ __asm__ __volatile__ ("rep ; ins" #s \ +: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } + +#define __OUTS(s) \ +static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \ +{ __asm__ __volatile__ ("rep ; outs" #s \ +: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } + +#define RETURN_TYPE unsigned char +__IN(b,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned short +__IN(w,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned int +__IN(l,"") +#undef RETURN_TYPE + +__OUT(b,"b",char) +__OUT(w,"w",short) +__OUT(l,,int) + +__INS(b) +__INS(w) +__INS(l) + +__OUTS(b) +__OUTS(w) +__OUTS(l) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/io_apic.h linux-2.4.23-pre6-swsusp/include/asm/io_apic.h --- linux-2.4.23-pre6/include/asm/io_apic.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/io_apic.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,154 @@ +#ifndef __ASM_IO_APIC_H +#define __ASM_IO_APIC_H + +#include +#include + +/* + * Intel IO-APIC support for SMP and UP systems. + * + * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar + */ + +#ifdef CONFIG_X86_IO_APIC + +#define APIC_MISMATCH_DEBUG + +#define IO_APIC_BASE(idx) \ + ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \ + + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK))) + +/* + * The structure of the IO-APIC: + */ +struct IO_APIC_reg_00 { + __u32 __reserved_2 : 14, + LTS : 1, + delivery_type : 1, + __reserved_1 : 8, + ID : 4, + __reserved_0 : 4; +} __attribute__ ((packed)); + +struct IO_APIC_reg_01 { + __u32 version : 8, + __reserved_2 : 7, + PRQ : 1, + entries : 8, + __reserved_1 : 8; +} __attribute__ ((packed)); + +struct IO_APIC_reg_02 { + __u32 __reserved_2 : 24, + arbitration : 4, + __reserved_1 : 4; +} __attribute__ ((packed)); + +struct IO_APIC_reg_03 { + __u32 boot_DT : 1, + __reserved_1 : 31; +} __attribute__ ((packed)); + +/* + * # of IO-APICs and # of IRQ routing registers + */ +extern int nr_ioapics; +extern int nr_ioapic_registers[MAX_IO_APICS]; + +enum ioapic_irq_destination_types { + dest_Fixed = 0, + dest_LowestPrio = 1, + dest_SMI = 2, + dest__reserved_1 = 3, + dest_NMI = 4, + dest_INIT = 5, + dest__reserved_2 = 6, + dest_ExtINT = 7 +}; + +struct IO_APIC_route_entry { + __u32 vector : 8, + delivery_mode : 3, /* 000: FIXED + * 001: lowest prio + * 111: ExtINT + */ + dest_mode : 1, /* 0: physical, 1: logical */ + delivery_status : 1, + polarity : 1, + irr : 1, + trigger : 1, /* 0: edge, 1: level */ + mask : 1, /* 0: enabled, 1: disabled */ + __reserved_2 : 15; + + union { struct { __u32 + __reserved_1 : 24, + physical_dest : 4, + __reserved_2 : 4; + } physical; + + struct { __u32 + __reserved_1 : 24, + logical_dest : 8; + } logical; + } dest; + +} __attribute__ ((packed)); + +/* + * MP-BIOS irq configuration table structures: + */ + +/* I/O APIC entries */ +extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; + +/* # of MP IRQ source entries */ +extern int mp_irq_entries; + +/* MP IRQ source entries */ +extern struct mpc_config_intsrc *mp_irqs; + +/* non-0 if default (table-less) MP configuration */ +extern int mpc_default_type; + +static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) +{ + *IO_APIC_BASE(apic) = reg; + return *(IO_APIC_BASE(apic)+4); +} + +static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + *IO_APIC_BASE(apic) = reg; + *(IO_APIC_BASE(apic)+4) = value; +} + +/* + * Synchronize the IO-APIC and the CPU by doing + * a dummy read from the IO-APIC + */ +static inline void io_apic_sync(unsigned int apic) +{ + (void) *(IO_APIC_BASE(apic)+4); +} + +/* 1 if "noapic" boot option passed */ +extern int skip_ioapic_setup; + +/* + * If we use the IO-APIC for IRQ routing, disable automatic + * assignment of PCI IRQ's. + */ +#define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup) + +#ifdef CONFIG_ACPI_BOOT +extern int io_apic_get_unique_id (int ioapic, int apic_id); +extern int io_apic_get_version (int ioapic); +extern int io_apic_get_redir_entries (int ioapic); +extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low); +#endif + +#else /* !CONFIG_X86_IO_APIC */ +#define io_apic_assign_pci_irqs 0 +#endif + +#endif diff -ruN linux-2.4.23-pre6/include/asm/ioctl.h linux-2.4.23-pre6-swsusp/include/asm/ioctl.h --- linux-2.4.23-pre6/include/asm/ioctl.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/ioctl.h 1995-11-15 16:15:02.000000000 +0900 @@ -0,0 +1,75 @@ +/* $Id: ioctl.h,v 1.5 1993/07/19 21:53:50 root Exp root $ + * + * linux/ioctl.h for Linux by H.H. Bergman. + */ + +#ifndef _ASMI386_IOCTL_H +#define _ASMI386_IOCTL_H + +/* ioctl command encoding: 32 bits total, command in lower 16 bits, + * size of the parameter structure in the lower 14 bits of the + * upper 16 bits. + * Encoding the size of the parameter structure in the ioctl request + * is useful for catching programs compiled with old versions + * and to avoid overwriting user space outside the user buffer area. + * The highest 2 bits are reserved for indicating the ``access mode''. + * NOTE: This limits the max parameter size to 16kB -1 ! + */ + +/* + * The following is for compatibility across the various Linux + * platforms. The i386 ioctl numbering scheme doesn't really enforce + * a type field. De facto, however, the top 8 bits of the lower 16 + * bits are indeed used as a type field, so we might just as well make + * this explicit here. Please be sure to use the decoding macros + * below from now on. + */ +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits. + */ +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _ASMI386_IOCTL_H */ diff -ruN linux-2.4.23-pre6/include/asm/ioctls.h linux-2.4.23-pre6-swsusp/include/asm/ioctls.h --- linux-2.4.23-pre6/include/asm/ioctls.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/ioctls.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,83 @@ +#ifndef __ARCH_I386_IOCTLS_H__ +#define __ARCH_I386_IOCTLS_H__ + +#include + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */ +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ +#define FIOQSIZE 0x5460 + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/ipc.h linux-2.4.23-pre6-swsusp/include/asm/ipc.h --- linux-2.4.23-pre6/include/asm/ipc.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/ipc.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,32 @@ +#ifndef __i386_IPC_H__ +#define __i386_IPC_H__ + +/* + * These are used to wrap system calls on x86. + * + * See arch/i386/kernel/sys_i386.c for ugly details.. + */ +struct ipc_kludge { + struct msgbuf *msgp; + long msgtyp; +}; + +#define SEMOP 1 +#define SEMGET 2 +#define SEMCTL 3 +#define SEMTIMEDOP 4 +#define MSGSND 11 +#define MSGRCV 12 +#define MSGGET 13 +#define MSGCTL 14 +#define SHMAT 21 +#define SHMDT 22 +#define SHMGET 23 +#define SHMCTL 24 + +/* Used by the DIPC package, try and avoid reusing it */ +#define DIPC 25 + +#define IPCCALL(version,op) ((version)<<16 | (op)) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/ipcbuf.h linux-2.4.23-pre6-swsusp/include/asm/ipcbuf.h --- linux-2.4.23-pre6/include/asm/ipcbuf.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/ipcbuf.h 2000-01-11 11:15:58.000000000 +0900 @@ -0,0 +1,29 @@ +#ifndef __i386_IPCBUF_H__ +#define __i386_IPCBUF_H__ + +/* + * The ipc64_perm structure for i386 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* __i386_IPCBUF_H__ */ diff -ruN linux-2.4.23-pre6/include/asm/irq.h linux-2.4.23-pre6-swsusp/include/asm/irq.h --- linux-2.4.23-pre6/include/asm/irq.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/irq.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,46 @@ +#ifndef _ASM_IRQ_H +#define _ASM_IRQ_H + +/* + * linux/include/asm/irq.h + * + * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar + * + * IRQ/IPI changes taken from work by Thomas Radke + * + */ + +#include + +#define TIMER_IRQ 0 + +/* + * 16 8259A IRQ's, 208 potential APIC interrupt sources. + * Right now the APIC is mostly only used for SMP. + * 256 vectors is an architectural limit. (we can have + * more than 256 devices theoretically, but they will + * have to use shared interrupts) + * Since vectors 0x00-0x1f are used/reserved for the CPU, + * the usable vector space is 0x20-0xff (224 vectors) + */ +#ifdef CONFIG_X86_IO_APIC +#define NR_IRQS 224 +#else +#define NR_IRQS 16 +#endif + +static __inline__ int irq_cannonicalize(int irq) +{ + return ((irq == 2) ? 9 : irq); +} + +extern void disable_irq(unsigned int); +extern void disable_irq_nosync(unsigned int); +extern void enable_irq(unsigned int); +extern void release_x86_irqs(struct task_struct *); + +#ifdef CONFIG_X86_LOCAL_APIC +#define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ +#endif + +#endif /* _ASM_IRQ_H */ diff -ruN linux-2.4.23-pre6/include/asm/keyboard.h linux-2.4.23-pre6-swsusp/include/asm/keyboard.h --- linux-2.4.23-pre6/include/asm/keyboard.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/keyboard.h 2001-11-23 04:47:23.000000000 +0900 @@ -0,0 +1,72 @@ +/* + * linux/include/asm-i386/keyboard.h + * + * Created 3 Nov 1996 by Geert Uytterhoeven + */ + +/* + * This file contains the i386 architecture specific keyboard definitions + */ + +#ifndef _I386_KEYBOARD_H +#define _I386_KEYBOARD_H + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include + +#define KEYBOARD_IRQ 1 +#define DISABLE_KBD_DURING_INTERRUPTS 0 + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *); +extern pm_callback pm_kbd_request_override; +extern unsigned char pckbd_sysrq_xlate[128]; + +#define kbd_setkeycode pckbd_setkeycode +#define kbd_getkeycode pckbd_getkeycode +#define kbd_translate pckbd_translate +#define kbd_unexpected_up pckbd_unexpected_up +#define kbd_leds pckbd_leds +#define kbd_init_hw pckbd_init_hw +#define kbd_sysrq_xlate pckbd_sysrq_xlate + +#define SYSRQ_KEY 0x54 + +/* resource allocation */ +#define kbd_request_region() +#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \ + "keyboard", NULL) + +/* How to access the keyboard macros on this platform. */ +#define kbd_read_input() inb(KBD_DATA_REG) +#define kbd_read_status() inb(KBD_STATUS_REG) +#define kbd_write_output(val) outb(val, KBD_DATA_REG) +#define kbd_write_command(val) outb(val, KBD_CNTL_REG) + +/* Some stoneage hardware needs delays after some operations. */ +#define kbd_pause() do { } while(0) + +/* + * Machine specific bits for the PS/2 driver + */ + +#define AUX_IRQ 12 + +#define aux_request_irq(hand, dev_id) \ + request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) + +#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id) + +#endif /* __KERNEL__ */ +#endif /* _I386_KEYBOARD_H */ diff -ruN linux-2.4.23-pre6/include/asm/kmap_types.h linux-2.4.23-pre6-swsusp/include/asm/kmap_types.h --- linux-2.4.23-pre6/include/asm/kmap_types.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/kmap_types.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,16 @@ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BH_IRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#endif diff -ruN linux-2.4.23-pre6/include/asm/ldt.h linux-2.4.23-pre6-swsusp/include/asm/ldt.h --- linux-2.4.23-pre6/include/asm/ldt.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/ldt.h 1999-07-12 01:11:46.000000000 +0900 @@ -0,0 +1,32 @@ +/* + * ldt.h + * + * Definitions of structures used with the modify_ldt system call. + */ +#ifndef _LINUX_LDT_H +#define _LINUX_LDT_H + +/* Maximum number of LDT entries supported. */ +#define LDT_ENTRIES 8192 +/* The size of each LDT entry. */ +#define LDT_ENTRY_SIZE 8 + +#ifndef __ASSEMBLY__ +struct modify_ldt_ldt_s { + unsigned int entry_number; + unsigned long base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; +}; + +#define MODIFY_LDT_CONTENTS_DATA 0 +#define MODIFY_LDT_CONTENTS_STACK 1 +#define MODIFY_LDT_CONTENTS_CODE 2 + +#endif /* !__ASSEMBLY__ */ +#endif diff -ruN linux-2.4.23-pre6/include/asm/linux_logo.h linux-2.4.23-pre6-swsusp/include/asm/linux_logo.h --- linux-2.4.23-pre6/include/asm/linux_logo.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/linux_logo.h 2001-06-12 11:15:27.000000000 +0900 @@ -0,0 +1,27 @@ +/* $Id: linux_logo.h,v 1.8 1998/07/30 16:30:24 jj Exp $ + * include/asm-i386/linux_logo.h: This is a linux logo + * to be displayed on boot. + * + * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu) + * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from 0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color 0x20) + * BW image has to be 80x80 as well, with MS bit + * on the left + * Serial_console ascii image can be any size, + * but should contain %s to display the version + */ + +#include +#include + +#define linux_logo_banner "Linux/ia32 version " UTS_RELEASE + +#include + diff -ruN linux-2.4.23-pre6/include/asm/lithium.h linux-2.4.23-pre6-swsusp/include/asm/lithium.h --- linux-2.4.23-pre6/include/asm/lithium.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/lithium.h 2001-07-27 05:40:32.000000000 +0900 @@ -0,0 +1,45 @@ +#ifndef __I386_LITHIUM_H +#define __I386_LITHIUM_H + +#include + +/* + * Lithium is the I/O ASIC on the SGI 320 and 540 Visual Workstations + */ + +#define LI_PCI_A_PHYS 0xfc000000 /* Enet is dev 3 */ +#define LI_PCI_B_PHYS 0xfd000000 /* PIIX4 is here */ + +/* see set_fixmap() and asm/fixmap.h */ +#define LI_PCIA_VADDR (fix_to_virt(FIX_LI_PCIA)) +#define LI_PCIB_VADDR (fix_to_virt(FIX_LI_PCIB)) + +/* Not a standard PCI? (not in linux/pci.h) */ +#define LI_PCI_BUSNUM 0x44 /* lo8: primary, hi8: sub */ +#define LI_PCI_INTEN 0x46 + +#ifdef CONFIG_X86_VISWS_APIC +/* More special purpose macros... */ +static __inline void li_pcia_write16(unsigned long reg, unsigned short v) +{ + *((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v; +} + +static __inline unsigned short li_pcia_read16(unsigned long reg) +{ + return *((volatile unsigned short *)(LI_PCIA_VADDR+reg)); +} + +static __inline void li_pcib_write16(unsigned long reg, unsigned short v) +{ + *((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v; +} + +static __inline unsigned short li_pcib_read16(unsigned long reg) +{ + return *((volatile unsigned short *)(LI_PCIB_VADDR+reg)); +} +#endif + +#endif + diff -ruN linux-2.4.23-pre6/include/asm/locks.h linux-2.4.23-pre6-swsusp/include/asm/locks.h --- linux-2.4.23-pre6/include/asm/locks.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/locks.h 2001-07-27 05:40:32.000000000 +0900 @@ -0,0 +1,135 @@ +/* + * SMP locks primitives for building ix86 locks + * (not yet used). + * + * Alan Cox, alan@redhat.com, 1995 + */ + +/* + * This would be much easier but far less clear and easy + * to borrow for other processors if it was just assembler. + */ + +static __inline__ void prim_spin_lock(struct spinlock *sp) +{ + int processor=smp_processor_id(); + + /* + * Grab the lock bit + */ + + while(lock_set_bit(0,&sp->lock)) + { + /* + * Failed, but that's cos we own it! + */ + + if(sp->cpu==processor) + { + sp->users++; + return 0; + } + /* + * Spin in the cache S state if possible + */ + while(sp->lock) + { + /* + * Wait for any invalidates to go off + */ + + if(smp_invalidate_needed&(1<spins++; + } + /* + * Someone wrote the line, we go 'I' and get + * the cache entry. Now try to regrab + */ + } + sp->users++;sp->cpu=processor; + return 1; +} + +/* + * Release a spin lock + */ + +static __inline__ int prim_spin_unlock(struct spinlock *sp) +{ + /* This is safe. The decrement is still guarded by the lock. A multilock would + not be safe this way */ + if(!--sp->users) + { + sp->cpu= NO_PROC_ID;lock_clear_bit(0,&sp->lock); + return 1; + } + return 0; +} + + +/* + * Non blocking lock grab + */ + +static __inline__ int prim_spin_lock_nb(struct spinlock *sp) +{ + if(lock_set_bit(0,&sp->lock)) + return 0; /* Locked already */ + sp->users++; + return 1; /* We got the lock */ +} + + +/* + * These wrap the locking primitives up for usage + */ + +static __inline__ void spinlock(struct spinlock *sp) +{ + if(sp->prioritylock_order) + panic("lock order violation: %s (%d)\n", sp->name, current->lock_order); + if(prim_spin_lock(sp)) + { + /* + * We got a new lock. Update the priority chain + */ + sp->oldpri=current->lock_order; + current->lock_order=sp->priority; + } +} + +static __inline__ void spinunlock(struct spinlock *sp) +{ + int pri; + if(current->lock_order!=sp->priority) + panic("lock release order violation %s (%d)\n", sp->name, current->lock_order); + pri=sp->oldpri; + if(prim_spin_unlock(sp)) + { + /* + * Update the debugging lock priority chain. We dumped + * our last right to the lock. + */ + current->lock_order=sp->pri; + } +} + +static __inline__ void spintestlock(struct spinlock *sp) +{ + /* + * We do no sanity checks, it's legal to optimistically + * get a lower lock. + */ + prim_spin_lock_nb(sp); +} + +static __inline__ void spintestunlock(struct spinlock *sp) +{ + /* + * A testlock doesn't update the lock chain so we + * must not update it on free + */ + prim_spin_unlock(sp); +} diff -ruN linux-2.4.23-pre6/include/asm/math_emu.h linux-2.4.23-pre6-swsusp/include/asm/math_emu.h --- linux-2.4.23-pre6/include/asm/math_emu.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/math_emu.h 2001-07-29 04:53:05.000000000 +0900 @@ -0,0 +1,35 @@ +#ifndef _I386_MATH_EMU_H +#define _I386_MATH_EMU_H + +#include + +int restore_i387_soft(void *s387, struct _fpstate *buf); +int save_i387_soft(void *s387, struct _fpstate * buf); + +/* This structure matches the layout of the data saved to the stack + following a device-not-present interrupt, part of it saved + automatically by the 80386/80486. + */ +struct info { + long ___orig_eip; + long ___ebx; + long ___ecx; + long ___edx; + long ___esi; + long ___edi; + long ___ebp; + long ___eax; + long ___ds; + long ___es; + long ___orig_eax; + long ___eip; + long ___cs; + long ___eflags; + long ___esp; + long ___ss; + long ___vm86_es; /* This and the following only in vm86 mode */ + long ___vm86_ds; + long ___vm86_fs; + long ___vm86_gs; +}; +#endif diff -ruN linux-2.4.23-pre6/include/asm/mc146818rtc.h linux-2.4.23-pre6-swsusp/include/asm/mc146818rtc.h --- linux-2.4.23-pre6/include/asm/mc146818rtc.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/mc146818rtc.h 2001-11-23 04:46:58.000000000 +0900 @@ -0,0 +1,29 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#define RTC_IRQ 8 + +#endif /* _ASM_MC146818RTC_H */ diff -ruN linux-2.4.23-pre6/include/asm/mca_dma.h linux-2.4.23-pre6-swsusp/include/asm/mca_dma.h --- linux-2.4.23-pre6/include/asm/mca_dma.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/mca_dma.h 2001-06-13 03:06:54.000000000 +0900 @@ -0,0 +1,202 @@ +#ifndef MCA_DMA_H +#define MCA_DMA_H + +#include +#include + +/* + * Microchannel specific DMA stuff. DMA on an MCA machine is fairly similar to + * standard PC dma, but it certainly has its quirks. DMA register addresses + * are in a different place and there are some added functions. Most of this + * should be pretty obvious on inspection. Note that the user must divide + * count by 2 when using 16-bit dma; that is not handled by these functions. + * + * Ramen Noodles are yummy. + * + * 1998 Tymm Twillman + */ + +/* + * Registers that are used by the DMA controller; FN is the function register + * (tell the controller what to do) and EXE is the execution register (how + * to do it) + */ + +#define MCA_DMA_REG_FN 0x18 +#define MCA_DMA_REG_EXE 0x1A + +/* + * Functions that the DMA controller can do + */ + +#define MCA_DMA_FN_SET_IO 0x00 +#define MCA_DMA_FN_SET_ADDR 0x20 +#define MCA_DMA_FN_GET_ADDR 0x30 +#define MCA_DMA_FN_SET_COUNT 0x40 +#define MCA_DMA_FN_GET_COUNT 0x50 +#define MCA_DMA_FN_GET_STATUS 0x60 +#define MCA_DMA_FN_SET_MODE 0x70 +#define MCA_DMA_FN_SET_ARBUS 0x80 +#define MCA_DMA_FN_MASK 0x90 +#define MCA_DMA_FN_RESET_MASK 0xA0 +#define MCA_DMA_FN_MASTER_CLEAR 0xD0 + +/* + * Modes (used by setting MCA_DMA_FN_MODE in the function register) + * + * Note that the MODE_READ is read from memory (write to device), and + * MODE_WRITE is vice-versa. + */ + +#define MCA_DMA_MODE_XFER 0x04 /* read by default */ +#define MCA_DMA_MODE_READ 0x04 /* same as XFER */ +#define MCA_DMA_MODE_WRITE 0x08 /* OR with MODE_XFER to use */ +#define MCA_DMA_MODE_IO 0x01 /* DMA from IO register */ +#define MCA_DMA_MODE_16 0x40 /* 16 bit xfers */ + + +/** + * mca_enable_dma - channel to enable DMA on + * @dmanr: DMA channel + * + * Enable the MCA bus DMA on a channel. This can be called from + * IRQ context. + */ + +static __inline__ void mca_enable_dma(unsigned int dmanr) +{ + outb(MCA_DMA_FN_RESET_MASK | dmanr, MCA_DMA_REG_FN); +} + +/** + * mca_disble_dma - channel to disable DMA on + * @dmanr: DMA channel + * + * Enable the MCA bus DMA on a channel. This can be called from + * IRQ context. + */ + +static __inline__ void mca_disable_dma(unsigned int dmanr) +{ + outb(MCA_DMA_FN_MASK | dmanr, MCA_DMA_REG_FN); +} + +/** + * mca_set_dma_addr - load a 24bit DMA address + * @dmanr: DMA channel + * @a: 24bit bus address + * + * Load the address register in the DMA controller. This has a 24bit + * limitation (16Mb). + */ + +static __inline__ void mca_set_dma_addr(unsigned int dmanr, unsigned int a) +{ + outb(MCA_DMA_FN_SET_ADDR | dmanr, MCA_DMA_REG_FN); + outb(a & 0xff, MCA_DMA_REG_EXE); + outb((a >> 8) & 0xff, MCA_DMA_REG_EXE); + outb((a >> 16) & 0xff, MCA_DMA_REG_EXE); +} + +/** + * mca_get_dma_addr - load a 24bit DMA address + * @dmanr: DMA channel + * + * Read the address register in the DMA controller. This has a 24bit + * limitation (16Mb). The return is a bus address. + */ + +static __inline__ unsigned int mca_get_dma_addr(unsigned int dmanr) +{ + unsigned int addr; + + outb(MCA_DMA_FN_GET_ADDR | dmanr, MCA_DMA_REG_FN); + addr = inb(MCA_DMA_REG_EXE); + addr |= inb(MCA_DMA_REG_EXE) << 8; + addr |= inb(MCA_DMA_REG_EXE) << 16; + + return addr; +} + +/** + * mca_set_dma_count - load a 16bit transfer count + * @dmanr: DMA channel + * @count: count + * + * Set the DMA count for this channel. This can be up to 64Kbytes. + * Setting a count of zero will not do what you expect. + */ + +static __inline__ void mca_set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; /* transfers one more than count -- correct for this */ + + outb(MCA_DMA_FN_SET_COUNT | dmanr, MCA_DMA_REG_FN); + outb(count & 0xff, MCA_DMA_REG_EXE); + outb((count >> 8) & 0xff, MCA_DMA_REG_EXE); +} + +/** + * mca_get_dma_residue - get the remaining bytes to transfer + * @dmanr: DMA channel + * + * This function returns the number of bytes left to transfer + * on this DMA channel. + */ + +static __inline__ unsigned int mca_get_dma_residue(unsigned int dmanr) +{ + unsigned short count; + + outb(MCA_DMA_FN_GET_COUNT | dmanr, MCA_DMA_REG_FN); + count = 1 + inb(MCA_DMA_REG_EXE); + count += inb(MCA_DMA_REG_EXE) << 8; + + return count; +} + +/** + * mca_set_dma_io - set the port for an I/O transfer + * @dmanr: DMA channel + * @io_addr: an I/O port number + * + * Unlike the ISA bus DMA controllers the DMA on MCA bus can transfer + * with an I/O port target. + */ + +static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr) +{ + /* + * DMA from a port address -- set the io address + */ + + outb(MCA_DMA_FN_SET_IO | dmanr, MCA_DMA_REG_FN); + outb(io_addr & 0xff, MCA_DMA_REG_EXE); + outb((io_addr >> 8) & 0xff, MCA_DMA_REG_EXE); +} + +/** + * mca_set_dma_mode - set the DMA mode + * @dmanr: DMA channel + * @mode: mode to set + * + * The DMA controller supports several modes. The mode values you can + * set are : + * + * %MCA_DMA_MODE_READ when reading from the DMA device. + * + * %MCA_DMA_MODE_WRITE to writing to the DMA device. + * + * %MCA_DMA_MODE_IO to do DMA to or from an I/O port. + * + * %MCA_DMA_MODE_16 to do 16bit transfers. + * + */ + +static __inline__ void mca_set_dma_mode(unsigned int dmanr, unsigned int mode) +{ + outb(MCA_DMA_FN_SET_MODE | dmanr, MCA_DMA_REG_FN); + outb(mode, MCA_DMA_REG_EXE); +} + +#endif /* MCA_DMA_H */ diff -ruN linux-2.4.23-pre6/include/asm/mman.h linux-2.4.23-pre6-swsusp/include/asm/mman.h --- linux-2.4.23-pre6/include/asm/mman.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/mman.h 2000-03-15 10:45:20.000000000 +0900 @@ -0,0 +1,38 @@ +#ifndef __I386_MMAN_H__ +#define __I386_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +#define MADV_NORMAL 0x0 /* default page-in behavior */ +#define MADV_RANDOM 0x1 /* page-in minimum required */ +#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ +#define MADV_WILLNEED 0x3 /* pre-fault pages */ +#define MADV_DONTNEED 0x4 /* discard these pages */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __I386_MMAN_H__ */ diff -ruN linux-2.4.23-pre6/include/asm/mmu.h linux-2.4.23-pre6-swsusp/include/asm/mmu.h --- linux-2.4.23-pre6/include/asm/mmu.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/mmu.h 2001-07-26 10:03:04.000000000 +0900 @@ -0,0 +1,13 @@ +#ifndef __i386_MMU_H +#define __i386_MMU_H + +/* + * The i386 doesn't have a mmu context, but + * we put the segment information here. + */ +typedef struct { + void *segments; + unsigned long cpuvalid; +} mm_context_t; + +#endif diff -ruN linux-2.4.23-pre6/include/asm/mmu_context.h linux-2.4.23-pre6-swsusp/include/asm/mmu_context.h --- linux-2.4.23-pre6/include/asm/mmu_context.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/mmu_context.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,67 @@ +#ifndef __I386_MMU_CONTEXT_H +#define __I386_MMU_CONTEXT_H + +#include +#include +#include +#include + +/* + * possibly do the LDT unload here? + */ +#define destroy_context(mm) do { } while(0) +#define init_new_context(tsk,mm) 0 + +#ifdef CONFIG_SMP + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) +{ + if(cpu_tlbstate[cpu].state == TLBSTATE_OK) + cpu_tlbstate[cpu].state = TLBSTATE_LAZY; +} +#else +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) +{ +} +#endif + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu) +{ + if (prev != next) { + /* stop flush ipis for the previous mm */ + clear_bit(cpu, &prev->cpu_vm_mask); + /* + * Re-load LDT if necessary + */ + if (prev->context.segments != next->context.segments) + load_LDT(next); +#ifdef CONFIG_SMP + cpu_tlbstate[cpu].state = TLBSTATE_OK; + cpu_tlbstate[cpu].active_mm = next; +#endif + set_bit(cpu, &next->cpu_vm_mask); + set_bit(cpu, &next->context.cpuvalid); + /* Re-load page tables */ + load_cr3(next->pgd); + } +#ifdef CONFIG_SMP + else { + cpu_tlbstate[cpu].state = TLBSTATE_OK; + if(cpu_tlbstate[cpu].active_mm != next) + out_of_line_bug(); + if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) { + /* We were in lazy tlb mode and leave_mm disabled + * tlb flush IPI delivery. We must reload %cr3. + */ + load_cr3(next->pgd); + } + if (!test_and_set_bit(cpu, &next->context.cpuvalid)) + load_LDT(next); + } +#endif +} + +#define activate_mm(prev, next) \ + switch_mm((prev),(next),NULL,smp_processor_id()) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/mmx.h linux-2.4.23-pre6-swsusp/include/asm/mmx.h --- linux-2.4.23-pre6/include/asm/mmx.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/mmx.h 2001-11-23 04:46:18.000000000 +0900 @@ -0,0 +1,14 @@ +#ifndef _ASM_MMX_H +#define _ASM_MMX_H + +/* + * MMX 3Dnow! helper operations + */ + +#include + +extern void *_mmx_memcpy(void *to, const void *from, size_t size); +extern void mmx_clear_page(void *page); +extern void mmx_copy_page(void *to, void *from); + +#endif diff -ruN linux-2.4.23-pre6/include/asm/module.h linux-2.4.23-pre6-swsusp/include/asm/module.h --- linux-2.4.23-pre6/include/asm/module.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/module.h 2001-09-14 08:33:03.000000000 +0900 @@ -0,0 +1,12 @@ +#ifndef _ASM_I386_MODULE_H +#define _ASM_I386_MODULE_H +/* + * This file contains the i386 architecture specific module code. + */ + +#define module_map(x) vmalloc(x) +#define module_unmap(x) vfree(x) +#define module_arch_init(x) (0) +#define arch_init_modules(x) do { } while (0) + +#endif /* _ASM_I386_MODULE_H */ diff -ruN linux-2.4.23-pre6/include/asm/mpspec.h linux-2.4.23-pre6-swsusp/include/asm/mpspec.h --- linux-2.4.23-pre6/include/asm/mpspec.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/mpspec.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,239 @@ +#ifndef __ASM_MPSPEC_H +#define __ASM_MPSPEC_H + +/* + * Structure definitions for SMP machines following the + * Intel Multiprocessing Specification 1.1 and 1.4. + */ + +/* + * This tag identifies where the SMP configuration + * information is. + */ + +#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') + +/* + * a maximum of 16 APICs with the current APIC ID architecture. + * xAPICs can have up to 256. SAPICs have 16 ID bits. + */ +#ifdef CONFIG_X86_CLUSTERED_APIC +#define MAX_APICS 256 +#else +#define MAX_APICS 16 +#endif + +#define MAX_MPC_ENTRY 1024 + +struct intel_mp_floating +{ + char mpf_signature[4]; /* "_MP_" */ + unsigned long mpf_physptr; /* Configuration table address */ + unsigned char mpf_length; /* Our length (paragraphs) */ + unsigned char mpf_specification;/* Specification version */ + unsigned char mpf_checksum; /* Checksum (makes sum 0) */ + unsigned char mpf_feature1; /* Standard or configuration ? */ + unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ + unsigned char mpf_feature3; /* Unused (0) */ + unsigned char mpf_feature4; /* Unused (0) */ + unsigned char mpf_feature5; /* Unused (0) */ +}; + +struct mp_config_table +{ + char mpc_signature[4]; +#define MPC_SIGNATURE "PCMP" + unsigned short mpc_length; /* Size of table */ + char mpc_spec; /* 0x01 */ + char mpc_checksum; + char mpc_oem[8]; + char mpc_productid[12]; + unsigned long mpc_oemptr; /* 0 if not present */ + unsigned short mpc_oemsize; /* 0 if not present */ + unsigned short mpc_oemcount; + unsigned long mpc_lapic; /* APIC address */ + unsigned long reserved; +}; + +/* Followed by entries */ + +#define MP_PROCESSOR 0 +#define MP_BUS 1 +#define MP_IOAPIC 2 +#define MP_INTSRC 3 +#define MP_LINTSRC 4 +#define MP_TRANSLATION 192 /* Used by IBM NUMA-Q to describe node locality */ + +struct mpc_config_processor +{ + unsigned char mpc_type; + unsigned char mpc_apicid; /* Local APIC number */ + unsigned char mpc_apicver; /* Its versions */ + unsigned char mpc_cpuflag; +#define CPU_ENABLED 1 /* Processor is available */ +#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ + unsigned long mpc_cpufeature; +#define CPU_STEPPING_MASK 0x0F +#define CPU_MODEL_MASK 0xF0 +#define CPU_FAMILY_MASK 0xF00 + unsigned long mpc_featureflag; /* CPUID feature value */ + unsigned long mpc_reserved[2]; +}; + +struct mpc_config_bus +{ + unsigned char mpc_type; + unsigned char mpc_busid; + unsigned char mpc_bustype[6] __attribute((packed)); +}; + +/* List of Bus Type string values, Intel MP Spec. */ +#define BUSTYPE_EISA "EISA" +#define BUSTYPE_ISA "ISA" +#define BUSTYPE_INTERN "INTERN" /* Internal BUS */ +#define BUSTYPE_MCA "MCA" +#define BUSTYPE_VL "VL" /* Local bus */ +#define BUSTYPE_PCI "PCI" +#define BUSTYPE_PCMCIA "PCMCIA" +#define BUSTYPE_CBUS "CBUS" +#define BUSTYPE_CBUSII "CBUSII" +#define BUSTYPE_FUTURE "FUTURE" +#define BUSTYPE_MBI "MBI" +#define BUSTYPE_MBII "MBII" +#define BUSTYPE_MPI "MPI" +#define BUSTYPE_MPSA "MPSA" +#define BUSTYPE_NUBUS "NUBUS" +#define BUSTYPE_TC "TC" +#define BUSTYPE_VME "VME" +#define BUSTYPE_XPRESS "XPRESS" + +struct mpc_config_ioapic +{ + unsigned char mpc_type; + unsigned char mpc_apicid; + unsigned char mpc_apicver; + unsigned char mpc_flags; +#define MPC_APIC_USABLE 0x01 + unsigned long mpc_apicaddr; +}; + +struct mpc_config_intsrc +{ + unsigned char mpc_type; + unsigned char mpc_irqtype; + unsigned short mpc_irqflag; + unsigned char mpc_srcbus; + unsigned char mpc_srcbusirq; + unsigned char mpc_dstapic; + unsigned char mpc_dstirq; +}; + +enum mp_irq_source_types { + mp_INT = 0, + mp_NMI = 1, + mp_SMI = 2, + mp_ExtINT = 3 +}; + +#define MP_IRQDIR_DEFAULT 0 +#define MP_IRQDIR_HIGH 1 +#define MP_IRQDIR_LOW 3 + + +struct mpc_config_lintsrc +{ + unsigned char mpc_type; + unsigned char mpc_irqtype; + unsigned short mpc_irqflag; + unsigned char mpc_srcbusid; + unsigned char mpc_srcbusirq; + unsigned char mpc_destapic; +#define MP_APIC_ALL 0xFF + unsigned char mpc_destapiclint; +}; + +struct mp_config_oemtable +{ + char oem_signature[4]; +#define MPC_OEM_SIGNATURE "_OEM" + unsigned short oem_length; /* Size of table */ + char oem_rev; /* 0x01 */ + char oem_checksum; + char mpc_oem[8]; +}; + +struct mpc_config_translation +{ + unsigned char mpc_type; + unsigned char trans_len; + unsigned char trans_type; + unsigned char trans_quad; + unsigned char trans_global; + unsigned char trans_local; + unsigned short trans_reserved; +}; + +/* + * Default configurations + * + * 1 2 CPU ISA 82489DX + * 2 2 CPU EISA 82489DX neither IRQ 0 timer nor IRQ 13 DMA chaining + * 3 2 CPU EISA 82489DX + * 4 2 CPU MCA 82489DX + * 5 2 CPU ISA+PCI + * 6 2 CPU EISA+PCI + * 7 2 CPU MCA+PCI + */ + +#ifdef CONFIG_MULTIQUAD +#define MAX_IRQ_SOURCES 512 +#else /* !CONFIG_MULTIQUAD */ +#define MAX_IRQ_SOURCES 256 +#endif /* CONFIG_MULTIQUAD */ + +#define MAX_MP_BUSSES 32 +enum mp_bustype { + MP_BUS_ISA = 1, + MP_BUS_EISA, + MP_BUS_PCI, + MP_BUS_MCA +}; +extern int *mp_bus_id_to_type; +extern int *mp_bus_id_to_node; +extern int *mp_bus_id_to_local; +extern int *mp_bus_id_to_pci_bus; +extern int quad_local_to_mp_bus_id [NR_CPUS/4][4]; + +extern unsigned int boot_cpu_physical_apicid; +extern unsigned long phys_cpu_present_map; +extern int smp_found_config; +extern void find_smp_config (void); +extern void get_smp_config (void); +extern int nr_ioapics; +extern int apic_version [MAX_APICS]; +extern int mp_irq_entries; +extern struct mpc_config_intsrc *mp_irqs; +extern int mpc_default_type; +extern int mp_current_pci_id; +extern unsigned long mp_lapic_addr; +extern int pic_mode; +extern int using_apic_timer; + +#ifdef CONFIG_ACPI_BOOT +extern void mp_register_lapic (u8 id, u8 enabled); +extern void mp_register_lapic_address (u64 address); + +#ifdef CONFIG_X86_IO_APIC +extern void mp_register_ioapic (u8 id, u32 address, u32 irq_base); +extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 global_irq); +extern void mp_config_acpi_legacy_irqs (void); +extern void mp_config_ioapic_for_sci(int irq); +extern void mp_parse_prt (void); +#else /*!CONFIG_X86_IO_APIC*/ +static inline void mp_config_ioapic_for_sci(int irq) { } +#endif /*!CONFIG_X86_IO_APIC*/ + +#endif /*CONFIG_ACPI_BOOT*/ + +#endif + diff -ruN linux-2.4.23-pre6/include/asm/msgbuf.h linux-2.4.23-pre6-swsusp/include/asm/msgbuf.h --- linux-2.4.23-pre6/include/asm/msgbuf.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/msgbuf.h 2000-01-11 11:15:58.000000000 +0900 @@ -0,0 +1,31 @@ +#ifndef _I386_MSGBUF_H +#define _I386_MSGBUF_H + +/* + * The msqid64_ds structure for i386 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _I386_MSGBUF_H */ diff -ruN linux-2.4.23-pre6/include/asm/msr.h linux-2.4.23-pre6-swsusp/include/asm/msr.h --- linux-2.4.23-pre6/include/asm/msr.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/msr.h 2003-10-05 03:45:24.000000000 +0900 @@ -0,0 +1,125 @@ +#ifndef __ASM_MSR_H +#define __ASM_MSR_H + +/* + * Access to machine-specific registers (available on 586 and better only) + * Note: the rd* operations modify the parameters directly (without using + * pointer indirection), this allows gcc to optimize better + */ + +#define rdmsr(msr,val1,val2) \ + __asm__ __volatile__("rdmsr" \ + : "=a" (val1), "=d" (val2) \ + : "c" (msr)) + +#define wrmsr(msr,val1,val2) \ + __asm__ __volatile__("wrmsr" \ + : /* no outputs */ \ + : "c" (msr), "a" (val1), "d" (val2)) + +#define rdtsc(low,high) \ + __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) + +#define rdtscl(low) \ + __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx") + +#define rdtscll(val) \ + __asm__ __volatile__("rdtsc" : "=A" (val)) + +#define write_tsc(val1,val2) wrmsr(0x10, val1, val2) + +#define rdpmc(counter,low,high) \ + __asm__ __volatile__("rdpmc" \ + : "=a" (low), "=d" (high) \ + : "c" (counter)) + +/* symbolic names for some interesting MSRs */ +/* Intel defined MSRs. */ +#define MSR_IA32_P5_MC_ADDR 0 +#define MSR_IA32_P5_MC_TYPE 1 +#define MSR_IA32_PLATFORM_ID 0x17 +#define MSR_IA32_EBL_CR_POWERON 0x2a + +#define MSR_IA32_APICBASE 0x1b +#define MSR_IA32_APICBASE_BSP (1<<8) +#define MSR_IA32_APICBASE_ENABLE (1<<11) +#define MSR_IA32_APICBASE_BASE (0xfffff<<12) + +#define MSR_IA32_UCODE_WRITE 0x79 +#define MSR_IA32_UCODE_REV 0x8b + +#define MSR_IA32_BBL_CR_CTL 0x119 + +#define MSR_IA32_MCG_CAP 0x179 +#define MSR_IA32_MCG_STATUS 0x17a +#define MSR_IA32_MCG_CTL 0x17b + +#define MSR_IA32_THERM_CONTROL 0x19a +#define MSR_IA32_THERM_INTERRUPT 0x19b +#define MSR_IA32_THERM_STATUS 0x19c +#define MSR_IA32_MISC_ENABLE 0x1a0 + +#define MSR_IA32_DEBUGCTLMSR 0x1d9 +#define MSR_IA32_LASTBRANCHFROMIP 0x1db +#define MSR_IA32_LASTBRANCHTOIP 0x1dc +#define MSR_IA32_LASTINTFROMIP 0x1dd +#define MSR_IA32_LASTINTTOIP 0x1de + +#define MSR_IA32_MC0_CTL 0x400 +#define MSR_IA32_MC0_STATUS 0x401 +#define MSR_IA32_MC0_ADDR 0x402 +#define MSR_IA32_MC0_MISC 0x403 + +#define MSR_P6_PERFCTR0 0xc1 +#define MSR_P6_PERFCTR1 0xc2 +#define MSR_P6_EVNTSEL0 0x186 +#define MSR_P6_EVNTSEL1 0x187 + +#define MSR_IA32_PERF_STATUS 0x198 +#define MSR_IA32_PERF_CTL 0x199 + +/* AMD Defined MSRs */ +#define MSR_K6_EFER 0xC0000080 +#define MSR_K6_STAR 0xC0000081 +#define MSR_K6_WHCR 0xC0000082 +#define MSR_K6_UWCCR 0xC0000085 +#define MSR_K6_EPMR 0xC0000086 +#define MSR_K6_PSOR 0xC0000087 +#define MSR_K6_PFIR 0xC0000088 + +#define MSR_K7_EVNTSEL0 0xC0010000 +#define MSR_K7_PERFCTR0 0xC0010004 +#define MSR_K7_HWCR 0xC0010015 +#define MSR_K7_CLK_CTL 0xC001001b +#define MSR_K7_FID_VID_CTL 0xC0010041 +#define MSR_K7_VID_STATUS 0xC0010042 + +/* Centaur-Hauls/IDT defined MSRs. */ +#define MSR_IDT_FCR1 0x107 +#define MSR_IDT_FCR2 0x108 +#define MSR_IDT_FCR3 0x109 +#define MSR_IDT_FCR4 0x10a + +#define MSR_IDT_MCR0 0x110 +#define MSR_IDT_MCR1 0x111 +#define MSR_IDT_MCR2 0x112 +#define MSR_IDT_MCR3 0x113 +#define MSR_IDT_MCR4 0x114 +#define MSR_IDT_MCR5 0x115 +#define MSR_IDT_MCR6 0x116 +#define MSR_IDT_MCR7 0x117 +#define MSR_IDT_MCR_CTRL 0x120 + +/* VIA Cyrix defined MSRs*/ +#define MSR_VIA_FCR 0x1107 +#define MSR_VIA_LONGHAUL 0x110a +#define MSR_VIA_RNG 0x110b +#define MSR_VIA_BCR2 0x1147 + +/* Transmeta defined MSRs */ +#define MSR_TMTA_LONGRUN_CTRL 0x80868010 +#define MSR_TMTA_LONGRUN_FLAGS 0x80868011 +#define MSR_TMTA_LRTI_READOUT 0x80868018 +#define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a + +#endif /* __ASM_MSR_H */ diff -ruN linux-2.4.23-pre6/include/asm/mtrr.h linux-2.4.23-pre6-swsusp/include/asm/mtrr.h --- linux-2.4.23-pre6/include/asm/mtrr.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/mtrr.h 2003-10-05 03:42:25.000000000 +0900 @@ -0,0 +1,131 @@ +/* Generic MTRR (Memory Type Range Register) ioctls. + + Copyright (C) 1997-1999 Richard Gooch + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Richard Gooch may be reached by email at rgooch@atnf.csiro.au + The postal address is: + Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia. +*/ +#ifndef _LINUX_MTRR_H +#define _LINUX_MTRR_H + +#include +#include + +#define MTRR_IOCTL_BASE 'M' + +struct mtrr_sentry +{ + unsigned long base; /* Base address */ + unsigned long size; /* Size of region */ + unsigned int type; /* Type of region */ +}; + +struct mtrr_gentry +{ + unsigned int regnum; /* Register number */ + unsigned long base; /* Base address */ + unsigned long size; /* Size of region */ + unsigned int type; /* Type of region */ +}; + +/* These are the various ioctls */ +#define MTRRIOC_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry) +#define MTRRIOC_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry) +#define MTRRIOC_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry) +#define MTRRIOC_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry) +#define MTRRIOC_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry) +#define MTRRIOC_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry) +#define MTRRIOC_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry) +#define MTRRIOC_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry) +#define MTRRIOC_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry) +#define MTRRIOC_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry) + +/* These are the region types */ +#define MTRR_TYPE_UNCACHABLE 0 +#define MTRR_TYPE_WRCOMB 1 +/*#define MTRR_TYPE_ 2*/ +/*#define MTRR_TYPE_ 3*/ +#define MTRR_TYPE_WRTHROUGH 4 +#define MTRR_TYPE_WRPROT 5 +#define MTRR_TYPE_WRBACK 6 +#define MTRR_NUM_TYPES 7 + +#ifdef MTRR_NEED_STRINGS +static char *mtrr_strings[MTRR_NUM_TYPES] = +{ + "uncachable", /* 0 */ + "write-combining", /* 1 */ + "?", /* 2 */ + "?", /* 3 */ + "write-through", /* 4 */ + "write-protect", /* 5 */ + "write-back", /* 6 */ +}; +#endif + +#ifdef __KERNEL__ + +/* The following functions are for use by other drivers */ +# ifdef CONFIG_MTRR +extern int mtrr_add (unsigned long base, unsigned long size, + unsigned int type, char increment); +extern int mtrr_add_page (unsigned long base, unsigned long size, + unsigned int type, char increment); +extern int mtrr_del (int reg, unsigned long base, unsigned long size); +extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); +extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); +# ifdef CONFIG_SOFTWARE_SUSPEND +extern int *mtrr_suspend(void); +extern int mtrr_resume(int *ptr); +# endif +# else +static __inline__ int mtrr_add (unsigned long base, unsigned long size, + unsigned int type, char increment) +{ + return -ENODEV; +} +static __inline__ int mtrr_add_page (unsigned long base, unsigned long size, + unsigned int type, char increment) +{ + return -ENODEV; +} +static __inline__ int mtrr_del (int reg, unsigned long base, + unsigned long size) +{ + return -ENODEV; +} +static __inline__ int mtrr_del_page (int reg, unsigned long base, + unsigned long size) +{ + return -ENODEV; +} + +static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;} + +# endif + +/* The following functions are for initialisation: don't use them! */ +extern int mtrr_init (void); +# if defined(CONFIG_SMP) && defined(CONFIG_MTRR) +extern void mtrr_init_boot_cpu (void); +extern void mtrr_init_secondary_cpu (void); +# endif + +#endif + +#endif /* _LINUX_MTRR_H */ diff -ruN linux-2.4.23-pre6/include/asm/namei.h linux-2.4.23-pre6-swsusp/include/asm/namei.h --- linux-2.4.23-pre6/include/asm/namei.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/namei.h 2000-04-03 07:49:07.000000000 +0900 @@ -0,0 +1,17 @@ +/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $ + * linux/include/asm-i386/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __I386_NAMEI_H +#define __I386_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __I386_NAMEI_H */ diff -ruN linux-2.4.23-pre6/include/asm/page.h linux-2.4.23-pre6-swsusp/include/asm/page.h --- linux-2.4.23-pre6/include/asm/page.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/page.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,142 @@ +#ifndef _I386_PAGE_H +#define _I386_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +#include + +#ifdef CONFIG_X86_USE_3DNOW + +#include + +#define clear_page(page) mmx_clear_page((void *)(page)) +#define copy_page(to,from) mmx_copy_page(to,from) + +#else + +/* + * On older X86 processors its not a win to use MMX here it seems. + * Maybe the K6-III ? + */ + +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + +#endif + +#define clear_user_page(page, vaddr) clear_page(page) +#define copy_user_page(to, from, vaddr) copy_page(to, from) + +/* + * These are used to make use of C type-checking.. + */ +#if CONFIG_X86_PAE +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_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) +#else +typedef struct { unsigned long pte_low; } pte_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +#define pte_val(x) ((x).pte_low) +#endif +#define PTE_MASK PAGE_MASK + +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#endif /* !__ASSEMBLY__ */ + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* + * This handles the memory map.. We could make this a config + * option, but too many people screw it up, and too few need + * it. + * + * A __PAGE_OFFSET of 0xC0000000 means that the kernel has + * a virtual address space of one gigabyte, which limits the + * amount of physical memory you can use to about 950MB. + * + * If you want more physical memory than this then see the CONFIG_HIGHMEM4G + * and CONFIG_HIGHMEM64G options in the kernel configuration. + */ + +#define __PAGE_OFFSET (0xC0000000) + +/* + * This much address space is reserved for vmalloc() and iomap() + * as well as fixmap mappings. + */ +#define __VMALLOC_RESERVE (128 << 20) + +#ifndef __ASSEMBLY__ + +/* + * Tell the user there is some problem. Beep too, so we can + * see^H^H^Hhear bugs in early bootup as well! + * The offending file and line are encoded after the "officially + * undefined" opcode for parsing in the trap handler. + */ + +#if 1 /* Set to zero for a slightly smaller kernel */ +#define BUG() \ + __asm__ __volatile__( "ud2\n" \ + "\t.word %c0\n" \ + "\t.long %c1\n" \ + : : "i" (__LINE__), "i" (__FILE__)) +#else +#define BUG() __asm__ __volatile__("ud2\n") +#endif + +#define PAGE_BUG(page) do { \ + BUG(); \ +} while (0) + +/* Pure 2^n version of get_order */ +static __inline__ int get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +#endif /* __ASSEMBLY__ */ + +#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) +#define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) +#define __MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) +#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)) +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT)) +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) + +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#endif /* __KERNEL__ */ + +#endif /* _I386_PAGE_H */ diff -ruN linux-2.4.23-pre6/include/asm/param.h linux-2.4.23-pre6-swsusp/include/asm/param.h --- linux-2.4.23-pre6/include/asm/param.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/param.h 2000-10-28 03:04:43.000000000 +0900 @@ -0,0 +1,24 @@ +#ifndef _ASMi386_PARAM_H +#define _ASMi386_PARAM_H + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ +#endif + +#endif diff -ruN linux-2.4.23-pre6/include/asm/parport.h linux-2.4.23-pre6-swsusp/include/asm/parport.h --- linux-2.4.23-pre6/include/asm/parport.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/parport.h 2000-03-15 11:04:50.000000000 +0900 @@ -0,0 +1,18 @@ +/* + * parport.h: ia32-specific parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh + * + * This file should only be included by drivers/parport/parport_pc.c. + */ + +#ifndef _ASM_I386_PARPORT_H +#define _ASM_I386_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_I386_PARPORT_H) */ diff -ruN linux-2.4.23-pre6/include/asm/pci.h linux-2.4.23-pre6-swsusp/include/asm/pci.h --- linux-2.4.23-pre6/include/asm/pci.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/pci.h 2003-10-05 03:45:24.000000000 +0900 @@ -0,0 +1,288 @@ +#ifndef __i386_PCI_H +#define __i386_PCI_H + +#include + +#ifdef __KERNEL__ + +/* Can be used to override the logic in pci_scan_bus for skipping + already-configured bus numbers - to be used for buggy BIOSes + or architectures with incomplete PCI setup by the loader */ + +#ifdef CONFIG_PCI +extern unsigned int pcibios_assign_all_busses(void); +#else +#define pcibios_assign_all_busses() 0 +#endif +#define pcibios_scan_all_fns() 0 + +extern unsigned long pci_mem_start; +#define PCIBIOS_MIN_IO 0x1000 +#define PCIBIOS_MIN_MEM (pci_mem_start) + +void pcibios_config_init(void); +struct pci_bus * pcibios_scan_root(int bus); +extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value); +extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value); + +void pcibios_set_master(struct pci_dev *dev); +void pcibios_penalize_isa_irq(int irq); +struct irq_routing_table *pcibios_get_irq_routing_table(void); +int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq); + +/* Dynamic DMA mapping stuff. + * i386 has everything mapped statically. + */ + +#include +#include +#include +#include +#include + +struct pci_dev; + +/* The PCI address space does equal the physical memory + * address space. The networking and block device layers use + * this boolean for bounce buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +/* Allocate and map kernel buffer using consistent mode DMA for a device. + * hwdev should be valid struct pci_dev pointer for PCI devices, + * NULL for PCI-like buses (ISA, EISA). + * Returns non-NULL cpu-view pointer to the buffer if successful and + * sets *dma_addrp to the pci side dma address as well, else *dma_addrp + * is undefined. + */ +extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle); + +/* Free and unmap a consistent DMA buffer. + * cpu_addr is what was returned from pci_alloc_consistent, + * size must be the same as what as passed into pci_alloc_consistent, + * and likewise dma_addr must be the same as what *dma_addrp was set to. + * + * References to the memory and mappings associated with cpu_addr/dma_addr + * past this call are illegal. + */ +extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +/* Map a single buffer of the indicated size for DMA in streaming mode. + * The 32-bit bus address to use is returned. + * + * 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. + */ +static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + out_of_line_bug(); + flush_write_buffers(); + return virt_to_bus(ptr); +} + +/* Unmap a single streaming mode DMA translation. The dma_addr and size + * must match what was provided for in a previous pci_map_single call. All + * other usages are undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see + * whatever the device wrote there. + */ +static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + out_of_line_bug(); + /* Nothing to do */ +} + +/* + * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical + * to pci_map_single, but takes a struct page instead of a virtual address + */ +static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + out_of_line_bug(); + + return ((dma_addr_t)(page - mem_map) * + (dma_addr_t) PAGE_SIZE + + (dma_addr_t) offset); +} + +static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + out_of_line_bug(); + /* Nothing to do */ +} + +/* pci_unmap_{page,single} is a nop so... */ +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) +#define pci_unmap_addr(PTR, ADDR_NAME) (0) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) +#define pci_unmap_len(PTR, LEN_NAME) (0) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) + +/* Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + out_of_line_bug(); + + /* + * temporary 2.4 hack + */ + for (i = 0; i < nents; i++ ) { + if (sg[i].address && sg[i].page) + out_of_line_bug(); + else if (!sg[i].address && !sg[i].page) + out_of_line_bug(); + + if (sg[i].address) + sg[i].dma_address = virt_to_bus(sg[i].address); + else + sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset; + } + + flush_write_buffers(); + return nents; +} + +/* Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction) +{ + if (direction == PCI_DMA_NONE) + out_of_line_bug(); + /* Nothing to do */ +} + +/* Make physical memory consistent for a single + * streaming mode DMA translation after a transfer. + * + * If you perform a pci_map_single() but wish to interrogate the + * buffer using the cpu, yet do not wish to teardown the PCI dma + * mapping, you must call this function before doing so. At the + * next point you give the PCI dma address back to the card, the + * device again owns the buffer. + */ +static inline void pci_dma_sync_single(struct pci_dev *hwdev, + dma_addr_t dma_handle, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + out_of_line_bug(); + flush_write_buffers(); +} + +/* Make physical memory consistent for a set of streaming + * mode DMA translations after a transfer. + * + * The same as pci_dma_sync_single but for a scatter-gather list, + * same rules and usage. + */ +static inline void pci_dma_sync_sg(struct pci_dev *hwdev, + struct scatterlist *sg, + int nelems, int direction) +{ + if (direction == PCI_DMA_NONE) + out_of_line_bug(); + flush_write_buffers(); +} + +/* Return whether the given PCI device DMA address mask can + * be supported properly. For example, if your device can + * only drive the low 24-bits during PCI bus mastering, then + * you would pass 0x00ffffff as the mask to this function. + */ +static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + */ + if(mask < 0x00ffffff) + return 0; + + return 1; +} + +/* This is always fine. */ +#define pci_dac_dma_supported(pci_dev, mask) (1) + +static __inline__ dma64_addr_t +pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction) +{ + return ((dma64_addr_t) page_to_bus(page) + + (dma64_addr_t) offset); +} + +static __inline__ struct page * +pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr) +{ + unsigned long poff = (dma_addr >> PAGE_SHIFT); + + return mem_map + poff; +} + +static __inline__ unsigned long +pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr) +{ + return (dma_addr & ~PAGE_MASK); +} + +static __inline__ void +pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction) +{ + flush_write_buffers(); +} + +/* These macros should be used after a pci_map_sg call has been done + * to get bus addresses of each of the SG entries and their lengths. + * You should only work with the number of sg entries pci_map_sg + * returns. + */ +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->length) + +/* Return the index of the PCI controller for device. */ +static inline int pci_controller_num(struct pci_dev *dev) +{ + return 0; +} + +#define HAVE_PCI_MMAP +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); + +#endif /* __KERNEL__ */ + +#endif /* __i386_PCI_H */ diff -ruN linux-2.4.23-pre6/include/asm/pgalloc.h linux-2.4.23-pre6-swsusp/include/asm/pgalloc.h --- linux-2.4.23-pre6/include/asm/pgalloc.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/pgalloc.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,238 @@ +#ifndef _I386_PGALLOC_H +#define _I386_PGALLOC_H + +#include +#include +#include +#include + +#define pgd_quicklist (current_cpu_data.pgd_quick) +#define pmd_quicklist (current_cpu_data.pmd_quick) +#define pte_quicklist (current_cpu_data.pte_quick) +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) + +#define pmd_populate(mm, pmd, pte) \ + set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) + +/* + * Allocate and free page tables. + */ + +#if defined (CONFIG_X86_PAE) +/* + * We can't include here, thus these uglinesses. + */ +struct kmem_cache_s; + +extern struct kmem_cache_s *pae_pgd_cachep; +extern void *kmem_cache_alloc(struct kmem_cache_s *, int); +extern void kmem_cache_free(struct kmem_cache_s *, void *); + + +static inline pgd_t *get_pgd_slow(void) +{ + int i; + pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL); + + if (pgd) { + for (i = 0; i < USER_PTRS_PER_PGD; i++) { + unsigned long pmd = __get_free_page(GFP_KERNEL); + if (!pmd) + goto out_oom; + clear_page(pmd); + set_pgd(pgd + i, __pgd(1 + __pa(pmd))); + } + memcpy(pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + } + return pgd; +out_oom: + for (i--; i >= 0; i--) + free_page((unsigned long)__va(pgd_val(pgd[i])-1)); + kmem_cache_free(pae_pgd_cachep, pgd); + return NULL; +} + +#else + +static inline pgd_t *get_pgd_slow(void) +{ + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL); + + if (pgd) { + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); + memcpy(pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + } + return pgd; +} + +#endif /* CONFIG_X86_PAE */ + +static inline pgd_t *get_pgd_fast(void) +{ + unsigned long *ret; + + if ((ret = pgd_quicklist) != NULL) { + pgd_quicklist = (unsigned long *)(*ret); + ret[0] = 0; + pgtable_cache_size--; + } else + ret = (unsigned long *)get_pgd_slow(); + return (pgd_t *)ret; +} + +static inline void free_pgd_fast(pgd_t *pgd) +{ + *(unsigned long *)pgd = (unsigned long) pgd_quicklist; + pgd_quicklist = (unsigned long *) pgd; + pgtable_cache_size++; +} + +static inline void free_pgd_slow(pgd_t *pgd) +{ +#if defined(CONFIG_X86_PAE) + int i; + + for (i = 0; i < USER_PTRS_PER_PGD; i++) + free_page((unsigned long)__va(pgd_val(pgd[i])-1)); + kmem_cache_free(pae_pgd_cachep, pgd); +#else + free_page((unsigned long)pgd); +#endif +} + +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) +{ + pte_t *pte; + + pte = (pte_t *) __get_free_page(GFP_KERNEL); + if (pte) + clear_page(pte); + return pte; +} + +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, + unsigned long address) +{ + unsigned long *ret; + + if ((ret = (unsigned long *)pte_quicklist) != NULL) { + pte_quicklist = (unsigned long *)(*ret); + ret[0] = ret[1]; + pgtable_cache_size--; + } + return (pte_t *)ret; +} + +static inline void pte_free_fast(pte_t *pte) +{ + *(unsigned long *)pte = (unsigned long) pte_quicklist; + pte_quicklist = (unsigned long *) pte; + pgtable_cache_size++; +} + +static __inline__ void pte_free_slow(pte_t *pte) +{ + free_page((unsigned long)pte); +} + +#define pte_free(pte) pte_free_fast(pte) +#define pgd_free(pgd) free_pgd_slow(pgd) +#define pgd_alloc(mm) get_pgd_fast() + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + * (In the PAE case we free the pmds as part of the pgd.) + */ + +#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); }) +#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_free_slow(x) do { } while (0) +#define pmd_free_fast(x) do { } while (0) +#define pmd_free(x) do { } while (0) +#define pgd_populate(mm, pmd, pte) BUG() + +extern int do_check_pgt_cache(int, int); + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(mm, start, end) flushes a range of pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables + * + * ..but the i386 has somewhat limited tlb flushing capabilities, + * and page-granular flushes are available only on i486 and up. + */ + +#ifndef CONFIG_SMP + +#define flush_tlb() __flush_tlb() +#define flush_tlb_all() __flush_tlb_all() +#define local_flush_tlb() __flush_tlb() + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->active_mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + if (vma->vm_mm == current->active_mm) + __flush_tlb_one(addr); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (mm == current->active_mm) + __flush_tlb(); +} + +#else + +#include + +#define local_flush_tlb() \ + __flush_tlb() + +extern void flush_tlb_all(void); +extern void flush_tlb_current_task(void); +extern void flush_tlb_mm(struct mm_struct *); +extern void flush_tlb_page(struct vm_area_struct *, unsigned long); + +#define flush_tlb() flush_tlb_current_task() + +static inline void flush_tlb_range(struct mm_struct * mm, unsigned long start, unsigned long end) +{ + flush_tlb_mm(mm); +} + +#define TLBSTATE_OK 1 +#define TLBSTATE_LAZY 2 + +struct tlb_state +{ + struct mm_struct *active_mm; + int state; +} ____cacheline_aligned; +extern struct tlb_state cpu_tlbstate[NR_CPUS]; + +#endif /* CONFIG_SMP */ + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + flush_tlb_mm(mm); +} + +#endif /* _I386_PGALLOC_H */ diff -ruN linux-2.4.23-pre6/include/asm/pgtable-2level.h linux-2.4.23-pre6-swsusp/include/asm/pgtable-2level.h --- linux-2.4.23-pre6/include/asm/pgtable-2level.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/pgtable-2level.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,65 @@ +#ifndef _I386_PGTABLE_2LEVEL_H +#define _I386_PGTABLE_2LEVEL_H + +/* + * traditional i386 two-level paging structure: + */ + +#define PGDIR_SHIFT 22 +#define PTRS_PER_PGD 1024 + +/* + * the i386 is two-level, so we don't really have any + * PMD directory physically. + */ +#define PMD_SHIFT 22 +#define PTRS_PER_PMD 1 + +#define PTRS_PER_PTE 1024 + +#define pte_ERROR(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) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } +#define pgd_clear(xp) do { } while (0) + +/* + * Certain architectures need to do special things when PTEs + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) (*(pteptr) = pteval) +#define set_pte_atomic(pteptr, pteval) (*(pteptr) = pteval) + +/* + * (pmds are folded into pgds so this doesnt get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) + +#define pgd_page(pgd) \ +((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) + +static 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 -ruN linux-2.4.23-pre6/include/asm/pgtable-3level.h linux-2.4.23-pre6-swsusp/include/asm/pgtable-3level.h --- linux-2.4.23-pre6/include/asm/pgtable-3level.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/pgtable-3level.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,104 @@ +#ifndef _I386_PGTABLE_3LEVEL_H +#define _I386_PGTABLE_3LEVEL_H + +/* + * Intel Physical Address Extension (PAE) Mode - three-level page + * tables on PPro+ CPUs. + * + * Copyright (C) 1999 Ingo Molnar + */ + +/* + * PGDIR_SHIFT determines what a top-level page table entry can map + */ +#define PGDIR_SHIFT 30 +#define PTRS_PER_PGD 4 + +/* + * PMD_SHIFT determines the size of the area a middle-level + * page table can map + */ +#define PMD_SHIFT 21 +#define PTRS_PER_PMD 512 + +/* + * entries per page directory level + */ +#define PTRS_PER_PTE 512 + +#define pte_ERROR(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) \ + printk("%s:%d: bad pgd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pgd_val(e)) + +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } + +/* 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) \ + set_64bit((unsigned long long *)(pgdptr),pgd_val(pgdval)) +#define set_pte_atomic(pteptr,pteval) \ + set_64bit((unsigned long long *)(pteptr),pte_val(pteval)) + + +/* + * Pentium-II erratum A13: in PAE mode we explicitly have to flush + * the TLB via cr3 if the top-level pgd is changed... + * We do not let the generic code free and clear pgd entries due to + * this erratum. + */ +static inline void pgd_clear (pgd_t * pgd) { } + +#define pgd_page(pgd) \ +((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) + +/* Find an entry in the second-level page table.. */ +#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 -ruN linux-2.4.23-pre6/include/asm/pgtable.h linux-2.4.23-pre6-swsusp/include/asm/pgtable.h --- linux-2.4.23-pre6/include/asm/pgtable.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/pgtable.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,369 @@ +#ifndef _I386_PGTABLE_H +#define _I386_PGTABLE_H + +#include + +/* + * The Linux memory management assumes a three-level page table setup. On + * the i386, we use that, but "fold" the mid level into the top-level page + * table, so that we physically have the same two-level page table as the + * i386 mmu expects. + * + * This file contains the functions and defines necessary to modify and use + * the i386 page table tree. + */ +#ifndef __ASSEMBLY__ +#include +#include +#include + +#ifndef _I386_BITOPS_H +#include +#endif + +extern pgd_t swapper_pg_dir[1024]; +extern void paging_init(void); + +/* Caches aren't brain-dead on the intel. */ +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(mm, start, end) do { } while (0) +#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) +#define flush_dcache_page(page) do { } while (0) +#define flush_icache_range(start, end) do { } while (0) +#define flush_icache_page(vma,pg) do { } while (0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) + +#define __flush_tlb() \ + do { \ + unsigned int tmpreg; \ + \ + __asm__ __volatile__( \ + "movl %%cr3, %0; # flush TLB \n" \ + "movl %0, %%cr3; \n" \ + : "=r" (tmpreg) \ + :: "memory"); \ + } while (0) + +/* + * Global pages have to be flushed a bit differently. Not a real + * performance problem because this does not happen often. + */ +#define __flush_tlb_global() \ + do { \ + unsigned int tmpreg; \ + \ + __asm__ __volatile__( \ + "movl %1, %%cr4; # turn off PGE \n" \ + "movl %%cr3, %0; # flush TLB \n" \ + "movl %0, %%cr3; \n" \ + "movl %2, %%cr4; # turn PGE back on \n" \ + : "=&r" (tmpreg) \ + : "r" (mmu_cr4_features & ~X86_CR4_PGE), \ + "r" (mmu_cr4_features) \ + : "memory"); \ + } while (0) + +extern unsigned long pgkern_mask; + +/* + * Do not check the PGE bit unnecesserily if this is a PPro+ kernel. + */ +#ifdef CONFIG_X86_PGE +# define __flush_tlb_all() __flush_tlb_global() +#else +# define __flush_tlb_all() \ + do { \ + if (cpu_has_pge) \ + __flush_tlb_global(); \ + else \ + __flush_tlb(); \ + } while (0) +#endif + +#define __flush_tlb_single(addr) \ + __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr)) + +#ifdef CONFIG_X86_INVLPG +# define __flush_tlb_one(addr) __flush_tlb_single(addr) +#else +# define __flush_tlb_one(addr) \ + do { \ + if (cpu_has_pge) \ + __flush_tlb_single(addr); \ + else \ + __flush_tlb(); \ + } while (0) +#endif + +/* + * 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]; +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) + +#endif /* !__ASSEMBLY__ */ + +/* + * The Linux x86 paging architecture is 'compile-time dual-mode', it + * implements both the traditional 2-level x86 page tables and the + * newer 3-level PAE-mode page tables. + */ +#ifndef __ASSEMBLY__ +#if CONFIG_X86_PAE +# include + +/* + * Need to initialise the X86 PAE caches + */ +extern void pgtable_cache_init(void); + +#else +# include + +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + +#endif +#endif + +#define __beep() asm("movb $0x3,%al; outb %al,$0x61") + +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) +#define FIRST_USER_PGD_NR 0 + +#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) + +#define TWOLEVEL_PGDIR_SHIFT 22 +#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT) +#define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS) + + +#ifndef __ASSEMBLY__ +/* Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \ + ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#if CONFIG_HIGHMEM +# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) +#else +# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) +#endif + +/* + * The 4MB page is guessing.. Detailed in the infamous "Chapter H" + * of the Pentium details, but assuming intel did the straightforward + * thing, this bit set in the page directory entry just means that + * 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 +#define _PAGE_PWT 0x008 +#define _PAGE_PCD 0x010 +#define _PAGE_ACCESSED 0x020 +#define _PAGE_DIRTY 0x040 +#define _PAGE_PSE 0x080 /* 4 MB (or 2MB) page, Pentium+, if present.. */ +#define _PAGE_GLOBAL 0x100 /* Global TLB entry PPro+ */ + +#define _PAGE_PROTNONE 0x080 /* If not present */ + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) + +#define __PAGE_KERNEL \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) +#define __PAGE_KERNEL_NOCACHE \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED) +#define __PAGE_KERNEL_RO \ + (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED) + +#ifdef CONFIG_X86_PGE +# define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL) +#else +# define MAKE_GLOBAL(x) \ + ({ \ + pgprot_t __ret; \ + \ + if (cpu_has_pge) \ + __ret = __pgprot((x) | _PAGE_GLOBAL); \ + else \ + __ret = __pgprot(x); \ + __ret; \ + }) +#endif + +#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL) +#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) + +/* + * The i386 can't do page protection for execute, and considers that + * the same are read. Also, write permissions imply read permissions. + * This is the closest we can get.. + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +/* + * Define this if things work differently on an i386 and an i486: + * it will (on an i486) warn about kernel memory accesses that are + * done without a 'verify_area(VERIFY_WRITE,..)' + */ +#undef TEST_VERIFY_AREA + +/* page table for 0-4MB for everybody */ +extern unsigned long pg0[1024]; + +#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)) +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) + + +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +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_set_wrprotect(pte_t *ptep) { clear_bit(_PAGE_BIT_RW, ptep); } +static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, 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) __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) __mk_pte((physpage) >> PAGE_SHIFT, pgprot) + +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)) + +#define pmd_page(pmd) \ +((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) + +/* to find an entry in a page-table-directory. */ +#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)) + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +#define __pmd_offset(address) \ + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) + +/* Find an entry in the third-level page table.. */ +#define __pte_offset(address) \ + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset(dir, address) ((pte_t *) pmd_page(*(dir)) + \ + __pte_offset(address)) + +/* + * The i386 doesn't have any external MMU info: the kernel page + * tables contain all the necessary information. + */ +#define update_mmu_cache(vma,address,pte) do { } while (0) + +/* Encode and de-code a swap entry */ +#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).pte_low }) +#define swp_entry_to_pte(x) ((pte_t) { (x).val }) + +struct page; +int change_page_attr(struct page *, int, pgprot_t prot); + +#endif /* !__ASSEMBLY__ */ + +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +#define PageSkip(page) (0) +#define kern_addr_valid(addr) (1) + +#define io_remap_page_range remap_page_range + +#endif /* _I386_PGTABLE_H */ diff -ruN linux-2.4.23-pre6/include/asm/poll.h linux-2.4.23-pre6-swsusp/include/asm/poll.h --- linux-2.4.23-pre6/include/asm/poll.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/poll.h 1997-01-24 04:01:28.000000000 +0900 @@ -0,0 +1,25 @@ +#ifndef __i386_POLL_H +#define __i386_POLL_H + +/* These are specified by iBCS2 */ +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 + +/* The rest seem to be more-or-less nonstandard. Check them! */ +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM 0x0100 +#define POLLWRBAND 0x0200 +#define POLLMSG 0x0400 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif diff -ruN linux-2.4.23-pre6/include/asm/posix_types.h linux-2.4.23-pre6-swsusp/include/asm/posix_types.h --- linux-2.4.23-pre6/include/asm/posix_types.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/posix_types.h 2000-01-18 15:22:52.000000000 +0900 @@ -0,0 +1,80 @@ +#ifndef __ARCH_I386_POSIX_TYPES_H +#define __ARCH_I386_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(fd,fdsetp) \ + __asm__ __volatile__("btsl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_CLR +#define __FD_CLR(fd,fdsetp) \ + __asm__ __volatile__("btrl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_ISSET +#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ + unsigned char __result; \ + __asm__ __volatile__("btl %1,%2 ; setb %0" \ + :"=q" (__result) :"r" ((int) (fd)), \ + "m" (*(__kernel_fd_set *) (fdsetp))); \ + __result; })) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__("cld ; rep ; stosl" \ + :"=m" (*(__kernel_fd_set *) (fdsetp)), \ + "=&c" (__d0), "=&D" (__d1) \ + :"a" (0), "1" (__FDSET_LONGS), \ + "2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \ +} while (0) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/processor.h linux-2.4.23-pre6-swsusp/include/asm/processor.h --- linux-2.4.23-pre6/include/asm/processor.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/processor.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,504 @@ +/* + * include/asm-i386/processor.h + * + * Copyright (C) 1994 Linus Torvalds + */ + +#ifndef __ASM_I386_PROCESSOR_H +#define __ASM_I386_PROCESSOR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) + +/* + * CPU type and hardware bug flags. Kept separately for each CPU. + * Members of this structure are referenced in head.S, so think twice + * before touching them. [mj] + */ + +struct cpuinfo_x86 { + __u8 x86; /* CPU family */ + __u8 x86_vendor; /* CPU vendor */ + __u8 x86_model; + __u8 x86_mask; + char wp_works_ok; /* It doesn't on 386's */ + char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */ + char hard_math; + char rfu; + int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ + __u32 x86_capability[NCAPINTS]; + char x86_vendor_id[16]; + char x86_model_id[64]; + int x86_cache_size; /* in KB - valid for CPUS which support this + call */ + int fdiv_bug; + int f00f_bug; + int coma_bug; + unsigned long loops_per_jiffy; + unsigned long *pgd_quick; + unsigned long *pmd_quick; + unsigned long *pte_quick; + unsigned long pgtable_cache_sz; +} __attribute__((__aligned__(SMP_CACHE_BYTES))); + +#define X86_VENDOR_INTEL 0 +#define X86_VENDOR_CYRIX 1 +#define X86_VENDOR_AMD 2 +#define X86_VENDOR_UMC 3 +#define X86_VENDOR_NEXGEN 4 +#define X86_VENDOR_CENTAUR 5 +#define X86_VENDOR_RISE 6 +#define X86_VENDOR_TRANSMETA 7 +#define X86_VENDOR_NSC 8 +#define X86_VENDOR_SIS 9 +#define X86_VENDOR_UNKNOWN 0xff + +/* + * capabilities of CPUs + */ + +extern struct cpuinfo_x86 boot_cpu_data; +extern struct tss_struct init_tss[NR_CPUS]; + +#ifdef CONFIG_SMP +extern struct cpuinfo_x86 cpu_data[]; +#define current_cpu_data cpu_data[smp_processor_id()] +#else +#define cpu_data (&boot_cpu_data) +#define current_cpu_data boot_cpu_data +#endif + +extern char ignore_irq13; + +extern void identify_cpu(struct cpuinfo_x86 *); +extern void print_cpu_info(struct cpuinfo_x86 *); +extern void dodgy_tsc(void); + +/* + * EFLAGS bits + */ +#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ +#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */ +#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */ +#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */ +#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */ +#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */ +#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */ +#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */ +#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */ +#define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */ +#define X86_EFLAGS_NT 0x00004000 /* Nested Task */ +#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */ +#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */ +#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */ +#define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */ +#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ +#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ + +/* + * Generic CPUID function + */ +static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx) +{ + __asm__("cpuid" + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), + "=d" (*edx) + : "0" (op)); +} + +/* + * CPUID functions returning a single datum + */ +static inline unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax; + + __asm__("cpuid" + : "=a" (eax) + : "0" (op) + : "bx", "cx", "dx"); + return eax; +} +static inline unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx; + + __asm__("cpuid" + : "=a" (eax), "=b" (ebx) + : "0" (op) + : "cx", "dx" ); + return ebx; +} +static inline unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ecx; + + __asm__("cpuid" + : "=a" (eax), "=c" (ecx) + : "0" (op) + : "bx", "dx" ); + return ecx; +} +static inline unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, edx; + + __asm__("cpuid" + : "=a" (eax), "=d" (edx) + : "0" (op) + : "bx", "cx"); + return edx; +} + +/* + * Intel CPU features in CR4 + */ +#define X86_CR4_VME 0x0001 /* enable vm86 extensions */ +#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ +#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ +#define X86_CR4_DE 0x0008 /* enable debugging extensions */ +#define X86_CR4_PSE 0x0010 /* enable page size extensions */ +#define X86_CR4_PAE 0x0020 /* enable physical address extensions */ +#define X86_CR4_MCE 0x0040 /* Machine check enable */ +#define X86_CR4_PGE 0x0080 /* enable global pages */ +#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ +#define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */ +#define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */ + +#define load_cr3(pgdir) \ + asm volatile("movl %0,%%cr3": :"r" (__pa(pgdir))); + +/* + * Save the cr4 feature set we're using (ie + * Pentium 4MB enable and PPro Global page + * enable), so that any CPU's that boot up + * after us can get the correct flags. + */ +extern unsigned long mmu_cr4_features; + +static inline void set_in_cr4 (unsigned long mask) +{ + mmu_cr4_features |= mask; + __asm__("movl %%cr4,%%eax\n\t" + "orl %0,%%eax\n\t" + "movl %%eax,%%cr4\n" + : : "irg" (mask) + :"ax"); +} + +static inline void clear_in_cr4 (unsigned long mask) +{ + mmu_cr4_features &= ~mask; + __asm__("movl %%cr4,%%eax\n\t" + "andl %0,%%eax\n\t" + "movl %%eax,%%cr4\n" + : : "irg" (~mask) + :"ax"); +} + +/* + * Cyrix CPU configuration register indexes + */ +#define CX86_CCR0 0xc0 +#define CX86_CCR1 0xc1 +#define CX86_CCR2 0xc2 +#define CX86_CCR3 0xc3 +#define CX86_CCR4 0xe8 +#define CX86_CCR5 0xe9 +#define CX86_CCR6 0xea +#define CX86_CCR7 0xeb +#define CX86_DIR0 0xfe +#define CX86_DIR1 0xff +#define CX86_ARR_BASE 0xc4 +#define CX86_RCR_BASE 0xdc + +/* + * Cyrix CPU indexed register access macros + */ + +#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); }) + +#define setCx86(reg, data) do { \ + outb((reg), 0x22); \ + outb((data), 0x23); \ +} while (0) + +/* + * Bus types (default is ISA, but people can check others with these..) + */ +#ifdef CONFIG_EISA +extern int EISA_bus; +#else +#define EISA_bus (0) +#endif +extern int MCA_bus; + +/* from system description table in BIOS. Mostly for MCA use, but +others may find it useful. */ +extern unsigned int machine_id; +extern unsigned int machine_submodel_id; +extern unsigned int BIOS_revision; +extern unsigned int mca_pentium_flag; + +/* + * User space process size: 3GB (default). + */ +#define TASK_SIZE (PAGE_OFFSET) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + +/* + * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. + */ +#define IO_BITMAP_SIZE 32 +#define IO_BITMAP_BYTES (IO_BITMAP_SIZE * 4) +#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) +#define INVALID_IO_BITMAP_OFFSET 0x8000 + +struct i387_fsave_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ + long status; /* software status information */ +}; + +struct i387_fxsave_struct { + unsigned short cwd; + unsigned short swd; + unsigned short twd; + unsigned short fop; + long fip; + long fcs; + long foo; + long fos; + long mxcsr; + long reserved; + long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ + long padding[56]; +} __attribute__ ((aligned (16))); + +struct i387_soft_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ + unsigned char ftop, changed, lookahead, no_update, rm, alimit; + struct info *info; + unsigned long entry_eip; +}; + +union i387_union { + struct i387_fsave_struct fsave; + struct i387_fxsave_struct fxsave; + struct i387_soft_struct soft; +}; + +typedef struct { + unsigned long seg; +} mm_segment_t; + +struct tss_struct { + unsigned short back_link,__blh; + unsigned long esp0; + unsigned short ss0,__ss0h; + unsigned long esp1; + unsigned short ss1,__ss1h; + unsigned long esp2; + unsigned short ss2,__ss2h; + unsigned long __cr3; + unsigned long eip; + unsigned long eflags; + unsigned long eax,ecx,edx,ebx; + unsigned long esp; + unsigned long ebp; + unsigned long esi; + unsigned long edi; + unsigned short es, __esh; + unsigned short cs, __csh; + unsigned short ss, __ssh; + unsigned short ds, __dsh; + unsigned short fs, __fsh; + unsigned short gs, __gsh; + unsigned short ldt, __ldth; + unsigned short trace, bitmap; + unsigned long io_bitmap[IO_BITMAP_SIZE+1]; + /* + * pads the TSS to be cacheline-aligned (size is 0x100) + */ + unsigned long __cacheline_filler[5]; +}; + +struct thread_struct { + unsigned long esp0; + unsigned long eip; + unsigned long esp; + unsigned long fs; + unsigned long gs; +/* Hardware debugging registers */ + unsigned long debugreg[8]; /* %%db0-7 debug registers */ +/* fault info */ + unsigned long cr2, trap_no, error_code; +/* floating point info */ + union i387_union i387; +/* virtual 86 mode info */ + struct vm86_struct * vm86_info; + unsigned long screen_bitmap; + unsigned long v86flags, v86mask, saved_esp0; +/* IO permissions */ + int ioperm; + unsigned long io_bitmap[IO_BITMAP_SIZE+1]; +}; + +#define INIT_THREAD { \ + 0, \ + 0, 0, 0, 0, \ + { [0 ... 7] = 0 }, /* debugging registers */ \ + 0, 0, 0, \ + { { 0, }, }, /* 387 state */ \ + 0,0,0,0,0, \ + 0,{~0,} /* io permissions */ \ +} + +#define INIT_TSS { \ + 0,0, /* back_link, __blh */ \ + sizeof(init_stack) + (long) &init_stack, /* esp0 */ \ + __KERNEL_DS, 0, /* ss0 */ \ + 0,0,0,0,0,0, /* stack1, stack2 */ \ + 0, /* cr3 */ \ + 0,0, /* eip,eflags */ \ + 0,0,0,0, /* eax,ecx,edx,ebx */ \ + 0,0,0,0, /* esp,ebp,esi,edi */ \ + 0,0,0,0,0,0, /* es,cs,ss */ \ + 0,0,0,0,0,0, /* ds,fs,gs */ \ + __LDT(0),0, /* ldt */ \ + 0, INVALID_IO_BITMAP_OFFSET, /* tace, bitmap */ \ + {~0, } /* ioperm */ \ +} + +#define start_thread(regs, new_eip, new_esp) do { \ + __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \ + set_fs(USER_DS); \ + regs->xds = __USER_DS; \ + regs->xes = __USER_DS; \ + regs->xss = __USER_DS; \ + regs->xcs = __USER_CS; \ + regs->eip = new_eip; \ + regs->esp = new_esp; \ +} while (0) + +/* Forward declaration, a strange C thing */ +struct task_struct; +struct mm_struct; + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); +/* + * create a kernel thread without removing it from tasklists + */ +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +/* Copy and release all segment info associated with a VM */ +extern void copy_segments(struct task_struct *p, struct mm_struct * mm); +extern void release_segments(struct mm_struct * mm); + +/* + * Return saved PC of a blocked thread. + */ +static inline unsigned long thread_saved_pc(struct thread_struct *t) +{ + return ((unsigned long *)t->esp)[3]; +} + +unsigned long get_wchan(struct task_struct *p); +#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) +#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) + +#define THREAD_SIZE (2*PAGE_SIZE) +#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) +#define free_task_struct(p) free_pages((unsigned long) (p), 1) +#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) + +#define init_task (init_task_union.task) +#define init_stack (init_task_union.stack) + +struct microcode { + unsigned int hdrver; + unsigned int rev; + unsigned int date; + unsigned int sig; + unsigned int cksum; + unsigned int ldrver; + unsigned int pf; + unsigned int reserved[5]; + unsigned int bits[500]; +}; + +/* '6' because it used to be for P6 only (but now covers Pentium 4 as well) */ +#define MICROCODE_IOCFREE _IO('6',0) + +/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ +static inline void rep_nop(void) +{ + __asm__ __volatile__("rep;nop" ::: "memory"); +} + +#define cpu_relax() rep_nop() + +/* Prefetch instructions for Pentium III and AMD Athlon */ +#if defined(CONFIG_MPENTIUMIII) || defined (CONFIG_MPENTIUM4) + +#define ARCH_HAS_PREFETCH +extern inline void prefetch(const void *x) +{ + __asm__ __volatile__ ("prefetchnta (%0)" : : "r"(x)); +} + +#elif CONFIG_X86_USE_3DNOW + +#define ARCH_HAS_PREFETCH +#define ARCH_HAS_PREFETCHW +#define ARCH_HAS_SPINLOCK_PREFETCH + +extern inline void prefetch(const void *x) +{ + __asm__ __volatile__ ("prefetch (%0)" : : "r"(x)); +} + +extern inline void prefetchw(const void *x) +{ + __asm__ __volatile__ ("prefetchw (%0)" : : "r"(x)); +} +#define spin_lock_prefetch(x) prefetchw(x) + +#endif + +#endif /* __ASM_I386_PROCESSOR_H */ diff -ruN linux-2.4.23-pre6/include/asm/ptrace.h linux-2.4.23-pre6-swsusp/include/asm/ptrace.h --- linux-2.4.23-pre6/include/asm/ptrace.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/ptrace.h 2001-09-15 06:04:08.000000000 +0900 @@ -0,0 +1,63 @@ +#ifndef _I386_PTRACE_H +#define _I386_PTRACE_H + +#define EBX 0 +#define ECX 1 +#define EDX 2 +#define ESI 3 +#define EDI 4 +#define EBP 5 +#define EAX 6 +#define DS 7 +#define ES 8 +#define FS 9 +#define GS 10 +#define ORIG_EAX 11 +#define EIP 12 +#define CS 13 +#define EFL 14 +#define UESP 15 +#define SS 16 +#define FRAME_SIZE 17 + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + int xds; + int xes; + long orig_eax; + long eip; + int xcs; + long eflags; + long esp; + int xss; +}; + +/* 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 __KERNEL__ +#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) +#define instruction_pointer(regs) ((regs)->eip) +extern void show_regs(struct pt_regs *); +#endif + +#endif diff -ruN linux-2.4.23-pre6/include/asm/resource.h linux-2.4.23-pre6-swsusp/include/asm/resource.h --- linux-2.4.23-pre6/include/asm/resource.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/resource.h 2000-09-23 06:21:19.000000000 +0900 @@ -0,0 +1,47 @@ +#ifndef _I386_RESOURCE_H +#define _I386_RESOURCE_H + +/* + * Resource limits + */ + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_RSS 5 /* max resident set size */ +#define RLIMIT_NPROC 6 /* max number of processes */ +#define RLIMIT_NOFILE 7 /* max number of open files */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ +#define RLIMIT_AS 9 /* address space limit */ +#define RLIMIT_LOCKS 10 /* maximum file locks held */ + +#define RLIM_NLIMITS 11 + +/* + * SuS says limits have to be unsigned. + * Which makes a ton more sense anyway. + */ +#define RLIM_INFINITY (~0UL) + +#ifdef __KERNEL__ + +#define INIT_RLIMITS \ +{ \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { _STK_LIM, RLIM_INFINITY }, \ + { 0, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ + { INR_OPEN, INR_OPEN }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ +} + +#endif /* __KERNEL__ */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/rwlock.h linux-2.4.23-pre6-swsusp/include/asm/rwlock.h --- linux-2.4.23-pre6/include/asm/rwlock.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/rwlock.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,83 @@ +/* include/asm-i386/rwlock.h + * + * Helpers used by both rw spinlocks and rw semaphores. + * + * Based in part on code from semaphore.h and + * spinlock.h Copyright 1996 Linus Torvalds. + * + * Copyright 1999 Red Hat, Inc. + * + * Written by Benjamin LaHaise. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_I386_RWLOCK_H +#define _ASM_I386_RWLOCK_H + +#define RW_LOCK_BIAS 0x01000000 +#define RW_LOCK_BIAS_STR "0x01000000" + +#define __build_read_lock_ptr(rw, helper) \ + asm volatile(LOCK "subl $1,(%0)\n\t" \ + "js 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2:\tcall " helper "\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + ::"a" (rw) : "memory") + +#define __build_read_lock_const(rw, helper) \ + asm volatile(LOCK "subl $1,%0\n\t" \ + "js 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2:\tpushl %%eax\n\t" \ + "leal %0,%%eax\n\t" \ + "call " helper "\n\t" \ + "popl %%eax\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + :"=m" (*(volatile int *)rw) : : "memory") + +#define __build_read_lock(rw, helper) do { \ + if (__builtin_constant_p(rw)) \ + __build_read_lock_const(rw, helper); \ + else \ + __build_read_lock_ptr(rw, helper); \ + } while (0) + +#define __build_write_lock_ptr(rw, helper) \ + asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ + "jnz 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2:\tcall " helper "\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + ::"a" (rw) : "memory") + +#define __build_write_lock_const(rw, helper) \ + asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ + "jnz 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2:\tpushl %%eax\n\t" \ + "leal %0,%%eax\n\t" \ + "call " helper "\n\t" \ + "popl %%eax\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + :"=m" (*(volatile int *)rw) : : "memory") + +#define __build_write_lock(rw, helper) do { \ + if (__builtin_constant_p(rw)) \ + __build_write_lock_const(rw, helper); \ + else \ + __build_write_lock_ptr(rw, helper); \ + } while (0) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/rwsem.h linux-2.4.23-pre6-swsusp/include/asm/rwsem.h --- linux-2.4.23-pre6/include/asm/rwsem.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/rwsem.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,264 @@ +/* rwsem.h: R/W semaphores implemented using XADD/CMPXCHG for i486+ + * + * Written by David Howells (dhowells@redhat.com). + * + * Derived from asm-i386/semaphore.h + * + * Trylock by Brian Watson (Brian.J.Watson@compaq.com). + * + * + * The MSW of the count is the negated number of active writers and waiting + * lockers, and the LSW is the total number of active locks + * + * The lock count is initialized to 0 (no active and no waiting lockers). + * + * When a writer subtracts WRITE_BIAS, it'll get 0xffff0001 for the case of an + * uncontended lock. This can be determined because XADD returns the old value. + * Readers increment by 1 and see a positive value when uncontended, negative + * if there are writers (and maybe) readers waiting (in which case it goes to + * sleep). + * + * The value of WAITING_BIAS supports up to 32766 waiting processes. This can + * be extended to 65534 by manually checking the whole MSW rather than relying + * on the S flag. + * + * The value of ACTIVE_BIAS supports up to 65535 active processes. + * + * This should be totally fair - if anything is waiting, a process that wants a + * lock will go to the back of the queue. When the currently active lock is + * released, if there's a writer at the front of the queue, then that and only + * that will be woken up; if there's a bunch of consequtive readers at the + * front, then they'll all be woken up, but no other readers will be. + */ + +#ifndef _I386_RWSEM_H +#define _I386_RWSEM_H + +#ifndef _LINUX_RWSEM_H +#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead +#endif + +#ifdef __KERNEL__ + +#include +#include + +struct rwsem_waiter; + +extern struct rw_semaphore *FASTCALL(rwsem_down_read_failed(struct rw_semaphore *sem)); +extern struct rw_semaphore *FASTCALL(rwsem_down_write_failed(struct rw_semaphore *sem)); +extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *)); + +/* + * the semaphore definition + */ +struct rw_semaphore { + signed long count; +#define RWSEM_UNLOCKED_VALUE 0x00000000 +#define RWSEM_ACTIVE_BIAS 0x00000001 +#define RWSEM_ACTIVE_MASK 0x0000ffff +#define RWSEM_WAITING_BIAS (-0x00010000) +#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS +#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) + spinlock_t wait_lock; + struct list_head wait_list; +#if RWSEM_DEBUG + int debug; +#endif +}; + +/* + * initialisation + */ +#if RWSEM_DEBUG +#define __RWSEM_DEBUG_INIT , 0 +#else +#define __RWSEM_DEBUG_INIT /* */ +#endif + +#define __RWSEM_INITIALIZER(name) \ +{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \ + __RWSEM_DEBUG_INIT } + +#define DECLARE_RWSEM(name) \ + struct rw_semaphore name = __RWSEM_INITIALIZER(name) + +static inline void init_rwsem(struct rw_semaphore *sem) +{ + sem->count = RWSEM_UNLOCKED_VALUE; + spin_lock_init(&sem->wait_lock); + INIT_LIST_HEAD(&sem->wait_list); +#if RWSEM_DEBUG + sem->debug = 0; +#endif +} + +/* + * lock for reading + */ +static inline void __down_read(struct rw_semaphore *sem) +{ + __asm__ __volatile__( + "# beginning down_read\n\t" +LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ + " js 2f\n\t" /* jump if we weren't granted the lock */ + "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " pushl %%ecx\n\t" + " pushl %%edx\n\t" + " call rwsem_down_read_failed\n\t" + " popl %%edx\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END + "# ending down_read\n\t" + : "+m"(sem->count) + : "a"(sem) + : "memory", "cc"); +} + +/* + * trylock for reading -- returns 1 if successful, 0 if contention + */ +static inline int __down_read_trylock(struct rw_semaphore *sem) +{ + __s32 result, tmp; + __asm__ __volatile__( + "# beginning __down_read_trylock\n\t" + " movl %0,%1\n\t" + "1:\n\t" + " movl %1,%2\n\t" + " addl %3,%2\n\t" + " jle 2f\n\t" +LOCK_PREFIX " cmpxchgl %2,%0\n\t" + " jnz 1b\n\t" + "2:\n\t" + "# ending __down_read_trylock\n\t" + : "+m"(sem->count), "=&a"(result), "=&r"(tmp) + : "i"(RWSEM_ACTIVE_READ_BIAS) + : "memory", "cc"); + return result>=0 ? 1 : 0; +} + +/* + * lock for writing + */ +static inline void __down_write(struct rw_semaphore *sem) +{ + int tmp; + + tmp = RWSEM_ACTIVE_WRITE_BIAS; + __asm__ __volatile__( + "# beginning down_write\n\t" +LOCK_PREFIX " xadd %0,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ + " testl %0,%0\n\t" /* was the count 0 before? */ + " jnz 2f\n\t" /* jump if we weren't granted the lock */ + "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " pushl %%ecx\n\t" + " call rwsem_down_write_failed\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END + "# ending down_write" + : "+d"(tmp), "+m"(sem->count) + : "a"(sem) + : "memory", "cc"); +} + +/* + * trylock for writing -- returns 1 if successful, 0 if contention + */ +static inline int __down_write_trylock(struct rw_semaphore *sem) +{ + signed long ret = cmpxchg(&sem->count, + RWSEM_UNLOCKED_VALUE, + RWSEM_ACTIVE_WRITE_BIAS); + if (ret == RWSEM_UNLOCKED_VALUE) + return 1; + return 0; +} + +/* + * unlock after reading + */ +static inline void __up_read(struct rw_semaphore *sem) +{ + __s32 tmp = -RWSEM_ACTIVE_READ_BIAS; + __asm__ __volatile__( + "# beginning __up_read\n\t" +LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ + " js 2f\n\t" /* jump if the lock is being waited upon */ + "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " decw %%dx\n\t" /* do nothing if still outstanding active readers */ + " jnz 1b\n\t" + " pushl %%ecx\n\t" + " call rwsem_wake\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END + "# ending __up_read\n" + : "+m"(sem->count), "+d"(tmp) + : "a"(sem) + : "memory", "cc"); +} + +/* + * unlock after writing + */ +static inline void __up_write(struct rw_semaphore *sem) +{ + __asm__ __volatile__( + "# beginning __up_write\n\t" + " movl %2,%%edx\n\t" +LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ + " jnz 2f\n\t" /* jump if the lock is being waited upon */ + "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " decw %%dx\n\t" /* did the active count reduce to 0? */ + " jnz 1b\n\t" /* jump back if not */ + " pushl %%ecx\n\t" + " call rwsem_wake\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END + "# ending __up_write\n" + : "+m"(sem->count) + : "a"(sem), "i"(-RWSEM_ACTIVE_WRITE_BIAS) + : "memory", "cc", "edx"); +} + +/* + * implement atomic add functionality + */ +static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) +{ + __asm__ __volatile__( +LOCK_PREFIX "addl %1,%0" + :"=m"(sem->count) + :"ir"(delta), "m"(sem->count)); +} + +/* + * implement exchange and add functionality + */ +static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) +{ + int tmp = delta; + + __asm__ __volatile__( +LOCK_PREFIX "xadd %0,(%2)" + : "+r"(tmp), "=m"(sem->count) + : "r"(sem), "m"(sem->count) + : "memory"); + + return tmp+delta; +} + +#endif /* __KERNEL__ */ +#endif /* _I386_RWSEM_H */ diff -ruN linux-2.4.23-pre6/include/asm/save_state.h linux-2.4.23-pre6-swsusp/include/asm/save_state.h --- linux-2.4.23-pre6/include/asm/save_state.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/save_state.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,212 @@ +#ifndef __ASM_I386_SAVE_STATE_H +#define __ASM_I386_SAVE_STATE_H + +/* + * Copyright 2001-2002 Pavel Machek + * Based on code + * Copyright 2001 Patrick Mochel + */ +#include +#include + +/* image of the saved processor state */ +struct saved_context { + u32 eax, ebx, ecx, edx; + u32 esp, ebp, esi, edi; + u16 es, fs, gs, ss; + u32 cr0, cr2, cr3, cr4; + u16 gdt_pad; + u16 gdt_limit; + u32 gdt_base; + u16 idt_pad; + u16 idt_limit; + u32 idt_base; + u16 ldt; + u16 tss; + u32 tr; + u32 safety; + u32 return_address; + u32 eflags; +} __attribute__((packed)); + +static struct saved_context saved_context; + +#define loaddebug(thread,register) \ + __asm__("movl %0,%%db" #register \ + : /* no output */ \ + :"r" ((thread)->debugreg[register])) + + +/* + * save_processor_context + * + * Save the state of the processor before we go to sleep. + * + * return_stack is the value of the stack pointer (%esp) as the caller sees it. + * A good way could not be found to obtain it from here (don't want to make _too_ + * many assumptions about the layout of the stack this far down.) Also, the + * handy little __builtin_frame_pointer(level) where level > 0, is blatantly + * buggy - it returns the value of the stack at the proper location, not the + * location, like it should (as of gcc 2.91.66) + * + * Note that the context and timing of this function is pretty critical. + * With a minimal amount of things going on in the caller and in here, gcc + * does a good job of being just a dumb compiler. Watch the assembly output + * if anything changes, though, and make sure everything is going in the right + * place. + */ +static inline void save_processor_context (void) +{ + kernel_fpu_begin(); + + /* + * descriptor tables + */ + asm volatile ("sgdt (%0)" : "=m" (saved_context.gdt_limit)); + asm volatile ("sidt (%0)" : "=m" (saved_context.idt_limit)); + asm volatile ("sldt (%0)" : "=m" (saved_context.ldt)); + asm volatile ("str (%0)" : "=m" (saved_context.tr)); + + /* + * save the general registers. + * note that gcc has constructs to specify output of certain registers, + * but they're not used here, because it assumes that you want to modify + * those registers, so it tries to be smart and save them beforehand. + * It's really not necessary, and kinda fishy (check the assembly output), + * so it's avoided. + */ + asm volatile ("movl %%esp, (%0)" : "=m" (saved_context.esp)); + asm volatile ("movl %%eax, (%0)" : "=m" (saved_context.eax)); + asm volatile ("movl %%ebx, (%0)" : "=m" (saved_context.ebx)); + asm volatile ("movl %%ecx, (%0)" : "=m" (saved_context.ecx)); + asm volatile ("movl %%edx, (%0)" : "=m" (saved_context.edx)); + asm volatile ("movl %%ebp, (%0)" : "=m" (saved_context.ebp)); + asm volatile ("movl %%esi, (%0)" : "=m" (saved_context.esi)); + asm volatile ("movl %%edi, (%0)" : "=m" (saved_context.edi)); + + /* + * segment registers + */ + asm volatile ("movw %%es, %0" : "=r" (saved_context.es)); + asm volatile ("movw %%fs, %0" : "=r" (saved_context.fs)); + asm volatile ("movw %%gs, %0" : "=r" (saved_context.gs)); + asm volatile ("movw %%ss, %0" : "=r" (saved_context.ss)); + + /* + * control registers + */ + asm volatile ("movl %%cr0, %0" : "=r" (saved_context.cr0)); + asm volatile ("movl %%cr2, %0" : "=r" (saved_context.cr2)); + asm volatile ("movl %%cr3, %0" : "=r" (saved_context.cr3)); + asm volatile ("movl %%cr4, %0" : "=r" (saved_context.cr4)); + + /* + * eflags + */ + asm volatile ("pushfl ; popl (%0)" : "=m" (saved_context.eflags)); +} + +static void fix_processor_context(void) +{ + int nr = smp_processor_id(); + struct tss_struct * t = &init_tss[nr]; + + set_tss_desc(nr,t); /* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy tsc or some similar stupidity. */ + gdt_table[__TSS(nr)].b &= 0xfffffdff; + + load_TR(nr); /* This does ltr */ + __load_LDT(nr); /* This does lldt */ + + /* + * Now maybe reload the debug registers + */ + if (current->thread.debugreg[7]){ + loaddebug(¤t->thread, 0); + loaddebug(¤t->thread, 1); + loaddebug(¤t->thread, 2); + loaddebug(¤t->thread, 3); + /* no 4 and 5 */ + loaddebug(¤t->thread, 6); + loaddebug(¤t->thread, 7); + } + +} + +static void +do_fpu_end(void) +{ + /* restore FPU regs if necessary */ + /* Do it out of line so that gcc does not move cr0 load to some stupid place */ + kernel_fpu_end(); +} + +/* + * restore_processor_context + * + * Restore the processor context as it was before we went to sleep + * - descriptor tables + * - control registers + * - segment registers + * - flags + * + * Note that it is critical that this function is declared inline. + * It was separated out from restore_state to make that function + * a little clearer, but it needs to be inlined because we won't have a + * stack when we get here (so we can't push a return address). + */ +static inline void restore_processor_context (void) +{ + /* + * first restore %ds, so we can access our data properly + */ + asm volatile (".align 4"); + asm volatile ("movw %0, %%ds" :: "r" ((u16)__KERNEL_DS)); + + + /* + * control registers + */ + asm volatile ("movl %0, %%cr4" :: "r" (saved_context.cr4)); + asm volatile ("movl %0, %%cr3" :: "r" (saved_context.cr3)); + asm volatile ("movl %0, %%cr2" :: "r" (saved_context.cr2)); + asm volatile ("movl %0, %%cr0" :: "r" (saved_context.cr0)); + + /* + * segment registers + */ + asm volatile ("movw %0, %%es" :: "r" (saved_context.es)); + asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs)); + asm volatile ("movw %0, %%gs" :: "r" (saved_context.gs)); + asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss)); + + /* + * the other general registers + * + * note that even though gcc has constructs to specify memory + * input into certain registers, it will try to be too smart + * and save them at the beginning of the function. This is esp. + * bad since we don't have a stack set up when we enter, and we + * want to preserve the values on exit. So, we set them manually. + */ + asm volatile ("movl %0, %%esp" :: "m" (saved_context.esp)); + asm volatile ("movl %0, %%ebp" :: "m" (saved_context.ebp)); + asm volatile ("movl %0, %%eax" :: "m" (saved_context.eax)); + asm volatile ("movl %0, %%ebx" :: "m" (saved_context.ebx)); + asm volatile ("movl %0, %%ecx" :: "m" (saved_context.ecx)); + asm volatile ("movl %0, %%edx" :: "m" (saved_context.edx)); + asm volatile ("movl %0, %%esi" :: "m" (saved_context.esi)); + asm volatile ("movl %0, %%edi" :: "m" (saved_context.edi)); + + /* + * now restore the descriptor tables to their proper values + */ + asm volatile ("lgdt (%0)" :: "m" (saved_context.gdt_limit)); + asm volatile ("lidt (%0)" :: "m" (saved_context.idt_limit)); + asm volatile ("lldt (%0)" :: "m" (saved_context.ldt)); + + fix_processor_context(); + do_fpu_end(); +} + +#endif + diff -ruN linux-2.4.23-pre6/include/asm/scatterlist.h linux-2.4.23-pre6-swsusp/include/asm/scatterlist.h --- linux-2.4.23-pre6/include/asm/scatterlist.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/scatterlist.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,34 @@ +#ifndef _I386_SCATTERLIST_H +#define _I386_SCATTERLIST_H + +/* + * Drivers must set either ->address or (preferred) ->page and ->offset + * to indicate where data must be transferred to/from. + * + * Using ->page is recommended since it handles highmem data as well as + * low mem. ->address is restricted to data which has a virtual mapping, and + * it will go away in the future. Updating to ->page can be automated very + * easily -- something like + * + * sg->address = some_ptr; + * + * can be rewritten as + * + * sg->page = virt_to_page(some_ptr); + * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK; + * + * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens + */ +struct scatterlist { + char * address; /* Location data is to be transferred to, NULL for + * highmem page */ + struct page * page; /* Location for highmem page, if any */ + unsigned int offset;/* for highmem, page offset */ + + dma_addr_t dma_address; + unsigned int length; +}; + +#define ISA_DMA_THRESHOLD (0x00ffffff) + +#endif /* !(_I386_SCATTERLIST_H) */ diff -ruN linux-2.4.23-pre6/include/asm/segment.h linux-2.4.23-pre6-swsusp/include/asm/segment.h --- linux-2.4.23-pre6/include/asm/segment.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/segment.h 1997-12-02 03:34:12.000000000 +0900 @@ -0,0 +1,10 @@ +#ifndef _ASM_SEGMENT_H +#define _ASM_SEGMENT_H + +#define __KERNEL_CS 0x10 +#define __KERNEL_DS 0x18 + +#define __USER_CS 0x23 +#define __USER_DS 0x2B + +#endif diff -ruN linux-2.4.23-pre6/include/asm/semaphore.h linux-2.4.23-pre6-swsusp/include/asm/semaphore.h --- linux-2.4.23-pre6/include/asm/semaphore.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/semaphore.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,222 @@ +#ifndef _I386_SEMAPHORE_H +#define _I386_SEMAPHORE_H + +#include + +#ifdef __KERNEL__ + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + * + * Modified 1996-12-23 by Dave Grothe to fix bugs in + * the original code and to make semaphore waits + * interruptible so that processes waiting on + * semaphores can be killed. + * Modified 1999-02-14 by Andrea Arcangeli, split the sched.c helper + * functions in asm/sempahore-helper.h while fixing a + * potential and subtle race discovered by Ulrich Schmid + * in down_interruptible(). Since I started to play here I + * also implemented the `trylock' semaphore operation. + * 1999-07-02 Artur Skawina + * Optimized "0(ecx)" -> "(ecx)" (the assembler does not + * do this). Changed calling sequences from push/jmp to + * traditional call/ret. + * Modified 2001-01-01 Andreas Franck + * Some hacks to ensure compatibility with recent + * GCC snapshots, to avoid stack corruption when compiling + * with -fomit-frame-pointer. It's not sure if this will + * be fixed in GCC, as our previous implementation was a + * bit dubious. + * + * If you would like to see an analysis of this implementation, please + * ftp to gcom.com and download the file + * /pub/linux/src/semaphore/semaphore-2.0.24.tar.gz. + * + */ + +#include +#include +#include +#include + +struct semaphore { + atomic_t count; + int sleepers; + wait_queue_head_t wait; +#if WAITQUEUE_DEBUG + long __magic; +#endif +}; + +#if WAITQUEUE_DEBUG +# define __SEM_DEBUG_INIT(name) \ + , (int)&(name).__magic +#else +# define __SEM_DEBUG_INIT(name) +#endif + +#define __SEMAPHORE_INITIALIZER(name,count) \ +{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + __SEM_DEBUG_INIT(name) } + +#define __MUTEX_INITIALIZER(name) \ + __SEMAPHORE_INITIALIZER(name,1) + +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) + +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) + +static inline void sema_init (struct semaphore *sem, int val) +{ +/* + * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); + * + * i'd rather use the more flexible initialization above, but sadly + * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. + */ + atomic_set(&sem->count, val); + sem->sleepers = 0; + init_waitqueue_head(&sem->wait); +#if WAITQUEUE_DEBUG + sem->__magic = (int)&sem->__magic; +#endif +} + +static inline void init_MUTEX (struct semaphore *sem) +{ + sema_init(sem, 1); +} + +static inline void init_MUTEX_LOCKED (struct semaphore *sem) +{ + sema_init(sem, 0); +} + +asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage int __down_failed_interruptible(void /* params in registers */); +asmlinkage int __down_failed_trylock(void /* params in registers */); +asmlinkage void __up_wakeup(void /* special register calling convention */); + +asmlinkage void __down(struct semaphore * sem); +asmlinkage int __down_interruptible(struct semaphore * sem); +asmlinkage int __down_trylock(struct semaphore * sem); +asmlinkage void __up(struct semaphore * sem); + +/* + * This is ugly, but we want the default case to fall through. + * "__down_failed" is a special asm handler that calls the C + * routine that actually waits. See arch/i386/kernel/semaphore.c + */ +static inline void down(struct semaphore * sem) +{ +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + __asm__ __volatile__( + "# atomic down operation\n\t" + LOCK "decl %0\n\t" /* --sem->count */ + "js 2f\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tcall __down_failed\n\t" + "jmp 1b\n" + LOCK_SECTION_END + :"=m" (sem->count) + :"c" (sem) + :"memory"); +} + +/* + * Interruptible try to acquire a semaphore. If we obtained + * it, return zero. If we were interrupted, returns -EINTR + */ +static inline int down_interruptible(struct semaphore * sem) +{ + int result; + +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + __asm__ __volatile__( + "# atomic interruptible down operation\n\t" + LOCK "decl %1\n\t" /* --sem->count */ + "js 2f\n\t" + "xorl %0,%0\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tcall __down_failed_interruptible\n\t" + "jmp 1b\n" + LOCK_SECTION_END + :"=a" (result), "=m" (sem->count) + :"c" (sem) + :"memory"); + return result; +} + +/* + * Non-blockingly attempt to down() a semaphore. + * Returns zero if we acquired it + */ +static inline int down_trylock(struct semaphore * sem) +{ + int result; + +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + __asm__ __volatile__( + "# atomic interruptible down operation\n\t" + LOCK "decl %1\n\t" /* --sem->count */ + "js 2f\n\t" + "xorl %0,%0\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tcall __down_failed_trylock\n\t" + "jmp 1b\n" + LOCK_SECTION_END + :"=a" (result), "=m" (sem->count) + :"c" (sem) + :"memory"); + return result; +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +static inline void up(struct semaphore * sem) +{ +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__( + "# atomic up operation\n\t" + LOCK "incl %0\n\t" /* ++sem->count */ + "jle 2f\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tcall __up_wakeup\n\t" + "jmp 1b\n" + LOCK_SECTION_END + ".subsection 0\n" + :"=m" (sem->count) + :"c" (sem) + :"memory"); +} + +static inline int sem_getcount(struct semaphore *sem) +{ + return atomic_read(&sem->count); +} + +#endif +#endif diff -ruN linux-2.4.23-pre6/include/asm/sembuf.h linux-2.4.23-pre6-swsusp/include/asm/sembuf.h --- linux-2.4.23-pre6/include/asm/sembuf.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/sembuf.h 2000-01-11 11:15:58.000000000 +0900 @@ -0,0 +1,25 @@ +#ifndef _I386_SEMBUF_H +#define _I386_SEMBUF_H + +/* + * The semid64_ds structure for i386 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _I386_SEMBUF_H */ diff -ruN linux-2.4.23-pre6/include/asm/serial.h linux-2.4.23-pre6-swsusp/include/asm/serial.h --- linux-2.4.23-pre6/include/asm/serial.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/serial.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,148 @@ +/* + * include/asm-i386/serial.h + */ + +#include + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD ( 1843200 / 16 ) + +/* Standard COM flags (except for COM4, because of the 8514 problem) */ +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF +#endif + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define FOURPORT_FLAGS ASYNC_FOURPORT +#define ACCENT_FLAGS 0 +#define BOCA_FLAGS 0 +#define HUB6_FLAGS 0 +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE +#endif + +#define MCA_COM_FLAGS (STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA) + +/* + * The following define the access methods for the HUB6 card. All + * access is through two ports for all 24 possible chips. The card is + * selected through the high 2 bits, the port on that card with the + * "middle" 3 bits, and the register on that port with the bottom + * 3 bits. + * + * While the access port and interrupt is configurable, the default + * port locations are 0x302 for the port control register, and 0x303 + * for the data read/write register. Normally, the interrupt is at irq3 + * but can be anything from 3 to 7 inclusive. Note that using 3 will + * require disabling com2. + */ + +#define C_P(card,port) (((card)<<6|(port)<<3) + 1) + +#define STD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ + +/* + * HCDP_SERIAL_PORT_DEFNS should be placed in exactly the same slot + * in rs_table as defined by HCDP_SERIAL_CONSOLE_PORT in + * include/linux/serial.h + */ +#define HCDP_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, -1, 0, STD_COM_FLAGS}, /* ttySx device + in comments sucks. + You add an entry + and you get to edit + boatloads of these + comments. Not worth + it */ + + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define EXTRA_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ + { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ + { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ + { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ + { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ + { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ + { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ + { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ + { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ + { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ + { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ + { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ + { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ + { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ + { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ + { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ + { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ + { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ + { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ + { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ + { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ + { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ + { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ + { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ + { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ + { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ + { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ + { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ +#else +#define EXTRA_SERIAL_PORT_DEFNS +#endif + +/* You can have up to four HUB6's in the system, but I've only + * included two cards here for a total of twelve ports. + */ +#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) +#define HUB6_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ +#else +#define HUB6_SERIAL_PORT_DFNS +#endif + +#ifdef CONFIG_MCA +#define MCA_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS }, \ + { 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS }, \ + { 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS }, \ + { 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS }, \ + { 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS }, \ + { 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS }, +#else +#define MCA_SERIAL_PORT_DFNS +#endif + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DEFNS \ + HCDP_SERIAL_PORT_DEFNS \ + EXTRA_SERIAL_PORT_DEFNS \ + HUB6_SERIAL_PORT_DFNS \ + MCA_SERIAL_PORT_DFNS + diff -ruN linux-2.4.23-pre6/include/asm/setup.h linux-2.4.23-pre6-swsusp/include/asm/setup.h --- linux-2.4.23-pre6/include/asm/setup.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/setup.h 1999-11-13 03:12:11.000000000 +0900 @@ -0,0 +1,10 @@ +/* + * Just a place holder. We don't want to have to test x86 before + * we include stuff + */ + +#ifndef _i386_SETUP_H +#define _i386_SETUP_H + + +#endif /* _i386_SETUP_H */ diff -ruN linux-2.4.23-pre6/include/asm/shmbuf.h linux-2.4.23-pre6-swsusp/include/asm/shmbuf.h --- linux-2.4.23-pre6/include/asm/shmbuf.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/shmbuf.h 2000-01-11 11:15:58.000000000 +0900 @@ -0,0 +1,42 @@ +#ifndef _I386_SHMBUF_H +#define _I386_SHMBUF_H + +/* + * The shmid64_ds structure for i386 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _I386_SHMBUF_H */ diff -ruN linux-2.4.23-pre6/include/asm/shmparam.h linux-2.4.23-pre6-swsusp/include/asm/shmparam.h --- linux-2.4.23-pre6/include/asm/shmparam.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/shmparam.h 1999-11-04 04:31:09.000000000 +0900 @@ -0,0 +1,6 @@ +#ifndef _ASMI386_SHMPARAM_H +#define _ASMI386_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _ASMI386_SHMPARAM_H */ diff -ruN linux-2.4.23-pre6/include/asm/sigcontext.h linux-2.4.23-pre6-swsusp/include/asm/sigcontext.h --- linux-2.4.23-pre6/include/asm/sigcontext.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/sigcontext.h 2000-06-22 12:59:38.000000000 +0900 @@ -0,0 +1,83 @@ +#ifndef _ASMi386_SIGCONTEXT_H +#define _ASMi386_SIGCONTEXT_H + +/* + * As documented in the iBCS2 standard.. + * + * The first part of "struct _fpstate" is just the normal i387 + * hardware setup, the extra "status" word is used to save the + * coprocessor status word before entering the handler. + * + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 + * + * The FPU state data structure has had to grow to accomodate the + * extended FPU state required by the Streaming SIMD Extensions. + * There is no documented standard to accomplish this at the moment. + */ +struct _fpreg { + unsigned short significand[4]; + unsigned short exponent; +}; + +struct _fpxreg { + unsigned short significand[4]; + unsigned short exponent; + unsigned short padding[3]; +}; + +struct _xmmreg { + unsigned long element[4]; +}; + +struct _fpstate { + /* Regular FPU environment */ + unsigned long cw; + unsigned long sw; + unsigned long tag; + unsigned long ipoff; + unsigned long cssel; + unsigned long dataoff; + unsigned long datasel; + struct _fpreg _st[8]; + unsigned short status; + unsigned short magic; /* 0xffff = regular FPU data only */ + + /* FXSR FPU environment */ + unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ + unsigned long mxcsr; + unsigned long reserved; + struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ + struct _xmmreg _xmm[8]; + unsigned long padding[56]; +}; + +#define X86_FXSR_MAGIC 0x0000 + +struct sigcontext { + unsigned short gs, __gsh; + unsigned short fs, __fsh; + unsigned short es, __esh; + unsigned short ds, __dsh; + unsigned long edi; + unsigned long esi; + unsigned long ebp; + unsigned long esp; + unsigned long ebx; + unsigned long edx; + unsigned long ecx; + unsigned long eax; + unsigned long trapno; + unsigned long err; + unsigned long eip; + unsigned short cs, __csh; + unsigned long eflags; + unsigned long esp_at_signal; + unsigned short ss, __ssh; + struct _fpstate * fpstate; + unsigned long oldmask; + unsigned long cr2; +}; + + +#endif diff -ruN linux-2.4.23-pre6/include/asm/siginfo.h linux-2.4.23-pre6-swsusp/include/asm/siginfo.h --- linux-2.4.23-pre6/include/asm/siginfo.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/siginfo.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,233 @@ +#ifndef _I386_SIGINFO_H +#define _I386_SIGINFO_H + +#include + +/* XXX: This structure was copied from the Alpha; is there an iBCS version? */ + +typedef union sigval { + int sival_int; + void *sival_ptr; +} sigval_t; + +#define SI_MAX_SIZE 128 +#define SI_PAD_SIZE ((SI_MAX_SIZE/sizeof(int)) - 3) + +typedef struct siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[SI_PAD_SIZE]; + + /* kill() */ + struct { + pid_t _pid; /* sender's pid */ + uid_t _uid; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + unsigned int _timer1; + unsigned int _timer2; + } _timer; + + /* POSIX.1b signals */ + struct { + pid_t _pid; /* sender's pid */ + uid_t _uid; /* sender's uid */ + sigval_t _sigval; + } _rt; + + /* SIGCHLD */ + struct { + pid_t _pid; /* which child */ + uid_t _uid; /* sender's uid */ + int _status; /* exit code */ + clock_t _utime; + clock_t _stime; + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + void *_addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} siginfo_t; + +/* + * How these fields are to be accessed. + */ +#define si_pid _sifields._kill._pid +#define si_uid _sifields._kill._uid +#define si_status _sifields._sigchld._status +#define si_utime _sifields._sigchld._utime +#define si_stime _sifields._sigchld._stime +#define si_value _sifields._rt._sigval +#define si_int _sifields._rt._sigval.sival_int +#define si_ptr _sifields._rt._sigval.sival_ptr +#define si_addr _sifields._sigfault._addr +#define si_band _sifields._sigpoll._band +#define si_fd _sifields._sigpoll._fd + +#ifdef __KERNEL__ +#define __SI_MASK 0xffff0000 +#define __SI_KILL (0 << 16) +#define __SI_TIMER (1 << 16) +#define __SI_POLL (2 << 16) +#define __SI_FAULT (3 << 16) +#define __SI_CHLD (4 << 16) +#define __SI_RT (5 << 16) +#define __SI_CODE(T,N) ((T) << 16 | ((N) & 0xffff)) +#else +#define __SI_KILL 0 +#define __SI_TIMER 0 +#define __SI_POLL 0 +#define __SI_FAULT 0 +#define __SI_CHLD 0 +#define __SI_RT 0 +#define __SI_CODE(T,N) (N) +#endif + +/* + * si_code values + * Digital reserves positive values for kernel-generated signals. + */ +#define SI_USER 0 /* sent by kill, sigsend, raise */ +#define SI_KERNEL 0x80 /* sent by the kernel from somewhere */ +#define SI_QUEUE -1 /* sent by sigqueue */ +#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */ +#define SI_MESGQ -3 /* sent by real time mesq state change */ +#define SI_ASYNCIO -4 /* sent by AIO completion */ +#define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ + +#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) +#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) + +/* + * SIGILL si_codes + */ +#define ILL_ILLOPC (__SI_FAULT|1) /* illegal opcode */ +#define ILL_ILLOPN (__SI_FAULT|2) /* illegal operand */ +#define ILL_ILLADR (__SI_FAULT|3) /* illegal addressing mode */ +#define ILL_ILLTRP (__SI_FAULT|4) /* illegal trap */ +#define ILL_PRVOPC (__SI_FAULT|5) /* privileged opcode */ +#define ILL_PRVREG (__SI_FAULT|6) /* privileged register */ +#define ILL_COPROC (__SI_FAULT|7) /* coprocessor error */ +#define ILL_BADSTK (__SI_FAULT|8) /* internal stack error */ +#define NSIGILL 8 + +/* + * SIGFPE si_codes + */ +#define FPE_INTDIV (__SI_FAULT|1) /* integer divide by zero */ +#define FPE_INTOVF (__SI_FAULT|2) /* integer overflow */ +#define FPE_FLTDIV (__SI_FAULT|3) /* floating point divide by zero */ +#define FPE_FLTOVF (__SI_FAULT|4) /* floating point overflow */ +#define FPE_FLTUND (__SI_FAULT|5) /* floating point underflow */ +#define FPE_FLTRES (__SI_FAULT|6) /* floating point inexact result */ +#define FPE_FLTINV (__SI_FAULT|7) /* floating point invalid operation */ +#define FPE_FLTSUB (__SI_FAULT|8) /* subscript out of range */ +#define NSIGFPE 8 + +/* + * SIGSEGV si_codes + */ +#define SEGV_MAPERR (__SI_FAULT|1) /* address not mapped to object */ +#define SEGV_ACCERR (__SI_FAULT|2) /* invalid permissions for mapped object */ +#define NSIGSEGV 2 + +/* + * SIGBUS si_codes + */ +#define BUS_ADRALN (__SI_FAULT|1) /* invalid address alignment */ +#define BUS_ADRERR (__SI_FAULT|2) /* non-existant physical address */ +#define BUS_OBJERR (__SI_FAULT|3) /* object specific hardware error */ +#define NSIGBUS 3 + +/* + * SIGTRAP si_codes + */ +#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */ +#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */ +#define NSIGTRAP 2 + +/* + * SIGCHLD si_codes + */ +#define CLD_EXITED (__SI_CHLD|1) /* child has exited */ +#define CLD_KILLED (__SI_CHLD|2) /* child was killed */ +#define CLD_DUMPED (__SI_CHLD|3) /* child terminated abnormally */ +#define CLD_TRAPPED (__SI_CHLD|4) /* traced child has trapped */ +#define CLD_STOPPED (__SI_CHLD|5) /* child has stopped */ +#define CLD_CONTINUED (__SI_CHLD|6) /* stopped child has continued */ +#define NSIGCHLD 6 + +/* + * SIGPOLL si_codes + */ +#define POLL_IN (__SI_POLL|1) /* data input available */ +#define POLL_OUT (__SI_POLL|2) /* output buffers available */ +#define POLL_MSG (__SI_POLL|3) /* input message available */ +#define POLL_ERR (__SI_POLL|4) /* i/o error */ +#define POLL_PRI (__SI_POLL|5) /* high priority input available */ +#define POLL_HUP (__SI_POLL|6) /* device disconnected */ +#define NSIGPOLL 6 + +/* + * sigevent definitions + * + * It seems likely that SIGEV_THREAD will have to be handled from + * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the + * thread manager then catches and does the appropriate nonsense. + * However, everything is written out here so as to not get lost. + */ +#define SIGEV_SIGNAL 0 /* notify via signal */ +#define SIGEV_NONE 1 /* other notification: meaningless */ +#define SIGEV_THREAD 2 /* deliver via thread creation */ + +#define SIGEV_MAX_SIZE 64 +#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) + +typedef struct sigevent { + sigval_t sigev_value; + int sigev_signo; + int sigev_notify; + union { + int _pad[SIGEV_PAD_SIZE]; + + struct { + void (*_function)(sigval_t); + void *_attribute; /* really pthread_attr_t */ + } _sigev_thread; + } _sigev_un; +} sigevent_t; + +#define sigev_notify_function _sigev_un._sigev_thread._function +#define sigev_notify_attributes _sigev_un._sigev_thread._attribute + +#ifdef __KERNEL__ +#include + +static inline void copy_siginfo(siginfo_t *to, siginfo_t *from) +{ + if (from->si_code < 0) + memcpy(to, from, sizeof(siginfo_t)); + else + /* _sigchld is currently the largest know union member */ + memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); +} + +extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from); + +#endif /* __KERNEL__ */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/signal.h linux-2.4.23-pre6-swsusp/include/asm/signal.h --- linux-2.4.23-pre6/include/asm/signal.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/signal.h 2001-11-23 04:46:18.000000000 +0900 @@ -0,0 +1,221 @@ +#ifndef _ASMi386_SIGNAL_H +#define _ASMi386_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX (_NSIG-1) + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND +#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ + +#define SA_RESTORER 0x04000000 + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#ifdef __KERNEL__ + +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + * SA_SHIRQ is for shared interrupt support on PCI and EISA. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_SHIRQ 0x04000000 +#endif + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(int); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +#include + +#define __HAVE_ARCH_SIG_BITOPS + +static __inline__ void sigaddset(sigset_t *set, int _sig) +{ + __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); +} + +static __inline__ void sigdelset(sigset_t *set, int _sig) +{ + __asm__("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); +} + +static __inline__ int __const_sigismember(sigset_t *set, int _sig) +{ + unsigned long sig = _sig - 1; + return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); +} + +static __inline__ int __gen_sigismember(sigset_t *set, int _sig) +{ + int ret; + __asm__("btl %2,%1\n\tsbbl %0,%0" + : "=r"(ret) : "m"(*set), "Ir"(_sig-1) : "cc"); + return ret; +} + +#define sigismember(set,sig) \ + (__builtin_constant_p(sig) ? \ + __const_sigismember((set),(sig)) : \ + __gen_sigismember((set),(sig))) + +#define sigmask(sig) (1UL << ((sig) - 1)) + +static __inline__ int sigfindinword(unsigned long word) +{ + __asm__("bsfl %1,%0" : "=r"(word) : "rm"(word) : "cc"); + return word; +} + +#endif /* __KERNEL__ */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/smp.h linux-2.4.23-pre6-swsusp/include/asm/smp.h --- linux-2.4.23-pre6/include/asm/smp.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/smp.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,115 @@ +#ifndef __ASM_SMP_H +#define __ASM_SMP_H + +/* + * We need the APIC definitions automatically as part of 'smp.h' + */ +#ifndef __ASSEMBLY__ +#include +#include +#include +#endif + +#ifdef CONFIG_X86_LOCAL_APIC +#ifndef __ASSEMBLY__ +#include +#include +#include +#ifdef CONFIG_X86_IO_APIC +#include +#endif +#include +#endif +#endif + +#ifdef CONFIG_SMP +#ifndef __ASSEMBLY__ + +/* + * Private routines/data + */ + +extern void smp_alloc_memory(void); +extern unsigned long phys_cpu_present_map; +extern unsigned long cpu_online_map; +extern volatile unsigned long smp_invalidate_needed; +extern int pic_mode; +extern int smp_num_siblings; +extern int cpu_sibling_map[]; + +extern void smp_flush_tlb(void); +extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); +extern void smp_send_reschedule(int cpu); +extern void smp_invalidate_rcv(void); /* Process an NMI */ +extern void (*mtrr_hook) (void); +extern void zap_low_mappings (void); + +/* + * On x86 all CPUs are mapped 1:1 to the APIC space. + * This simplifies scheduling and IPI sending and + * compresses data structures. + */ +static inline int cpu_logical_map(int cpu) +{ + return cpu; +} +static inline int cpu_number_map(int cpu) +{ + return cpu; +} + +/* + * Some lowlevel functions might want to know about + * the real APIC ID <-> CPU # mapping. + */ +#define MAX_APICID 256 +extern volatile int cpu_to_physical_apicid[NR_CPUS]; +extern volatile int physical_apicid_to_cpu[MAX_APICID]; +extern volatile int cpu_to_logical_apicid[NR_CPUS]; +extern volatile int logical_apicid_to_cpu[MAX_APICID]; + +/* + * General functions that each host system must provide. + */ + +extern void smp_boot_cpus(void); +extern void smp_store_cpu_info(int id); /* Store per CPU info (like the initial udelay numbers */ + +/* + * This function is needed by all SMP systems. It must _always_ be valid + * from the initial startup. We map APIC_BASE very early in page_setup(), + * so this is correct in the x86 case. + */ + +#define smp_processor_id() (current->processor) + +static __inline int hard_smp_processor_id(void) +{ + /* we don't want to mark this access volatile - bad code generation */ + return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID)); +} + +static __inline int logical_smp_processor_id(void) +{ + /* we don't want to mark this access volatile - bad code generation */ + return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); +} + +#endif /* !__ASSEMBLY__ */ + +#define NO_PROC_ID 0xFF /* No processor magic marker */ + +/* + * This magic constant controls our willingness to transfer + * a process across CPUs. Such a transfer incurs misses on the L1 + * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My + * gut feeling is this will vary by board in value. For a board + * with separate L2 cache it probably depends also on the RSS, and + * for a board with shared L2 cache it ought to decay fast as other + * processes are run. + */ + +#define PROC_CHANGE_PENALTY 15 /* Schedule penalty */ + +#endif +#endif diff -ruN linux-2.4.23-pre6/include/asm/smpboot.h linux-2.4.23-pre6-swsusp/include/asm/smpboot.h --- linux-2.4.23-pre6/include/asm/smpboot.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/smpboot.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,132 @@ +#ifndef __ASM_SMPBOOT_H +#define __ASM_SMPBOOT_H + +/*emum for clustered_apic_mode values*/ +enum{ + CLUSTERED_APIC_NONE = 0, + CLUSTERED_APIC_XAPIC, + CLUSTERED_APIC_NUMAQ +}; + +#ifdef CONFIG_X86_CLUSTERED_APIC +extern unsigned int apic_broadcast_id; +extern unsigned char clustered_apic_mode; +extern unsigned char esr_disable; +extern unsigned char int_delivery_mode; +extern unsigned int int_dest_addr_mode; +extern int cyclone_setup(char*); + +static inline void detect_clustered_apic(char* oem, char* prod) +{ + /* + * Can't recognize Summit xAPICs at present, so use the OEM ID. + */ + if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "VIGIL SMP", 9)){ + clustered_apic_mode = CLUSTERED_APIC_XAPIC; + apic_broadcast_id = APIC_BROADCAST_ID_XAPIC; + int_dest_addr_mode = APIC_DEST_PHYSICAL; + int_delivery_mode = dest_Fixed; + esr_disable = 1; + /*Start cyclone clock*/ + cyclone_setup(0); + /* check for ACPI tables */ + } else if (!strncmp(oem, "IBM", 3) && + (!strncmp(prod, "SERVIGIL", 8) || + !strncmp(prod, "EXA", 3) || + !strncmp(prod, "RUTHLESS", 8))){ + clustered_apic_mode = CLUSTERED_APIC_XAPIC; + apic_broadcast_id = APIC_BROADCAST_ID_XAPIC; + int_dest_addr_mode = APIC_DEST_PHYSICAL; + int_delivery_mode = dest_Fixed; + esr_disable = 1; + /*Start cyclone clock*/ + cyclone_setup(0); + } else if (!strncmp(oem, "IBM NUMA", 8)){ + clustered_apic_mode = CLUSTERED_APIC_NUMAQ; + apic_broadcast_id = APIC_BROADCAST_ID_APIC; + int_dest_addr_mode = APIC_DEST_LOGICAL; + int_delivery_mode = dest_LowestPrio; + esr_disable = 1; + } +} +#define INT_DEST_ADDR_MODE (int_dest_addr_mode) +#define INT_DELIVERY_MODE (int_delivery_mode) +#else /* CONFIG_X86_CLUSTERED_APIC */ +#define apic_broadcast_id (APIC_BROADCAST_ID_APIC) +#define clustered_apic_mode (CLUSTERED_APIC_NONE) +#define esr_disable (0) +#define detect_clustered_apic(x,y) +#define INT_DEST_ADDR_MODE (APIC_DEST_LOGICAL) /* logical delivery */ +#define INT_DELIVERY_MODE (dest_LowestPrio) +#endif /* CONFIG_X86_CLUSTERED_APIC */ +#define BAD_APICID 0xFFu + +#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467) +#define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469) + +#define boot_cpu_apicid ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?boot_cpu_logical_apicid:boot_cpu_physical_apicid) + +extern unsigned char raw_phys_apicid[NR_CPUS]; + +/* + * How to map from the cpu_present_map + */ +static inline int cpu_present_to_apicid(int mps_cpu) +{ + if (clustered_apic_mode == CLUSTERED_APIC_XAPIC) + return raw_phys_apicid[mps_cpu]; + if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) + return (mps_cpu/4)*16 + (1<<(mps_cpu%4)); + return mps_cpu; +} + +static inline unsigned long apicid_to_phys_cpu_present(int apicid) +{ + if(clustered_apic_mode) + return 1UL << (((apicid >> 4) << 2) + (apicid & 0x3)); + return 1UL << apicid; +} + +#define physical_to_logical_apicid(phys_apic) ( (1ul << (phys_apic & 0x3)) | (phys_apic & 0xF0u) ) + +/* + * Mappings between logical cpu number and logical / physical apicid + * The first four macros are trivial, but it keeps the abstraction consistent + */ +extern volatile int logical_apicid_2_cpu[]; +extern volatile int cpu_2_logical_apicid[]; +extern volatile int physical_apicid_2_cpu[]; +extern volatile int cpu_2_physical_apicid[]; + +#define logical_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid] +#define cpu_to_logical_apicid(cpu) cpu_2_logical_apicid[cpu] +#define physical_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid] +#define cpu_to_physical_apicid(cpu) cpu_2_physical_apicid[cpu] +#ifdef CONFIG_MULTIQUAD /* use logical IDs to bootstrap */ +#define boot_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid] +#define cpu_to_boot_apicid(cpu) cpu_2_logical_apicid[cpu] +#else /* !CONFIG_MULTIQUAD */ /* use physical IDs to bootstrap */ +#define boot_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid] +#define cpu_to_boot_apicid(cpu) cpu_2_physical_apicid[cpu] +#endif /* CONFIG_MULTIQUAD */ + +#ifdef CONFIG_X86_CLUSTERED_APIC +static inline int target_cpus(void) +{ + static int cpu; + switch(clustered_apic_mode){ + case CLUSTERED_APIC_NUMAQ: + /* Broadcast intrs to local quad only. */ + return APIC_BROADCAST_ID_APIC; + case CLUSTERED_APIC_XAPIC: + /*round robin the interrupts*/ + cpu = (cpu+1)%smp_num_cpus; + return cpu_to_physical_apicid(cpu); + default: + } + return cpu_online_map; +} +#else +#define target_cpus() (cpu_online_map) +#endif +#endif diff -ruN linux-2.4.23-pre6/include/asm/smplock.h linux-2.4.23-pre6-swsusp/include/asm/smplock.h --- linux-2.4.23-pre6/include/asm/smplock.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/smplock.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,81 @@ +#ifndef __ASM_SMPLOCK_H +#define __ASM_SMPLOCK_H + +/* + * + * + * i386 SMP lock implementation + */ +#include +#include +#include +#include + +extern spinlock_cacheline_t kernel_flag_cacheline; +#define kernel_flag kernel_flag_cacheline.lock + +#define kernel_locked() spin_is_locked(&kernel_flag) + +/* + * Release global kernel lock and global interrupt lock + */ +#define release_kernel_lock(task, cpu) \ +do { \ + if (task->lock_depth >= 0) \ + spin_unlock(&kernel_flag); \ + release_irqlock(cpu); \ + __sti(); \ +} while (0) + +/* + * Re-acquire the kernel lock + */ +#define reacquire_kernel_lock(task) \ +do { \ + if (task->lock_depth >= 0) \ + spin_lock(&kernel_flag); \ +} while (0) + + +/* + * Getting the big kernel lock. + * + * This cannot happen asynchronously, + * so we only need to worry about other + * CPU's. + */ +static __inline__ void lock_kernel(void) +{ +#if 1 + if (!++current->lock_depth) + spin_lock(&kernel_flag); +#else + __asm__ __volatile__( + "incl %1\n\t" + "jne 9f" + spin_lock_string + "\n9:" + :"=m" (__dummy_lock(&kernel_flag)), + "=m" (current->lock_depth)); +#endif +} + +static __inline__ void unlock_kernel(void) +{ + if (current->lock_depth < 0) + out_of_line_bug(); +#if 1 + if (--current->lock_depth < 0) + spin_unlock(&kernel_flag); +#else + __asm__ __volatile__( + "decl %1\n\t" + "jns 9f\n\t" + spin_unlock_string + "\n9:" + :"=m" (__dummy_lock(&kernel_flag)), + "=m" (current->lock_depth)); +#endif +} + +#endif /* __ASM_SMPLOCK_H */ diff -ruN linux-2.4.23-pre6/include/asm/socket.h linux-2.4.23-pre6-swsusp/include/asm/socket.h --- linux-2.4.23-pre6/include/asm/socket.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/socket.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,64 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include + +/* For setsockopt(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 + +/* Nasty libc5 fixup - bletch */ +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#define SOCK_MAX (SOCK_PACKET+1) +#endif + +#endif /* _ASM_SOCKET_H */ diff -ruN linux-2.4.23-pre6/include/asm/sockios.h linux-2.4.23-pre6-swsusp/include/asm/sockios.h --- linux-2.4.23-pre6/include/asm/sockios.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/sockios.h 1996-03-24 19:47:39.000000000 +0900 @@ -0,0 +1,12 @@ +#ifndef __ARCH_I386_SOCKIOS__ +#define __ARCH_I386_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/softirq.h linux-2.4.23-pre6-swsusp/include/asm/softirq.h --- linux-2.4.23-pre6/include/asm/softirq.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/softirq.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,48 @@ +#ifndef __ASM_SOFTIRQ_H +#define __ASM_SOFTIRQ_H + +#include +#include + +#define __cpu_bh_enable(cpu) \ + do { barrier(); local_bh_count(cpu)--; } while (0) +#define cpu_bh_disable(cpu) \ + do { local_bh_count(cpu)++; barrier(); } while (0) + +#define local_bh_disable() cpu_bh_disable(smp_processor_id()) +#define __local_bh_enable() __cpu_bh_enable(smp_processor_id()) + +#define in_softirq() (local_bh_count(smp_processor_id()) != 0) + +/* + * NOTE: this assembly code assumes: + * + * (char *)&local_bh_count - 8 == (char *)&softirq_pending + * + * If you change the offsets in irq_stat then you have to + * update this code as well. + */ +#define local_bh_enable() \ +do { \ + unsigned int *ptr = &local_bh_count(smp_processor_id()); \ + \ + barrier(); \ + if (!--*ptr) \ + __asm__ __volatile__ ( \ + "cmpl $0, -8(%0);" \ + "jnz 2f;" \ + "1:;" \ + \ + LOCK_SECTION_START("") \ + "2: pushl %%eax; pushl %%ecx; pushl %%edx;" \ + "call %c1;" \ + "popl %%edx; popl %%ecx; popl %%eax;" \ + "jmp 1b;" \ + LOCK_SECTION_END \ + \ + : /* no output */ \ + : "r" (ptr), "i" (do_softirq) \ + /* no registers clobbered */ ); \ +} while (0) + +#endif /* __ASM_SOFTIRQ_H */ diff -ruN linux-2.4.23-pre6/include/asm/spinlock.h linux-2.4.23-pre6-swsusp/include/asm/spinlock.h --- linux-2.4.23-pre6/include/asm/spinlock.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/spinlock.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,212 @@ +#ifndef __ASM_SPINLOCK_H +#define __ASM_SPINLOCK_H + +#include +#include +#include +#include + +extern int printk(const char * fmt, ...) + __attribute__ ((format (printf, 1, 2))); + +/* It seems that people are forgetting to + * initialize their spinlocks properly, tsk tsk. + * Remember to turn this off in 2.4. -ben + */ +#if defined(CONFIG_DEBUG_SPINLOCK) +#define SPINLOCK_DEBUG 1 +#else +#define SPINLOCK_DEBUG 0 +#endif + +/* + * Your basic SMP spinlocks, allowing only a single CPU anywhere + */ + +typedef struct { + volatile unsigned int lock; +#if SPINLOCK_DEBUG + unsigned magic; +#endif +} spinlock_t; + +#define SPINLOCK_MAGIC 0xdead4ead + +#if SPINLOCK_DEBUG +#define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC +#else +#define SPINLOCK_MAGIC_INIT /* */ +#endif + +#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT } + +#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0) + +/* + * Simple spin lock operations. There are two variants, one clears IRQ's + * on the local processor, one does not. + * + * We make no fairness assumptions. They have a cost. + */ + +#define spin_is_locked(x) (*(volatile signed char *)(&(x)->lock) <= 0) +#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) + +#define spin_lock_string \ + "\n1:\t" \ + "lock ; decb %0\n\t" \ + "js 2f\n" \ + LOCK_SECTION_START("") \ + "2:\t" \ + "cmpb $0,%0\n\t" \ + "rep;nop\n\t" \ + "jle 2b\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END + +/* + * This works. Despite all the confusion. + * (except on PPro SMP or if we are using OOSTORE) + * (PPro errata 66, 92) + */ + +#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE) + +#define spin_unlock_string \ + "movb $1,%0" \ + :"=m" (lock->lock) : : "memory" + + +static inline void spin_unlock(spinlock_t *lock) +{ +#if SPINLOCK_DEBUG + if (lock->magic != SPINLOCK_MAGIC) + BUG(); + if (!spin_is_locked(lock)) + BUG(); +#endif + __asm__ __volatile__( + spin_unlock_string + ); +} + +#else + +#define spin_unlock_string \ + "xchgb %b0, %1" \ + :"=q" (oldval), "=m" (lock->lock) \ + :"0" (oldval) : "memory" + +static inline void spin_unlock(spinlock_t *lock) +{ + char oldval = 1; +#if SPINLOCK_DEBUG + if (lock->magic != SPINLOCK_MAGIC) + BUG(); + if (!spin_is_locked(lock)) + BUG(); +#endif + __asm__ __volatile__( + spin_unlock_string + ); +} + +#endif + +static inline int spin_trylock(spinlock_t *lock) +{ + char oldval; + __asm__ __volatile__( + "xchgb %b0,%1" + :"=q" (oldval), "=m" (lock->lock) + :"0" (0) : "memory"); + return oldval > 0; +} + +static inline void spin_lock(spinlock_t *lock) +{ +#if SPINLOCK_DEBUG + __label__ here; +here: + if (lock->magic != SPINLOCK_MAGIC) { +printk("eip: %p\n", &&here); + BUG(); + } +#endif + __asm__ __volatile__( + spin_lock_string + :"=m" (lock->lock) : : "memory"); +} + + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { + volatile unsigned int lock; +#if SPINLOCK_DEBUG + unsigned magic; +#endif +} rwlock_t; + +#define RWLOCK_MAGIC 0xdeaf1eed + +#if SPINLOCK_DEBUG +#define RWLOCK_MAGIC_INIT , RWLOCK_MAGIC +#else +#define RWLOCK_MAGIC_INIT /* */ +#endif + +#define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT } + +#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) + +/* + * On x86, we implement read-write locks as a 32-bit counter + * with the high bit (sign) being the "contended" bit. + * + * The inline assembly is non-obvious. Think about it. + * + * Changed to use the same technique as rw semaphores. See + * semaphore.h for details. -ben + */ +/* the spinlock helpers are in arch/i386/kernel/semaphore.c */ + +static inline void read_lock(rwlock_t *rw) +{ +#if SPINLOCK_DEBUG + if (rw->magic != RWLOCK_MAGIC) + BUG(); +#endif + __build_read_lock(rw, "__read_lock_failed"); +} + +static inline void write_lock(rwlock_t *rw) +{ +#if SPINLOCK_DEBUG + if (rw->magic != RWLOCK_MAGIC) + BUG(); +#endif + __build_write_lock(rw, "__write_lock_failed"); +} + +#define read_unlock(rw) asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory") +#define write_unlock(rw) asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory") + +static inline int write_trylock(rwlock_t *lock) +{ + atomic_t *count = (atomic_t *)lock; + if (atomic_sub_and_test(RW_LOCK_BIAS, count)) + return 1; + atomic_add(RW_LOCK_BIAS, count); + return 0; +} + +#endif /* __ASM_SPINLOCK_H */ diff -ruN linux-2.4.23-pre6/include/asm/stat.h linux-2.4.23-pre6-swsusp/include/asm/stat.h --- linux-2.4.23-pre6/include/asm/stat.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/stat.h 2000-08-02 06:08:00.000000000 +0900 @@ -0,0 +1,78 @@ +#ifndef _I386_STAT_H +#define _I386_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned short st_dev; + unsigned char __pad0[10]; + +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned short st_rdev; + unsigned char __pad3[10]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* future possible st_blocks high bits */ + + unsigned long st_atime; + unsigned long __pad5; + + unsigned long st_mtime; + unsigned long __pad6; + + unsigned long st_ctime; + unsigned long __pad7; /* will be high 32 bits of ctime someday */ + + unsigned long long st_ino; +}; + +#endif diff -ruN linux-2.4.23-pre6/include/asm/statfs.h linux-2.4.23-pre6-swsusp/include/asm/statfs.h --- linux-2.4.23-pre6/include/asm/statfs.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/statfs.h 2001-11-23 04:46:18.000000000 +0900 @@ -0,0 +1,25 @@ +#ifndef _I386_STATFS_H +#define _I386_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + +#endif diff -ruN linux-2.4.23-pre6/include/asm/string-486.h linux-2.4.23-pre6-swsusp/include/asm/string-486.h --- linux-2.4.23-pre6/include/asm/string-486.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/string-486.h 2001-11-23 04:46:18.000000000 +0900 @@ -0,0 +1,617 @@ +#ifndef _I386_STRING_I486_H_ +#define _I386_STRING_I486_H_ + +/* + * This string-include defines all string functions as inline + * functions. Use gcc. It also assumes ds=es=data space, this should be + * normal. Most of the string-functions are rather heavily hand-optimized, + * see especially strtok,strstr,str[c]spn. They should work, but are not + * very easy to understand. Everything is done entirely within the register + * set, making the functions fast and clean. + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Revised and optimized for i486/pentium + * 1994/03/15 by Alberto Vignani/Davide Parodi @crf.it + * + * Split into 2 CPU specific files by Alan Cox to keep #ifdef noise down. + * + * 1999/10/5 Proper register args for newer GCCs and minor bugs + * fixed - Petko Manolov (petkan@spct.net) + * 1999/10/14 3DNow memscpy() added - Petkan + * 2000/05/09 extern changed to static in function definitions + * and a few cleanups - Petkan + */ + +#define __HAVE_ARCH_STRCPY +static inline char * strcpy(char * dest,const char *src) +{ +register char *tmp= (char *)dest; +register char dummy; +__asm__ __volatile__( + "\n1:\t" + "movb (%0),%2\n\t" + "incl %0\n\t" + "movb %2,(%1)\n\t" + "incl %1\n\t" + "testb %2,%2\n\t" + "jne 1b" + :"=r" (src), "=r" (tmp), "=q" (dummy) + :"0" (src), "1" (tmp) + :"memory"); +return dest; +} + +#define __HAVE_ARCH_STRNCPY +static inline char * strncpy(char * dest,const char *src,size_t count) +{ +register char *tmp= (char *)dest; +register char dummy; +if (count) { +__asm__ __volatile__( + "\n1:\t" + "movb (%0),%2\n\t" + "incl %0\n\t" + "movb %2,(%1)\n\t" + "incl %1\n\t" + "decl %3\n\t" + "je 3f\n\t" + "testb %2,%2\n\t" + "jne 1b\n\t" + "2:\tmovb %2,(%1)\n\t" + "incl %1\n\t" + "decl %3\n\t" + "jne 2b\n\t" + "3:" + :"=r" (src), "=r" (tmp), "=q" (dummy), "=r" (count) + :"0" (src), "1" (tmp), "3" (count) + :"memory"); + } /* if (count) */ +return dest; +} + +#define __HAVE_ARCH_STRCAT +static inline char * strcat(char * dest,const char * src) +{ +register char *tmp = (char *)(dest-1); +register char dummy; +__asm__ __volatile__( + "\n1:\tincl %1\n\t" + "cmpb $0,(%1)\n\t" + "jne 1b\n" + "2:\tmovb (%2),%b0\n\t" + "incl %2\n\t" + "movb %b0,(%1)\n\t" + "incl %1\n\t" + "testb %b0,%b0\n\t" + "jne 2b\n" + :"=q" (dummy), "=r" (tmp), "=r" (src) + :"1" (tmp), "2" (src) + :"memory"); +return dest; +} + +#define __HAVE_ARCH_STRNCAT +static inline char * strncat(char * dest,const char * src,size_t count) +{ +register char *tmp = (char *)(dest-1); +register char dummy; +__asm__ __volatile__( + "\n1:\tincl %1\n\t" + "cmpb $0,(%1)\n\t" + "jne 1b\n" + "2:\tdecl %3\n\t" + "js 3f\n\t" + "movb (%2),%b0\n\t" + "incl %2\n\t" + "movb %b0,(%1)\n\t" + "incl %1\n\t" + "testb %b0,%b0\n\t" + "jne 2b\n" + "3:\txorb %0,%0\n\t" + "movb %b0,(%1)\n\t" + :"=q" (dummy), "=r" (tmp), "=r" (src), "=r" (count) + :"1" (tmp), "2" (src), "3" (count) + :"memory"); +return dest; +} + +#define __HAVE_ARCH_STRCMP +static inline int strcmp(const char * cs,const char * ct) +{ +register int __res; +__asm__ __volatile__( + "\n1:\tmovb (%1),%b0\n\t" + "incl %1\n\t" + "cmpb %b0,(%2)\n\t" + "jne 2f\n\t" + "incl %2\n\t" + "testb %b0,%b0\n\t" + "jne 1b\n\t" + "xorl %0,%0\n\t" + "jmp 3f\n" + "2:\tmovl $1,%0\n\t" + "jb 3f\n\t" + "negl %0\n" + "3:" + :"=q" (__res), "=r" (cs), "=r" (ct) + :"1" (cs), "2" (ct) + : "memory" ); +return __res; +} + +#define __HAVE_ARCH_STRNCMP +static inline int strncmp(const char * cs,const char * ct,size_t count) +{ +register int __res; +__asm__ __volatile__( + "\n1:\tdecl %3\n\t" + "js 2f\n\t" + "movb (%1),%b0\n\t" + "incl %1\n\t" + "cmpb %b0,(%2)\n\t" + "jne 3f\n\t" + "incl %2\n\t" + "testb %b0,%b0\n\t" + "jne 1b\n" + "2:\txorl %0,%0\n\t" + "jmp 4f\n" + "3:\tmovl $1,%0\n\t" + "jb 4f\n\t" + "negl %0\n" + "4:" + :"=q" (__res), "=r" (cs), "=r" (ct), "=r" (count) + :"1" (cs), "2" (ct), "3" (count)); +return __res; +} + +#define __HAVE_ARCH_STRCHR +static inline char * strchr(const char * s, int c) +{ +register char * __res; +__asm__ __volatile__( + "movb %%al,%%ah\n" + "1:\tmovb (%1),%%al\n\t" + "cmpb %%ah,%%al\n\t" + "je 2f\n\t" + "incl %1\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "xorl %1,%1\n" + "2:\tmovl %1,%0\n\t" + :"=a" (__res), "=r" (s) + :"0" (c), "1" (s)); +return __res; +} + +#define __HAVE_ARCH_STRRCHR +static inline char * strrchr(const char * s, int c) +{ +int d0, d1; +register char * __res; +__asm__ __volatile__( + "movb %%al,%%ah\n" + "1:\tlodsb\n\t" + "cmpb %%ah,%%al\n\t" + "jne 2f\n\t" + "leal -1(%%esi),%0\n" + "2:\ttestb %%al,%%al\n\t" + "jne 1b" + :"=d" (__res), "=&S" (d0), "=&a" (d1) + :"0" (0), "1" (s), "2" (c)); +return __res; +} + + +#define __HAVE_ARCH_STRCSPN +static inline size_t strcspn(const char * cs, const char * ct) +{ +int d0, d1; +register char * __res; +__asm__ __volatile__( + "movl %6,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %6,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 1b\n" + "2:\tdecl %0" + :"=S" (__res), "=&a" (d0), "=&c" (d1) + :"0" (cs), "1" (0), "2" (0xffffffff), "g" (ct) + :"dx", "di"); +return __res-cs; +} + + +#define __HAVE_ARCH_STRLEN +static inline size_t strlen(const char * s) +{ +/* + * slightly slower on a 486, but with better chances of + * register allocation + */ +register char dummy, *tmp= (char *)s; +__asm__ __volatile__( + "\n1:\t" + "movb\t(%0),%1\n\t" + "incl\t%0\n\t" + "testb\t%1,%1\n\t" + "jne\t1b" + :"=r" (tmp),"=q" (dummy) + :"0" (s) + : "memory" ); +return (tmp-s-1); +} + +/* Added by Gertjan van Wingerde to make minix and sysv module work */ +#define __HAVE_ARCH_STRNLEN +static inline size_t strnlen(const char * s, size_t count) +{ +int d0; +register int __res; +__asm__ __volatile__( + "movl %3,%0\n\t" + "jmp 2f\n" + "1:\tcmpb $0,(%0)\n\t" + "je 3f\n\t" + "incl %0\n" + "2:\tdecl %2\n\t" + "cmpl $-1,%2\n\t" + "jne 1b\n" + "3:\tsubl %3,%0" + :"=a" (__res), "=&d" (d0) + :"1" (count), "c" (s)); +return __res; +} +/* end of additional stuff */ + + +/* + * These ought to get tweaked to do some cache priming. + */ + +static inline void * __memcpy_by4(void * to, const void * from, size_t n) +{ +register void *tmp = (void *)to; +register int dummy1,dummy2; +__asm__ __volatile__ ( + "\n1:\tmovl (%2),%0\n\t" + "addl $4,%2\n\t" + "movl %0,(%1)\n\t" + "addl $4,%1\n\t" + "decl %3\n\t" + "jnz 1b" + :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) + :"1" (tmp), "2" (from), "3" (n/4) + :"memory"); +return (to); +} + +static inline void * __memcpy_by2(void * to, const void * from, size_t n) +{ +register void *tmp = (void *)to; +register int dummy1,dummy2; +__asm__ __volatile__ ( + "shrl $1,%3\n\t" + "jz 2f\n" /* only a word */ + "1:\tmovl (%2),%0\n\t" + "addl $4,%2\n\t" + "movl %0,(%1)\n\t" + "addl $4,%1\n\t" + "decl %3\n\t" + "jnz 1b\n" + "2:\tmovw (%2),%w0\n\t" + "movw %w0,(%1)" + :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) + :"1" (tmp), "2" (from), "3" (n/2) + :"memory"); +return (to); +} + +static inline void * __memcpy_g(void * to, const void * from, size_t n) +{ +int d0, d1, d2; +register void *tmp = (void *)to; +__asm__ __volatile__ ( + "shrl $1,%%ecx\n\t" + "jnc 1f\n\t" + "movsb\n" + "1:\tshrl $1,%%ecx\n\t" + "jnc 2f\n\t" + "movsw\n" + "2:\trep\n\t" + "movsl" + :"=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n), "1" ((long) tmp), "2" ((long) from) + :"memory"); +return (to); +} + +#define __memcpy_c(d,s,count) \ +((count%4==0) ? \ + __memcpy_by4((d),(s),(count)) : \ + ((count%2==0) ? \ + __memcpy_by2((d),(s),(count)) : \ + __memcpy_g((d),(s),(count)))) + +#define __memcpy(d,s,count) \ +(__builtin_constant_p(count) ? \ + __memcpy_c((d),(s),(count)) : \ + __memcpy_g((d),(s),(count))) + +#define __HAVE_ARCH_MEMCPY + +#include + +#ifdef CONFIG_X86_USE_3DNOW + +#include + +/* +** This CPU favours 3DNow strongly (eg AMD K6-II, K6-III, Athlon) +*/ + +static inline void * __constant_memcpy3d(void * to, const void * from, size_t len) +{ + if (len < 512) + return __memcpy_c(to, from, len); + return _mmx_memcpy(to, from, len); +} + +static inline void *__memcpy3d(void *to, const void *from, size_t len) +{ + if(len < 512) + return __memcpy_g(to, from, len); + return _mmx_memcpy(to, from, len); +} + +#define memcpy(d, s, count) \ +(__builtin_constant_p(count) ? \ + __constant_memcpy3d((d),(s),(count)) : \ + __memcpy3d((d),(s),(count))) + +#else /* CONFIG_X86_USE_3DNOW */ + +/* +** Generic routines +*/ + + +#define memcpy(d, s, count) __memcpy(d, s, count) + +#endif /* CONFIG_X86_USE_3DNOW */ + + +extern void __struct_cpy_bug( void ); + +#define struct_cpy(x,y) \ +({ \ + if (sizeof(*(x)) != sizeof(*(y))) \ + __struct_cpy_bug; \ + memcpy(x, y, sizeof(*(x))); \ +}) + + +#define __HAVE_ARCH_MEMMOVE +static inline void * memmove(void * dest,const void * src, size_t n) +{ +int d0, d1, d2; +register void *tmp = (void *)dest; +if (dest +/* + * On a 486 or Pentium, we are better off not using the + * byte string operations. But on a 386 or a PPro the + * byte string ops are faster than doing it by hand + * (MUCH faster on a Pentium). + * + * Also, the byte strings actually work correctly. Forget + * the i486 routines for now as they may be broken.. + */ +#if FIXED_486_STRING && defined(CONFIG_X86_USE_STRING_486) +#include +#else + +/* + * This string-include defines all string functions as inline + * functions. Use gcc. It also assumes ds=es=data space, this should be + * normal. Most of the string-functions are rather heavily hand-optimized, + * see especially strtok,strstr,str[c]spn. They should work, but are not + * very easy to understand. Everything is done entirely within the register + * set, making the functions fast and clean. String instructions have been + * used through-out, making for "slightly" unclear code :-) + * + * NO Copyright (C) 1991, 1992 Linus Torvalds, + * consider these trivial functions to be PD. + */ + +#define __HAVE_ARCH_STRCPY +static inline char * strcpy(char * dest,const char *src) +{ +int d0, d1, d2; +__asm__ __volatile__( + "1:\tlodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + :"0" (src),"1" (dest) : "memory"); +return dest; +} + +#define __HAVE_ARCH_STRNCPY +static inline char * strncpy(char * dest,const char *src,size_t count) +{ +int d0, d1, d2, d3; +__asm__ __volatile__( + "1:\tdecl %2\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "rep\n\t" + "stosb\n" + "2:" + : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3) + :"0" (src),"1" (dest),"2" (count) : "memory"); +return dest; +} + +#define __HAVE_ARCH_STRCAT +static inline char * strcat(char * dest,const char * src) +{ +int d0, d1, d2, d3; +__asm__ __volatile__( + "repne\n\t" + "scasb\n\t" + "decl %1\n" + "1:\tlodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b" + : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) + : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory"); +return dest; +} + +#define __HAVE_ARCH_STRNCAT +static inline char * strncat(char * dest,const char * src,size_t count) +{ +int d0, d1, d2, d3; +__asm__ __volatile__( + "repne\n\t" + "scasb\n\t" + "decl %1\n\t" + "movl %8,%3\n" + "1:\tdecl %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txorl %2,%2\n\t" + "stosb" + : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) + : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) + : "memory"); +return dest; +} + +#define __HAVE_ARCH_STRCMP +static inline int strcmp(const char * cs,const char * ct) +{ +int d0, d1; +register int __res; +__asm__ __volatile__( + "1:\tlodsb\n\t" + "scasb\n\t" + "jne 2f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "xorl %%eax,%%eax\n\t" + "jmp 3f\n" + "2:\tsbbl %%eax,%%eax\n\t" + "orb $1,%%al\n" + "3:" + :"=a" (__res), "=&S" (d0), "=&D" (d1) + :"1" (cs),"2" (ct)); +return __res; +} + +#define __HAVE_ARCH_STRNCMP +static inline int strncmp(const char * cs,const char * ct,size_t count) +{ +register int __res; +int d0, d1, d2; +__asm__ __volatile__( + "1:\tdecl %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "scasb\n\t" + "jne 3f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txorl %%eax,%%eax\n\t" + "jmp 4f\n" + "3:\tsbbl %%eax,%%eax\n\t" + "orb $1,%%al\n" + "4:" + :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) + :"1" (cs),"2" (ct),"3" (count)); +return __res; +} + +#define __HAVE_ARCH_STRCHR +static inline char * strchr(const char * s, int c) +{ +int d0; +register char * __res; +__asm__ __volatile__( + "movb %%al,%%ah\n" + "1:\tlodsb\n\t" + "cmpb %%ah,%%al\n\t" + "je 2f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "movl $1,%1\n" + "2:\tmovl %1,%0\n\t" + "decl %0" + :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c)); +return __res; +} + +#define __HAVE_ARCH_STRRCHR +static inline char * strrchr(const char * s, int c) +{ +int d0, d1; +register char * __res; +__asm__ __volatile__( + "movb %%al,%%ah\n" + "1:\tlodsb\n\t" + "cmpb %%ah,%%al\n\t" + "jne 2f\n\t" + "leal -1(%%esi),%0\n" + "2:\ttestb %%al,%%al\n\t" + "jne 1b" + :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); +return __res; +} + +#define __HAVE_ARCH_STRLEN +static inline size_t strlen(const char * s) +{ +int d0; +register int __res; +__asm__ __volatile__( + "repne\n\t" + "scasb\n\t" + "notl %0\n\t" + "decl %0" + :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff)); +return __res; +} + +static inline void * __memcpy(void * to, const void * from, size_t n) +{ +int d0, d1, d2; +__asm__ __volatile__( + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); +return (to); +} + +/* + * This looks horribly ugly, but the compiler can optimize it totally, + * as the count is constant. + */ +static inline void * __constant_memcpy(void * to, const void * from, size_t n) +{ + switch (n) { + case 0: + return to; + case 1: + *(unsigned char *)to = *(const unsigned char *)from; + return to; + case 2: + *(unsigned short *)to = *(const unsigned short *)from; + return to; + case 3: + *(unsigned short *)to = *(const unsigned short *)from; + *(2+(unsigned char *)to) = *(2+(const unsigned char *)from); + return to; + case 4: + *(unsigned long *)to = *(const unsigned long *)from; + return to; + case 6: /* for Ethernet addresses */ + *(unsigned long *)to = *(const unsigned long *)from; + *(2+(unsigned short *)to) = *(2+(const unsigned short *)from); + return to; + case 8: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + return to; + case 12: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); + return to; + case 16: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); + *(3+(unsigned long *)to) = *(3+(const unsigned long *)from); + return to; + case 20: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); + *(3+(unsigned long *)to) = *(3+(const unsigned long *)from); + *(4+(unsigned long *)to) = *(4+(const unsigned long *)from); + return to; + } +#define COMMON(x) \ +__asm__ __volatile__( \ + "rep ; movsl" \ + x \ + : "=&c" (d0), "=&D" (d1), "=&S" (d2) \ + : "0" (n/4),"1" ((long) to),"2" ((long) from) \ + : "memory"); +{ + int d0, d1, d2; + switch (n % 4) { + case 0: COMMON(""); return to; + case 1: COMMON("\n\tmovsb"); return to; + case 2: COMMON("\n\tmovsw"); return to; + default: COMMON("\n\tmovsw\n\tmovsb"); return to; + } +} + +#undef COMMON +} + +#define __HAVE_ARCH_MEMCPY + +#ifdef CONFIG_X86_USE_3DNOW + +#include + +/* + * This CPU favours 3DNow strongly (eg AMD Athlon) + */ + +static inline void * __constant_memcpy3d(void * to, const void * from, size_t len) +{ + if (len < 512) + return __constant_memcpy(to, from, len); + return _mmx_memcpy(to, from, len); +} + +static __inline__ void *__memcpy3d(void *to, const void *from, size_t len) +{ + if (len < 512) + return __memcpy(to, from, len); + return _mmx_memcpy(to, from, len); +} + +#define memcpy(t, f, n) \ +(__builtin_constant_p(n) ? \ + __constant_memcpy3d((t),(f),(n)) : \ + __memcpy3d((t),(f),(n))) + +#else + +/* + * No 3D Now! + */ + +#define memcpy(t, f, n) \ +(__builtin_constant_p(n) ? \ + __constant_memcpy((t),(f),(n)) : \ + __memcpy((t),(f),(n))) + +#endif + +/* + * struct_cpy(x,y), copy structure *x into (matching structure) *y. + * + * We get link-time errors if the structure sizes do not match. + * There is no runtime overhead, it's all optimized away at + * compile time. + */ +extern void __struct_cpy_bug (void); + +#define struct_cpy(x,y) \ +({ \ + if (sizeof(*(x)) != sizeof(*(y))) \ + __struct_cpy_bug; \ + memcpy(x, y, sizeof(*(x))); \ +}) + +#define __HAVE_ARCH_MEMMOVE +static inline void * memmove(void * dest,const void * src, size_t n) +{ +int d0, d1, d2; +if (dest + * Based on code + * Copyright 2001 Patrick Mochel + */ +#include +#include +#ifdef SUSPEND_C +#include +#endif +/* image of the saved processor state */ +struct saved_context { + u32 eax, ebx, ecx, edx; + u32 esp, ebp, esi, edi; + u16 es, fs, gs, ss; + u32 cr0, cr2, cr3, cr4; + u16 gdt_pad; + u16 gdt_limit; + u32 gdt_base; + u16 idt_pad; + u16 idt_limit; + u32 idt_base; + u16 ldt; + u16 tss; + u32 tr; + u32 safety; + u32 return_address; + u32 eflags; +} __attribute__((packed)); + +struct saved_context saved_context; + +#define loaddebug(thread,register) \ + __asm__("movl %0,%%db" #register \ + : /* no output */ \ + :"r" ((thread)->debugreg[register])) + + +/* + * save_processor_context + * + * Save the state of the processor before we go to sleep. + * + * return_stack is the value of the stack pointer (%esp) as the caller sees it. + * A good way could not be found to obtain it from here (don't want to make _too_ + * many assumptions about the layout of the stack this far down.) Also, the + * handy little __builtin_frame_pointer(level) where level > 0, is blatantly + * buggy - it returns the value of the stack at the proper location, not the + * location, like it should (as of gcc 2.91.66) + * + * Note that the context and timing of this function is pretty critical. + * With a minimal amount of things going on in the caller and in here, gcc + * does a good job of being just a dumb compiler. Watch the assembly output + * if anything changes, though, and make sure everything is going in the right + * place. + */ +static inline void save_processor_context (void) +{ + kernel_fpu_begin(); + + /* + * descriptor tables + */ + asm volatile ("sgdt (%0)" : "=m" (saved_context.gdt_limit)); + asm volatile ("sidt (%0)" : "=m" (saved_context.idt_limit)); + asm volatile ("sldt (%0)" : "=m" (saved_context.ldt)); + asm volatile ("str (%0)" : "=m" (saved_context.tr)); + + /* + * save the general registers. + * note that gcc has constructs to specify output of certain registers, + * but they're not used here, because it assumes that you want to modify + * those registers, so it tries to be smart and save them beforehand. + * It's really not necessary, and kinda fishy (check the assembly output), + * so it's avoided. + */ + asm volatile ("movl %%esp, (%0)" : "=m" (saved_context.esp)); + asm volatile ("movl %%eax, (%0)" : "=m" (saved_context.eax)); + asm volatile ("movl %%ebx, (%0)" : "=m" (saved_context.ebx)); + asm volatile ("movl %%ecx, (%0)" : "=m" (saved_context.ecx)); + asm volatile ("movl %%edx, (%0)" : "=m" (saved_context.edx)); + asm volatile ("movl %%ebp, (%0)" : "=m" (saved_context.ebp)); + asm volatile ("movl %%esi, (%0)" : "=m" (saved_context.esi)); + asm volatile ("movl %%edi, (%0)" : "=m" (saved_context.edi)); + + /* + * segment registers + */ + asm volatile ("movw %%es, %0" : "=r" (saved_context.es)); + asm volatile ("movw %%fs, %0" : "=r" (saved_context.fs)); + asm volatile ("movw %%gs, %0" : "=r" (saved_context.gs)); + asm volatile ("movw %%ss, %0" : "=r" (saved_context.ss)); + + /* + * control registers + */ + asm volatile ("movl %%cr0, %0" : "=r" (saved_context.cr0)); + asm volatile ("movl %%cr2, %0" : "=r" (saved_context.cr2)); + asm volatile ("movl %%cr3, %0" : "=r" (saved_context.cr3)); + asm volatile ("movl %%cr4, %0" : "=r" (saved_context.cr4)); + + /* + * eflags + */ + asm volatile ("pushfl ; popl (%0)" : "=m" (saved_context.eflags)); +} + +void fix_processor_context(void) +{ + int nr = smp_processor_id(); + struct tss_struct * t = &init_tss[nr]; + + set_tss_desc(nr,t); /* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy tsc or some similar stupidity. */ + gdt_table[__TSS(nr)].b &= 0xfffffdff; + + load_TR(nr); /* This does ltr */ + + load_LDT(current->active_mm); /* This does lldt */ + + /* + * Now maybe reload the debug registers + */ + if (current->thread.debugreg[7]){ + loaddebug(¤t->thread, 0); + loaddebug(¤t->thread, 1); + loaddebug(¤t->thread, 2); + loaddebug(¤t->thread, 3); + /* no 4 and 5 */ + loaddebug(¤t->thread, 6); + loaddebug(¤t->thread, 7); + } + +} + +void +do_fpu_end(void) +{ + /* restore FPU regs if necessary */ + /* Do it out of line so that gcc does not move cr0 load to some stupid place */ + kernel_fpu_end(); +} + +/* + * restore_processor_context + * + * Restore the processor context as it was before we went to sleep + * - descriptor tables + * - control registers + * - segment registers + * - flags + * + * Note that it is critical that this function is declared inline. + * It was separated out from restore_state to make that function + * a little clearer, but it needs to be inlined because we won't have a + * stack when we get here (so we can't push a return address). + */ +inline void restore_processor_context (void) +{ + /* + * first restore %ds, so we can access our data properly + */ + asm volatile (".align 4"); + asm volatile ("movw %0, %%ds" :: "r" ((u16)__KERNEL_DS)); + + + /* + * control registers + */ + asm volatile ("movl %0, %%cr4" :: "r" (saved_context.cr4)); + asm volatile ("movl %0, %%cr3" :: "r" (saved_context.cr3)); + asm volatile ("movl %0, %%cr2" :: "r" (saved_context.cr2)); + asm volatile ("movl %0, %%cr0" :: "r" (saved_context.cr0)); + + /* + * segment registers + */ + asm volatile ("movw %0, %%es" :: "r" (saved_context.es)); + asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs)); + asm volatile ("movw %0, %%gs" :: "r" (saved_context.gs)); + asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss)); + + /* + * the other general registers + * + * note that even though gcc has constructs to specify memory + * input into certain registers, it will try to be too smart + * and save them at the beginning of the function. This is esp. + * bad since we don't have a stack set up when we enter, and we + * want to preserve the values on exit. So, we set them manually. + */ + asm volatile ("movl %0, %%esp" :: "m" (saved_context.esp)); + asm volatile ("movl %0, %%ebp" :: "m" (saved_context.ebp)); + asm volatile ("movl %0, %%eax" :: "m" (saved_context.eax)); + asm volatile ("movl %0, %%ebx" :: "m" (saved_context.ebx)); + asm volatile ("movl %0, %%ecx" :: "m" (saved_context.ecx)); + asm volatile ("movl %0, %%edx" :: "m" (saved_context.edx)); + asm volatile ("movl %0, %%esi" :: "m" (saved_context.esi)); + asm volatile ("movl %0, %%edi" :: "m" (saved_context.edi)); + + /* + * now restore the descriptor tables to their proper values + * ltr is done i fix_processor_context(). + */ + asm volatile ("lgdt (%0)" :: "m" (saved_context.gdt_limit)); + asm volatile ("lidt (%0)" :: "m" (saved_context.idt_limit)); + asm volatile ("lldt (%0)" :: "m" (saved_context.ldt)); + + fix_processor_context(); + + /* + * the flags + */ + asm volatile ("pushl %0 ; popfl" :: "m" (saved_context.eflags)); + + do_fpu_end(); +} + +#ifdef SUSPEND_C +/* Local variables for do_magic */ +volatile static int loop __nosavedata = 0; +volatile static int state1 __nosavedata = 0; +volatile static int state2 __nosavedata = 0; +volatile static int state3 __nosavedata = 0; +volatile static struct range *origrange __nosavedata; +volatile static struct range *copyrange __nosavedata; +volatile static int origoffset __nosavedata; +volatile static int copyoffset __nosavedata; +volatile static unsigned long * origpage __nosavedata; +volatile static unsigned long * copypage __nosavedata; +volatile static int orig_min_free __nosavedata; +#ifndef CONFIG_SMP +static unsigned long c_loops_per_jiffy_ref __nosavedata = 0; +static unsigned long cpu_khz_ref __nosavedata = 0; +#endif + +/* + * FIXME: This function should really be written in assembly. Actually + * requirement is that it does not touch stack, because %esp will be + * wrong during resume before restore_processor_context(). Check + * assembly if you modify this. + */ +static void do_suspend_lowlevel(int resume) +{ + if (!resume) { + do_magic_suspend_1(); + PRINTPREEMPTCOUNT("Before save_processor_context."); + save_processor_context(); /* We need to capture registers and memory at "same time" */ + PRINTPREEMPTCOUNT("After save_processor_context."); + do_magic_suspend_2(); /* If everything goes okay, this function does not return */ + return; + } + + /* We want to run from swapper_pg_dir, since swapper_pg_dir is stored in constant + * place in memory + */ + + __asm__( "movl %%ecx,%%cr3\n" ::"c"(__pa(swapper_pg_dir))); + +/* + * Final function for resuming: after copying the pages to their original + * position, it restores the register state. + * + * What about page tables? Writing data pages may toggle + * accessed/dirty bits in our page tables. That should be no problems + * with 4MB page tables. That's why we require have_pse. + * + * This loops destroys stack from under itself, so it better should + * not use any stack space, itself. When this function is entered at + * resume time, we move stack to _old_ place. This is means that this + * function must use no stack and no local variables in registers, + * until calling restore_processor_context(); + * + * Critical section here: noone should touch saved memory after + * do_magic_resume_1; copying works, because nr_copy_pages, + * pagedir_nosave, loop and loop2 are nosavedata. + */ + + do_magic_resume_1(); + +#ifdef CONFIG_PREEMPT + /* + * Preempt disabled in kernel we're about to restore. + * Make sure we match state now. + */ + preempt_disable(); + PRINTPREEMPTCOUNT("Prior to copying old kernel back."); +#endif + + state1 = swsusp_action; + state2 = swsusp_debug_state; + state3 = console_loglevel; + +#ifndef CONFIG_SMP + c_loops_per_jiffy_ref = cpu_data->loops_per_jiffy; + cpu_khz_ref = cpu_khz; +#endif + + origrange = pagedir_nosave.origranges.first; + copyrange = pagedir_nosave.destranges.first; + origoffset = origrange->minimum; + copyoffset = copyrange->minimum; + origpage = (unsigned long *) (page_address(mem_map + origoffset)); + copypage = (unsigned long *) (page_address(mem_map + copyoffset)); + orig_min_free = swsusp_min_free; + + while (origrange) { + for (loop=0; loop < (PAGE_SIZE / sizeof(unsigned long)); loop++) { + *(origpage + loop) = *(copypage + loop); + __flush_tlb(); + } + + if (origoffset < origrange->maximum) { + origoffset++; + origpage += (PAGE_SIZE / sizeof(unsigned long)); + } else { + origrange = origrange->next; + if (origrange) { + origoffset = origrange->minimum; + origpage = (unsigned long *) (page_address(mem_map + origoffset)); + } + } + + if (copyoffset < copyrange->maximum) { + copyoffset++; + copypage += (PAGE_SIZE / sizeof(unsigned long)); + } else { + copyrange = copyrange->next; + if (copyrange) { + copyoffset = copyrange->minimum; + copypage = (unsigned long *) (page_address(mem_map + copyoffset)); + } + } + } + + restore_processor_context(); + +/* Ahah, we now run with our old stack, and with registers copied from + suspend time */ + +#ifndef CONFIG_SMP + cpu_data->loops_per_jiffy = c_loops_per_jiffy_ref; + loops_per_jiffy = c_loops_per_jiffy_ref; + cpu_khz = cpu_khz_ref; +#endif + swsusp_action = state1; + swsusp_debug_state = state2; + console_loglevel = state3; + swsusp_min_free = orig_min_free; + + do_magic_resume_2(); +} +#endif diff -ruN linux-2.4.23-pre6/include/asm/system.h linux-2.4.23-pre6-swsusp/include/asm/system.h --- linux-2.4.23-pre6/include/asm/system.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/system.h 2003-08-25 20:44:43.000000000 +0900 @@ -0,0 +1,380 @@ +#ifndef __ASM_SYSTEM_H +#define __ASM_SYSTEM_H + +#include +#include +#include +#include +#include /* for LOCK_PREFIX */ + +#ifdef __KERNEL__ + +struct task_struct; /* one of the stranger aspects of C forward declarations.. */ +extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next)); + +#define prepare_to_switch() do { } while(0) +#define switch_to(prev,next,last) do { \ + asm volatile("pushl %%esi\n\t" \ + "pushl %%edi\n\t" \ + "pushl %%ebp\n\t" \ + "movl %%esp,%0\n\t" /* save ESP */ \ + "movl %3,%%esp\n\t" /* restore ESP */ \ + "movl $1f,%1\n\t" /* save EIP */ \ + "pushl %4\n\t" /* restore EIP */ \ + "jmp __switch_to\n" \ + "1:\t" \ + "popl %%ebp\n\t" \ + "popl %%edi\n\t" \ + "popl %%esi\n\t" \ + :"=m" (prev->thread.esp),"=m" (prev->thread.eip), \ + "=b" (last) \ + :"m" (next->thread.esp),"m" (next->thread.eip), \ + "a" (prev), "d" (next), \ + "b" (prev)); \ +} while (0) + +#define _set_base(addr,base) do { unsigned long __pr; \ +__asm__ __volatile__ ("movw %%dx,%1\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %%dl,%2\n\t" \ + "movb %%dh,%3" \ + :"=&d" (__pr) \ + :"m" (*((addr)+2)), \ + "m" (*((addr)+4)), \ + "m" (*((addr)+7)), \ + "0" (base) \ + ); } while(0) + +#define _set_limit(addr,limit) do { unsigned long __lr; \ +__asm__ __volatile__ ("movw %%dx,%1\n\t" \ + "rorl $16,%%edx\n\t" \ + "movb %2,%%dh\n\t" \ + "andb $0xf0,%%dh\n\t" \ + "orb %%dh,%%dl\n\t" \ + "movb %%dl,%2" \ + :"=&d" (__lr) \ + :"m" (*(addr)), \ + "m" (*((addr)+6)), \ + "0" (limit) \ + ); } while(0) + +#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) ) +#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 ) + +static inline unsigned long _get_base(char * addr) +{ + unsigned long __base; + __asm__("movb %3,%%dh\n\t" + "movb %2,%%dl\n\t" + "shll $16,%%edx\n\t" + "movw %1,%%dx" + :"=&d" (__base) + :"m" (*((addr)+2)), + "m" (*((addr)+4)), + "m" (*((addr)+7))); + return __base; +} + +#define get_base(ldt) _get_base( ((char *)&(ldt)) ) + +/* + * Load a segment. Fall back on loading the zero + * segment if something goes wrong.. + */ +#define loadsegment(seg,value) \ + asm volatile("\n" \ + "1:\t" \ + "movl %0,%%" #seg "\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3:\t" \ + "pushl $0\n\t" \ + "popl %%" #seg "\n\t" \ + "jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n\t" \ + ".align 4\n\t" \ + ".long 1b,3b\n" \ + ".previous" \ + : :"m" (*(unsigned int *)&(value))) + +/* + * Clear and set 'TS' bit respectively + */ +#define clts() __asm__ __volatile__ ("clts") +#define read_cr0() ({ \ + unsigned int __dummy; \ + __asm__( \ + "movl %%cr0,%0\n\t" \ + :"=r" (__dummy)); \ + __dummy; \ +}) +#define write_cr0(x) \ + __asm__("movl %0,%%cr0": :"r" (x)); + +#define read_cr4() ({ \ + unsigned int __dummy; \ + __asm__( \ + "movl %%cr4,%0\n\t" \ + :"=r" (__dummy)); \ + __dummy; \ +}) +#define write_cr4(x) \ + __asm__("movl %0,%%cr4": :"r" (x)); +#define stts() write_cr0(8 | read_cr0()) + +#endif /* __KERNEL__ */ + +#define wbinvd() \ + __asm__ __volatile__ ("wbinvd": : :"memory"); + +static inline unsigned long get_limit(unsigned long segment) +{ + unsigned long __limit; + __asm__("lsll %1,%0" + :"=r" (__limit):"r" (segment)); + return __limit+1; +} + +#define nop() __asm__ __volatile__ ("nop") + +#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr)))) + +#define tas(ptr) (xchg((ptr),1)) + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x)) + + +/* + * The semantics of XCHGCMP8B are a bit strange, this is why + * there is a loop and the loading of %%eax and %%edx has to + * be inside. This inlines well in most cases, the cached + * cost is around ~38 cycles. (in the future we might want + * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that + * might have an implicit FPU-save as a cost, so it's not + * clear which path to go.) + * + * chmxchg8b must be used with the lock prefix here to allow + * the instruction to be executed atomically, see page 3-102 + * of the instruction set reference 24319102.pdf. We need + * the reader side to see the coherent 64bit value. + */ +static inline void __set_64bit (unsigned long long * ptr, + unsigned int low, unsigned int high) +{ + __asm__ __volatile__ ( + "\n1:\t" + "movl (%0), %%eax\n\t" + "movl 4(%0), %%edx\n\t" + "lock cmpxchg8b (%0)\n\t" + "jnz 1b" + : /* no outputs */ + : "D"(ptr), + "b"(low), + "c"(high) + : "ax","dx","memory"); +} + +static inline void __set_64bit_constant (unsigned long long *ptr, + unsigned long long value) +{ + __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL)); +} +#define ll_low(x) *(((unsigned int*)&(x))+0) +#define ll_high(x) *(((unsigned int*)&(x))+1) + +static inline void __set_64bit_var (unsigned long long *ptr, + unsigned long long value) +{ + __set_64bit(ptr,ll_low(value), ll_high(value)); +} + +#define set_64bit(ptr,value) \ +(__builtin_constant_p(value) ? \ + __set_64bit_constant(ptr, value) : \ + __set_64bit_var(ptr, value) ) + +#define _set_64bit(ptr,value) \ +(__builtin_constant_p(value) ? \ + __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \ + __set_64bit(ptr, ll_low(value), ll_high(value)) ) + +/* + * Note: no "lock" prefix even on SMP: xchg always implies lock anyway + * Note 2: xchg has side effect, so that attribute volatile is necessary, + * but generally the primitive is invalid, *ptr is output argument. --ANK + */ +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + switch (size) { + case 1: + __asm__ __volatile__("xchgb %b0,%1" + :"=q" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + case 2: + __asm__ __volatile__("xchgw %w0,%1" + :"=r" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + case 4: + __asm__ __volatile__("xchgl %0,%1" + :"=r" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + } + return x; +} + +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ + +#ifdef CONFIG_X86_CMPXCHG +#define __HAVE_ARCH_CMPXCHG 1 + +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + unsigned long prev; + switch (size) { + case 1: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + case 2: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + case 4: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + } + return old; +} + +#define cmpxchg(ptr,o,n)\ + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ + (unsigned long)(n),sizeof(*(ptr)))) + +#else +/* Compiling for a 386 proper. Is it worth implementing via cli/sti? */ +#endif + +/* + * Force strict CPU ordering. + * And yes, this is required on UP too when we're talking + * to devices. + * + * For now, "wmb()" doesn't actually do anything, as all + * Intel CPU's follow what Intel calls a *Processor Order*, + * in which all writes are seen in the program order even + * outside the CPU. + * + * I expect future Intel CPU's to have a weaker ordering, + * but I'd also expect them to finally get their act together + * and add some real memory barriers if so. + * + * Some non intel clones support out of order store. wmb() ceases to be a + * nop for these. + */ + +#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") +#define rmb() mb() + +#ifdef CONFIG_X86_OOSTORE +#define wmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") +#else +#define wmb() __asm__ __volatile__ ("": : :"memory") +#endif + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define set_mb(var, value) do { xchg(&var, value); } while (0) +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define set_mb(var, value) do { var = value; barrier(); } while (0) +#endif + +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +/* interrupt control.. */ +#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */) +#define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc") +#define __cli() __asm__ __volatile__("cli": : :"memory") +#define __sti() __asm__ __volatile__("sti": : :"memory") +/* used in the idle loop; sti takes one instruction cycle to complete */ +#define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory") + +#define __save_and_cli(x) do { __save_flags(x); __cli(); } while(0); +#define __save_and_sti(x) do { __save_flags(x); __sti(); } while(0); + +/* For spinlocks etc */ +#if 0 +#define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory") +#define local_irq_set(x) __asm__ __volatile__("pushfl ; popl %0 ; sti":"=g" (x): /* no input */ :"memory") +#else +#define local_irq_save(x) __save_and_cli(x) +#define local_irq_set(x) __save_and_sti(x) +#endif + +#define local_irq_restore(x) __restore_flags(x) +#define local_irq_disable() __cli() +#define local_irq_enable() __sti() + +#ifdef CONFIG_SMP + +extern void __global_cli(void); +extern void __global_sti(void); +extern unsigned long __global_save_flags(void); +extern void __global_restore_flags(unsigned long); +#define cli() __global_cli() +#define sti() __global_sti() +#define save_flags(x) ((x)=__global_save_flags()) +#define restore_flags(x) __global_restore_flags(x) +#define save_and_cli(x) do { save_flags(x); cli(); } while(0); +#define save_and_sti(x) do { save_flags(x); sti(); } while(0); + +#else + +#define cli() __cli() +#define sti() __sti() +#define save_flags(x) __save_flags(x) +#define restore_flags(x) __restore_flags(x) +#define save_and_cli(x) __save_and_cli(x) +#define save_and_sti(x) __save_and_sti(x) + +#endif + +/* + * disable hlt during certain critical i/o operations + */ +#define HAVE_DISABLE_HLT +void disable_hlt(void); +void enable_hlt(void); + +extern unsigned long dmi_broken; +extern int is_sony_vaio_laptop; + +#define BROKEN_ACPI_Sx 0x0001 +#define BROKEN_INIT_AFTER_S1 0x0002 +#define BROKEN_PNP_BIOS 0x0004 + +#endif diff -ruN linux-2.4.23-pre6/include/asm/termbits.h linux-2.4.23-pre6-swsusp/include/asm/termbits.h --- linux-2.4.23-pre6/include/asm/termbits.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/termbits.h 2000-01-21 09:05:26.000000000 +0900 @@ -0,0 +1,172 @@ +#ifndef __ARCH_I386_TERMBITS_H__ +#define __ARCH_I386_TERMBITS_H__ + +#include + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif diff -ruN linux-2.4.23-pre6/include/asm/termios.h linux-2.4.23-pre6-swsusp/include/asm/termios.h --- linux-2.4.23-pre6/include/asm/termios.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/termios.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,108 @@ +#ifndef _I386_TERMIOS_H +#define _I386_TERMIOS_H + +#include +#include + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */ + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 +#define N_X25 6 /* X.25 async */ +#define N_6PACK 7 +#define N_MASC 8 /* Reserved for Mobitex module */ +#define N_R3964 9 /* Reserved for Simatic R3964 module */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ +#define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */ +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 /* synchronous PPP */ +#define N_HCI 15 /* Bluetooth HCI UART */ + +#ifdef __KERNEL__ + +/* intr=^C quit=^\ erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ + unsigned short __tmp; \ + get_user(__tmp,&(termio)->x); \ + *(unsigned short *) &(termios)->x = __tmp; \ +} + +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* _I386_TERMIOS_H */ diff -ruN linux-2.4.23-pre6/include/asm/timex.h linux-2.4.23-pre6-swsusp/include/asm/timex.h --- linux-2.4.23-pre6/include/asm/timex.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/timex.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,58 @@ +/* + * linux/include/asm-i386/timex.h + * + * i386 architecture timex specifications + */ +#ifndef _ASMi386_TIMEX_H +#define _ASMi386_TIMEX_H + +#include +#include + +#ifdef CONFIG_MELAN +# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */ +#else +# define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +#endif + +#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ +#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ + (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ + << (SHIFT_SCALE-SHIFT_HZ)) / HZ) + +/* + * Standard way to access the cycle counter on i586+ CPUs. + * Currently only used on SMP. + * + * If you really have a SMP machine with i486 chips or older, + * compile for that, and this will just always return zero. + * That's ok, it just means that the nicer scheduling heuristics + * won't work for you. + * + * We only use the low 32 bits, and we'd simply better make sure + * that we reschedule before that wraps. Scheduling at least every + * four billion cycles just basically sounds like a good idea, + * regardless of how fast the machine is. + */ +typedef unsigned long long cycles_t; + +extern cycles_t cacheflush_time; + +static inline cycles_t get_cycles (void) +{ +#ifndef CONFIG_X86_TSC + return 0; +#else + unsigned long long ret; + + rdtscll(ret); + return ret; +#endif +} + +extern unsigned long cpu_khz; + +#define vxtime_lock() do {} while (0) +#define vxtime_unlock() do {} while (0) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/tlb.h linux-2.4.23-pre6-swsusp/include/asm/tlb.h --- linux-2.4.23-pre6/include/asm/tlb.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/tlb.h 2001-09-15 00:41:04.000000000 +0900 @@ -0,0 +1 @@ +#include diff -ruN linux-2.4.23-pre6/include/asm/types.h linux-2.4.23-pre6-swsusp/include/asm/types.h --- linux-2.4.23-pre6/include/asm/types.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/types.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,57 @@ +#ifndef _I386_TYPES_H +#define _I386_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#include + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* DMA addresses come in generic and 64-bit flavours. */ + +#ifdef CONFIG_HIGHMEM64G +typedef u64 dma_addr_t; +#else +typedef u32 dma_addr_t; +#endif +typedef u64 dma64_addr_t; + +#endif /* __KERNEL__ */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/uaccess.h linux-2.4.23-pre6-swsusp/include/asm/uaccess.h --- linux-2.4.23-pre6/include/asm/uaccess.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/uaccess.h 2003-06-13 23:51:38.000000000 +0900 @@ -0,0 +1,801 @@ +#ifndef __i386_UACCESS_H +#define __i386_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include +#include + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + * + * For historical reasons, these macros are grossly misnamed. + */ + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + + +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) +#define USER_DS MAKE_MM_SEG(PAGE_OFFSET) + +#define get_ds() (KERNEL_DS) +#define get_fs() (current->addr_limit) +#define set_fs(x) (current->addr_limit = (x)) + +#define segment_eq(a,b) ((a).seg == (b).seg) + +extern int __verify_write(const void *, unsigned long); + +#define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg)) + +/* + * Test whether a block of memory is a valid user space address. + * Returns 0 if the range is valid, nonzero otherwise. + * + * This is equivalent to the following test: + * (u33)addr + (u33)size >= (u33)current->addr_limit.seg + * + * This needs 33-bit arithmetic. We have a carry... + */ +#define __range_ok(addr,size) ({ \ + unsigned long flag,sum; \ + asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \ + :"=&r" (flag), "=r" (sum) \ + :"1" (addr),"g" ((int)(size)),"g" (current->addr_limit.seg)); \ + flag; }) + +#ifdef CONFIG_X86_WP_WORKS_OK + +/** + * access_ok: - Checks if a user space pointer is valid + * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that + * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe + * to write to a block, it is always safe to read from it. + * @addr: User space pointer to start of block to check + * @size: Size of block to check + * + * Context: User context only. This function may sleep. + * + * Checks if a pointer to a block of memory in user space is valid. + * + * Returns true (nonzero) if the memory block may be valid, false (zero) + * if it is definitely invalid. + * + * Note that, depending on architecture, this function probably just + * checks that the pointer is in the user space range - after calling + * this function, memory access functions may still return -EFAULT. + */ +#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) + +#else + +#define access_ok(type,addr,size) ( (__range_ok(addr,size) == 0) && \ + ((type) == VERIFY_READ || boot_cpu_data.wp_works_ok || \ + segment_eq(get_fs(),KERNEL_DS) || \ + __verify_write((void *)(addr),(size)))) + +#endif + +/** + * verify_area: - Obsolete, use access_ok() + * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE + * @addr: User space pointer to start of block to check + * @size: Size of block to check + * + * Context: User context only. This function may sleep. + * + * This function has been replaced by access_ok(). + * + * Checks if a pointer to a block of memory in user space is valid. + * + * Returns zero if the memory block may be valid, -EFAULT + * if it is definitely invalid. + * + * See access_ok() for more details. + */ +static inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size) ? 0 : -EFAULT; +} + + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + * + * This gets kind of ugly. We want to return _two_ values in "get_user()" + * and yet we don't want to do any pointers, because that is too much + * of a performance impact. Thus we have a few rather ugly macros here, + * and hide all the uglyness from the user. + * + * The "__xxx" versions of the user access functions are versions that + * do not verify the address space, that must have been done previously + * with a separate "access_ok()" call (this is used when we do multiple + * accesses to the same area of user memory). + */ + +extern void __get_user_1(void); +extern void __get_user_2(void); +extern void __get_user_4(void); + +#define __get_user_x(size,ret,x,ptr) \ + __asm__ __volatile__("call __get_user_" #size \ + :"=a" (ret),"=d" (x) \ + :"0" (ptr)) + + +/* Careful: we have to cast the result to the type of the pointer for sign reasons */ +/** + * get_user: - Get a simple variable from user space. + * @x: Variable to store result. + * @ptr: Source address, in user space. + * + * Context: User context only. This function may sleep. + * + * This macro copies a single simple variable from user space to kernel + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and the result of + * dereferencing @ptr must be assignable to @x without a cast. + * + * Returns zero on success, or -EFAULT on error. + * On error, the variable @x is set to zero. + */ +#define get_user(x,ptr) \ +({ int __ret_gu,__val_gu; \ + switch(sizeof (*(ptr))) { \ + case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ + case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ + case 4: __get_user_x(4,__ret_gu,__val_gu,ptr); break; \ + default: __get_user_x(X,__ret_gu,__val_gu,ptr); break; \ + } \ + (x) = (__typeof__(*(ptr)))__val_gu; \ + __ret_gu; \ +}) + +extern void __put_user_1(void); +extern void __put_user_2(void); +extern void __put_user_4(void); +extern void __put_user_8(void); + +extern void __put_user_bad(void); + + +/** + * put_user: - Write a simple value into user space. + * @x: Value to copy to user space. + * @ptr: Destination address, in user space. + * + * Context: User context only. This function may sleep. + * + * This macro copies a single simple value from kernel space to user + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and @x must be assignable + * to the result of dereferencing @ptr. + * + * Returns zero on success, or -EFAULT on error. + */ +#define put_user(x,ptr) \ + __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + + +/** + * __get_user: - Get a simple variable from user space, with less checking. + * @x: Variable to store result. + * @ptr: Source address, in user space. + * + * Context: User context only. This function may sleep. + * + * This macro copies a single simple variable from user space to kernel + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and the result of + * dereferencing @ptr must be assignable to @x without a cast. + * + * Caller must check the pointer with access_ok() before calling this + * function. + * + * Returns zero on success, or -EFAULT on error. + * On error, the variable @x is set to zero. + */ +#define __get_user(x,ptr) \ + __get_user_nocheck((x),(ptr),sizeof(*(ptr))) + + +/** + * __put_user: - Write a simple value into user space, with less checking. + * @x: Value to copy to user space. + * @ptr: Destination address, in user space. + * + * Context: User context only. This function may sleep. + * + * This macro copies a single simple value from kernel space to user + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and @x must be assignable + * to the result of dereferencing @ptr. + * + * Caller must check the pointer with access_ok() before calling this + * function. + * + * Returns zero on success, or -EFAULT on error. + */ +#define __put_user(x,ptr) \ + __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + +#define __put_user_nocheck(x,ptr,size) \ +({ \ + long __pu_err; \ + __put_user_size((x),(ptr),(size),__pu_err); \ + __pu_err; \ +}) + + +#define __put_user_check(x,ptr,size) \ +({ \ + long __pu_err = -EFAULT; \ + __typeof__(*(ptr)) *__pu_addr = (ptr); \ + if (access_ok(VERIFY_WRITE,__pu_addr,size)) \ + __put_user_size((x),__pu_addr,(size),__pu_err); \ + __pu_err; \ +}) + +#define __put_user_u64(x, addr, err) \ + __asm__ __volatile__( \ + "1: movl %%eax,0(%2)\n" \ + "2: movl %%edx,4(%2)\n" \ + "3:\n" \ + ".section .fixup,\"ax\"\n" \ + "4: movl %3,%0\n" \ + " jmp 3b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,4b\n" \ + " .long 2b,4b\n" \ + ".previous" \ + : "=r"(err) \ + : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err)) + +#define __put_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: __put_user_asm(x,ptr,retval,"b","b","iq"); break; \ + case 2: __put_user_asm(x,ptr,retval,"w","w","ir"); break; \ + case 4: __put_user_asm(x,ptr,retval,"l","","ir"); break; \ + case 8: __put_user_u64(x,ptr,retval); break; \ + default: __put_user_bad(); \ + } \ +} while (0) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct *)(x)) + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ +#define __put_user_asm(x, addr, err, itype, rtype, ltype) \ + __asm__ __volatile__( \ + "1: mov"itype" %"rtype"1,%2\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %3,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : "=r"(err) \ + : ltype (x), "m"(__m(addr)), "i"(-EFAULT), "0"(err)) + + +#define __get_user_nocheck(x,ptr,size) \ +({ \ + long __gu_err, __gu_val; \ + __get_user_size(__gu_val,(ptr),(size),__gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +extern long __get_user_bad(void); + +#define __get_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: __get_user_asm(x,ptr,retval,"b","b","=q"); break; \ + case 2: __get_user_asm(x,ptr,retval,"w","w","=r"); break; \ + case 4: __get_user_asm(x,ptr,retval,"l","","=r"); break; \ + default: (x) = __get_user_bad(); \ + } \ +} while (0) + +#define __get_user_asm(x, addr, err, itype, rtype, ltype) \ + __asm__ __volatile__( \ + "1: mov"itype" %2,%"rtype"1\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %3,%0\n" \ + " xor"itype" %"rtype"1,%"rtype"1\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : "=r"(err), ltype (x) \ + : "m"(__m(addr)), "i"(-EFAULT), "0"(err)) + + +/* + * Copy To/From Userspace + */ + +/* Generic arbitrary sized copy. */ +#define __copy_user(to,from,size) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + " movl %3,%0\n" \ + "1: rep; movsb\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: lea 0(%3,%0,4),%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,2b\n" \ + ".previous" \ + : "=&c"(size), "=&D" (__d0), "=&S" (__d1) \ + : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) \ + : "memory"); \ +} while (0) + +#define __copy_user_zeroing(to,from,size) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + " movl %3,%0\n" \ + "1: rep; movsb\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: lea 0(%3,%0,4),%0\n" \ + "4: pushl %0\n" \ + " pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " rep; stosb\n" \ + " popl %%eax\n" \ + " popl %0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,4b\n" \ + ".previous" \ + : "=&c"(size), "=&D" (__d0), "=&S" (__d1) \ + : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) \ + : "memory"); \ +} while (0) + +/* We let the __ versions of copy_from/to_user inline, because they're often + * used in fast paths and have only a small space overhead. + */ +static inline unsigned long +__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n) +{ + __copy_user_zeroing(to,from,n); + return n; +} + +static inline unsigned long +__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n) +{ + __copy_user(to,from,n); + return n; +} + + +/* Optimize just a little bit when we know the size of the move. */ +#define __constant_copy_user(to, from, size) \ +do { \ + int __d0, __d1; \ + switch (size & 3) { \ + default: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + "2: shl $2,%0\n" \ + " jmp 1b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,2b\n" \ + ".previous" \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ + break; \ + case 1: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsb\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: shl $2,%0\n" \ + "4: incl %0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,4b\n" \ + ".previous" \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ + break; \ + case 2: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsw\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: shl $2,%0\n" \ + "4: addl $2,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,4b\n" \ + ".previous" \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ + break; \ + case 3: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsw\n" \ + "2: movsb\n" \ + "3:\n" \ + ".section .fixup,\"ax\"\n" \ + "4: shl $2,%0\n" \ + "5: addl $2,%0\n" \ + "6: incl %0\n" \ + " jmp 3b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,4b\n" \ + " .long 1b,5b\n" \ + " .long 2b,6b\n" \ + ".previous" \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ + break; \ + } \ +} while (0) + +/* Optimize just a little bit when we know the size of the move. */ +#define __constant_copy_user_zeroing(to, from, size) \ +do { \ + int __d0, __d1; \ + switch (size & 3) { \ + default: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + "2: pushl %0\n" \ + " pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " rep; stosl\n" \ + " popl %%eax\n" \ + " popl %0\n" \ + " shl $2,%0\n" \ + " jmp 1b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,2b\n" \ + ".previous" \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ + break; \ + case 1: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsb\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: pushl %0\n" \ + " pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " rep; stosl\n" \ + " stosb\n" \ + " popl %%eax\n" \ + " popl %0\n" \ + " shl $2,%0\n" \ + " incl %0\n" \ + " jmp 2b\n" \ + "4: pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " stosb\n" \ + " popl %%eax\n" \ + " incl %0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,4b\n" \ + ".previous" \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ + break; \ + case 2: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsw\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: pushl %0\n" \ + " pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " rep; stosl\n" \ + " stosw\n" \ + " popl %%eax\n" \ + " popl %0\n" \ + " shl $2,%0\n" \ + " addl $2,%0\n" \ + " jmp 2b\n" \ + "4: pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " stosw\n" \ + " popl %%eax\n" \ + " addl $2,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,4b\n" \ + ".previous" \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ + break; \ + case 3: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsw\n" \ + "2: movsb\n" \ + "3:\n" \ + ".section .fixup,\"ax\"\n" \ + "4: pushl %0\n" \ + " pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " rep; stosl\n" \ + " stosw\n" \ + " stosb\n" \ + " popl %%eax\n" \ + " popl %0\n" \ + " shl $2,%0\n" \ + " addl $3,%0\n" \ + " jmp 2b\n" \ + "5: pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " stosw\n" \ + " stosb\n" \ + " popl %%eax\n" \ + " addl $3,%0\n" \ + " jmp 2b\n" \ + "6: pushl %%eax\n" \ + " xorl %%eax,%%eax\n" \ + " stosb\n" \ + " popl %%eax\n" \ + " incl %0\n" \ + " jmp 3b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,4b\n" \ + " .long 1b,5b\n" \ + " .long 2b,6b\n" \ + ".previous" \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ + break; \ + } \ +} while (0) + +unsigned long __generic_copy_to_user(void *, const void *, unsigned long); +unsigned long __generic_copy_from_user(void *, const void *, unsigned long); + +static inline unsigned long +__constant_copy_to_user(void *to, const void *from, unsigned long n) +{ + prefetch(from); + if (access_ok(VERIFY_WRITE, to, n)) + __constant_copy_user(to,from,n); + return n; +} + +static inline unsigned long +__constant_copy_from_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + __constant_copy_user_zeroing(to,from,n); + else + memset(to, 0, n); + return n; +} + +static inline unsigned long +__constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n) +{ + __constant_copy_user(to,from,n); + return n; +} + +static inline unsigned long +__constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n) +{ + __constant_copy_user_zeroing(to,from,n); + return n; +} + +/** + * copy_to_user: - Copy a block of data into user space. + * @to: Destination address, in user space. + * @from: Source address, in kernel space. + * @n: Number of bytes to copy. + * + * Context: User context only. This function may sleep. + * + * Copy data from kernel space to user space. + * + * Returns number of bytes that could not be copied. + * On success, this will be zero. + */ +#define copy_to_user(to,from,n) \ + (__builtin_constant_p(n) ? \ + __constant_copy_to_user((to),(from),(n)) : \ + __generic_copy_to_user((to),(from),(n))) + +/** + * copy_from_user: - Copy a block of data from user space. + * @to: Destination address, in kernel space. + * @from: Source address, in user space. + * @n: Number of bytes to copy. + * + * Context: User context only. This function may sleep. + * + * Copy data from user space to kernel space. + * + * Returns number of bytes that could not be copied. + * On success, this will be zero. + * + * If some data could not be copied, this function will pad the copied + * data to the requested size using zero bytes. + */ +#define copy_from_user(to,from,n) \ + (__builtin_constant_p(n) ? \ + __constant_copy_from_user((to),(from),(n)) : \ + __generic_copy_from_user((to),(from),(n))) + +/** + * __copy_to_user: - Copy a block of data into user space, with less checking. + * @to: Destination address, in user space. + * @from: Source address, in kernel space. + * @n: Number of bytes to copy. + * + * Context: User context only. This function may sleep. + * + * Copy data from kernel space to user space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be copied. + * On success, this will be zero. + */ +#define __copy_to_user(to,from,n) \ + (__builtin_constant_p(n) ? \ + __constant_copy_to_user_nocheck((to),(from),(n)) : \ + __generic_copy_to_user_nocheck((to),(from),(n))) + +/** + * __copy_from_user: - Copy a block of data from user space, with less checking. + * @to: Destination address, in kernel space. + * @from: Source address, in user space. + * @n: Number of bytes to copy. + * + * Context: User context only. This function may sleep. + * + * Copy data from user space to kernel space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be copied. + * On success, this will be zero. + * + * If some data could not be copied, this function will pad the copied + * data to the requested size using zero bytes. + */ +#define __copy_from_user(to,from,n) \ + (__builtin_constant_p(n) ? \ + __constant_copy_from_user_nocheck((to),(from),(n)) : \ + __generic_copy_from_user_nocheck((to),(from),(n))) + +long strncpy_from_user(char *dst, const char *src, long count); +long __strncpy_from_user(char *dst, const char *src, long count); + +/** + * strlen_user: - Get the size of a string in user space. + * @str: The string to measure. + * + * Context: User context only. This function may sleep. + * + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * + * If there is a limit on the length of a valid string, you may wish to + * consider using strnlen_user() instead. + */ +#define strlen_user(str) strnlen_user(str, ~0UL >> 1) + +long strnlen_user(const char *str, long n); +unsigned long clear_user(void *mem, unsigned long len); +unsigned long __clear_user(void *mem, unsigned long len); + +#endif /* __i386_UACCESS_H */ diff -ruN linux-2.4.23-pre6/include/asm/ucontext.h linux-2.4.23-pre6-swsusp/include/asm/ucontext.h --- linux-2.4.23-pre6/include/asm/ucontext.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/ucontext.h 1997-12-02 03:45:24.000000000 +0900 @@ -0,0 +1,12 @@ +#ifndef _ASMi386_UCONTEXT_H +#define _ASMi386_UCONTEXT_H + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif /* !_ASMi386_UCONTEXT_H */ diff -ruN linux-2.4.23-pre6/include/asm/unaligned.h linux-2.4.23-pre6-swsusp/include/asm/unaligned.h --- linux-2.4.23-pre6/include/asm/unaligned.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/unaligned.h 2001-05-23 02:23:16.000000000 +0900 @@ -0,0 +1,37 @@ +#ifndef __I386_UNALIGNED_H +#define __I386_UNALIGNED_H + +/* + * The i386 can do unaligned accesses itself. + * + * The strange macros are there to make sure these can't + * be misused in a way that makes them not work on other + * architectures where unaligned accesses aren't as simple. + */ + +/** + * get_unaligned - get value from possibly mis-aligned location + * @ptr: pointer to value + * + * This macro should be used for accessing values larger in size than + * single bytes at locations that are expected to be improperly aligned, + * e.g. retrieving a u16 value from a location not u16-aligned. + * + * Note that unaligned accesses can be very expensive on some architectures. + */ +#define get_unaligned(ptr) (*(ptr)) + +/** + * put_unaligned - put value to a possibly mis-aligned location + * @val: value to place + * @ptr: pointer to location + * + * This macro should be used for placing values larger in size than + * single bytes at locations that are expected to be improperly aligned, + * e.g. writing a u16 value to a location not u16-aligned. + * + * Note that unaligned accesses can be very expensive on some architectures. + */ +#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/unistd.h linux-2.4.23-pre6-swsusp/include/asm/unistd.h --- linux-2.4.23-pre6/include/asm/unistd.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/unistd.h 2002-11-29 08:53:15.000000000 +0900 @@ -0,0 +1,386 @@ +#ifndef _ASM_I386_UNISTD_H_ +#define _ASM_I386_UNISTD_H_ + +/* + * This file contains the system call numbers. + */ + +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_lchown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86old 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_vm86 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread 180 +#define __NR_pwrite 181 +#define __NR_chown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_lchown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_chown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_mincore 218 +#define __NR_madvise 219 +#define __NR_madvise1 219 /* delete when C lib stub is removed */ +#define __NR_getdents64 220 +#define __NR_fcntl64 221 +#define __NR_security 223 /* syscall for security modules */ +#define __NR_gettid 224 +#define __NR_readahead 225 +#define __NR_setxattr 226 +#define __NR_lsetxattr 227 +#define __NR_fsetxattr 228 +#define __NR_getxattr 229 +#define __NR_lgetxattr 230 +#define __NR_fgetxattr 231 +#define __NR_listxattr 232 +#define __NR_llistxattr 233 +#define __NR_flistxattr 234 +#define __NR_removexattr 235 +#define __NR_lremovexattr 236 +#define __NR_fremovexattr 237 +#define __NR_tkill 238 +#define __NR_sendfile64 239 +#define __NR_futex 240 +#define __NR_sched_setaffinity 241 +#define __NR_sched_getaffinity 242 +#define __NR_set_thread_area 243 +#define __NR_get_thread_area 244 +#define __NR_io_setup 245 +#define __NR_io_destroy 246 +#define __NR_io_getevents 247 +#define __NR_io_submit 248 +#define __NR_io_cancel 249 +#define __NR_alloc_hugepages 250 +#define __NR_free_hugepages 251 +#define __NR_exit_group 252 + +/* user-visible error numbers are in the range -1 - -124: see */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name)); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(arg1))); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3))); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4))); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \ +__syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \ + : "=a" (__res) \ + : "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \ + "0" ((long)(arg6))); \ +__syscall_return(type,__res); \ +} + +#ifdef __KERNEL_SYSCALLS__ + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static inline _syscall0(int,pause) +static inline _syscall0(int,sync) +static inline _syscall0(pid_t,setsid) +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) +static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count) +static inline _syscall1(int,dup,int,fd) +static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static inline _syscall3(int,open,const char *,file,int,flag,int,mode) +static inline _syscall1(int,close,int,fd) +static inline _syscall1(int,_exit,int,exitcode) +static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) +static inline _syscall1(int,delete_module,const char *,name) + +static inline pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +#endif + +#endif /* _ASM_I386_UNISTD_H_ */ diff -ruN linux-2.4.23-pre6/include/asm/user.h linux-2.4.23-pre6-swsusp/include/asm/user.h --- linux-2.4.23-pre6/include/asm/user.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/user.h 2001-11-23 04:48:21.000000000 +0900 @@ -0,0 +1,122 @@ +#ifndef _I386_USER_H +#define _I386_USER_H + +#include +#include +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ + +/* + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 + * + * Provide support for the GDB 5.0+ PTRACE_{GET|SET}FPXREGS requests for + * interacting with the FXSR-format floating point environment. Floating + * point data can be accessed in the regular format in the usual manner, + * and both the standard and SIMD floating point data can be accessed via + * the new ptrace requests. In either case, changes to the FPU environment + * will be reflected in the task's state as expected. + */ + +struct user_i387_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ +}; + +struct user_fxsr_struct { + unsigned short cwd; + unsigned short swd; + unsigned short twd; + unsigned short fop; + long fip; + long fcs; + long foo; + long fos; + long mxcsr; + long reserved; + long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ + long padding[56]; +}; + +/* + * This is the old layout of "struct pt_regs", and + * is still the layout used by user mode (the new + * pt_regs doesn't have all registers as the kernel + * doesn't use the extra segment registers) + */ +struct user_regs_struct { + long ebx, ecx, edx, esi, edi, ebp, eax; + unsigned short ds, __ds, es, __es; + unsigned short fs, __fs, gs, __gs; + long orig_eax, eip; + unsigned short cs, __cs; + long eflags, esp; + unsigned short ss, __ss; +}; + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ +struct user{ +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + struct user_regs_struct regs; /* Where the registers are actually stored */ +/* ptrace does not yet supply these. Someday.... */ + int u_fpvalid; /* True if math co-processor being used. */ + /* for this mess. Not yet used. */ + struct user_i387_struct i387; /* Math Co-processor registers. */ +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct user_pt_regs * u_ar0; /* Used by gdb to help find the values for */ + /* the registers. */ + struct user_i387_struct* u_fpstate; /* Math Co-processor pointer. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ + int u_debugreg[8]; +}; +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* _I386_USER_H */ diff -ruN linux-2.4.23-pre6/include/asm/vga.h linux-2.4.23-pre6-swsusp/include/asm/vga.h --- linux-2.4.23-pre6/include/asm/vga.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/vga.h 1998-07-11 07:18:32.000000000 +0900 @@ -0,0 +1,20 @@ +/* + * Access to VGA videoram + * + * (c) 1998 Martin Mares + */ + +#ifndef _LINUX_ASM_VGA_H_ +#define _LINUX_ASM_VGA_H_ + +/* + * On the PC, we can just recalculate addresses and then + * access the videoram directly without any black magic. + */ + +#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) + +#define vga_readb(x) (*(x)) +#define vga_writeb(x,y) (*(y) = (x)) + +#endif diff -ruN linux-2.4.23-pre6/include/asm/vm86.h linux-2.4.23-pre6-swsusp/include/asm/vm86.h --- linux-2.4.23-pre6/include/asm/vm86.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/vm86.h 1998-06-25 06:30:11.000000000 +0900 @@ -0,0 +1,208 @@ +#ifndef _LINUX_VM86_H +#define _LINUX_VM86_H + +/* + * I'm guessing at the VIF/VIP flag usage, but hope that this is how + * the Pentium uses them. Linux will return from vm86 mode when both + * VIF and VIP is set. + * + * On a Pentium, we could probably optimize the virtual flags directly + * in the eflags register instead of doing it "by hand" in vflags... + * + * Linus + */ + +#define TF_MASK 0x00000100 +#define IF_MASK 0x00000200 +#define IOPL_MASK 0x00003000 +#define NT_MASK 0x00004000 +#define VM_MASK 0x00020000 +#define AC_MASK 0x00040000 +#define VIF_MASK 0x00080000 /* virtual interrupt flag */ +#define VIP_MASK 0x00100000 /* virtual interrupt pending */ +#define ID_MASK 0x00200000 + +#define BIOSSEG 0x0f000 + +#define CPU_086 0 +#define CPU_186 1 +#define CPU_286 2 +#define CPU_386 3 +#define CPU_486 4 +#define CPU_586 5 + +/* + * Return values for the 'vm86()' system call + */ +#define VM86_TYPE(retval) ((retval) & 0xff) +#define VM86_ARG(retval) ((retval) >> 8) + +#define VM86_SIGNAL 0 /* return due to signal */ +#define VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */ +#define VM86_INTx 2 /* int3/int x instruction (ARG = x) */ +#define VM86_STI 3 /* sti/popf/iret instruction enabled virtual interrupts */ + +/* + * Additional return values when invoking new vm86() + */ +#define VM86_PICRETURN 4 /* return due to pending PIC request */ +#define VM86_TRAP 6 /* return due to DOS-debugger request */ + +/* + * function codes when invoking new vm86() + */ +#define VM86_PLUS_INSTALL_CHECK 0 +#define VM86_ENTER 1 +#define VM86_ENTER_NO_BYPASS 2 +#define VM86_REQUEST_IRQ 3 +#define VM86_FREE_IRQ 4 +#define VM86_GET_IRQ_BITS 5 +#define VM86_GET_AND_RESET_IRQ 6 + +/* + * This is the stack-layout seen by the user space program when we have + * done a translation of "SAVE_ALL" from vm86 mode. The real kernel layout + * is 'kernel_vm86_regs' (see below). + */ + +struct vm86_regs { +/* + * normal regs, with special meaning for the segment descriptors.. + */ + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + long __null_ds; + long __null_es; + long __null_fs; + long __null_gs; + long orig_eax; + long eip; + unsigned short cs, __csh; + long eflags; + long esp; + unsigned short ss, __ssh; +/* + * these are specific to v86 mode: + */ + unsigned short es, __esh; + unsigned short ds, __dsh; + unsigned short fs, __fsh; + unsigned short gs, __gsh; +}; + +struct revectored_struct { + unsigned long __map[8]; /* 256 bits */ +}; + +struct vm86_struct { + struct vm86_regs regs; + unsigned long flags; + unsigned long screen_bitmap; + unsigned long cpu_type; + struct revectored_struct int_revectored; + struct revectored_struct int21_revectored; +}; + +/* + * flags masks + */ +#define VM86_SCREEN_BITMAP 0x0001 + +struct vm86plus_info_struct { + unsigned long force_return_for_pic:1; + unsigned long vm86dbg_active:1; /* for debugger */ + unsigned long vm86dbg_TFpendig:1; /* for debugger */ + unsigned long unused:28; + unsigned long is_vm86pus:1; /* for vm86 internal use */ + unsigned char vm86dbg_intxxtab[32]; /* for debugger */ +}; + +struct vm86plus_struct { + struct vm86_regs regs; + unsigned long flags; + unsigned long screen_bitmap; + unsigned long cpu_type; + struct revectored_struct int_revectored; + struct revectored_struct int21_revectored; + struct vm86plus_info_struct vm86plus; +}; + +#ifdef __KERNEL__ +/* + * This is the (kernel) stack-layout when we have done a "SAVE_ALL" from vm86 + * mode - the main change is that the old segment descriptors aren't + * useful any more and are forced to be zero by the kernel (and the + * hardware when a trap occurs), and the real segment descriptors are + * at the end of the structure. Look at ptrace.h to see the "normal" + * setup. For user space layout see 'struct vm86_regs' above. + */ + +struct kernel_vm86_regs { +/* + * normal regs, with special meaning for the segment descriptors.. + */ + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + long __null_ds; + long __null_es; + long orig_eax; + long eip; + unsigned short cs, __csh; + long eflags; + long esp; + unsigned short ss, __ssh; +/* + * these are specific to v86 mode: + */ + unsigned short es, __esh; + unsigned short ds, __dsh; + unsigned short fs, __fsh; + unsigned short gs, __gsh; +}; + +struct kernel_vm86_struct { + struct kernel_vm86_regs regs; +/* + * the below part remains on the kernel stack while we are in VM86 mode. + * 'tss.esp0' then contains the address of VM86_TSS_ESP0 below, and when we + * get forced back from VM86, the CPU and "SAVE_ALL" will restore the above + * 'struct kernel_vm86_regs' with the then actual values. + * Therefore, pt_regs in fact points to a complete 'kernel_vm86_struct' + * in kernelspace, hence we need not reget the data from userspace. + */ +#define VM86_TSS_ESP0 flags + unsigned long flags; + unsigned long screen_bitmap; + unsigned long cpu_type; + struct revectored_struct int_revectored; + struct revectored_struct int21_revectored; + struct vm86plus_info_struct vm86plus; + struct pt_regs *regs32; /* here we save the pointer to the old regs */ +/* + * The below is not part of the structure, but the stack layout continues + * this way. In front of 'return-eip' may be some data, depending on + * compilation, so we don't rely on this and save the pointer to 'oldregs' + * in 'regs32' above. + * However, with GCC-2.7.2 and the current CFLAGS you see exactly this: + + long return-eip; from call to vm86() + struct pt_regs oldregs; user space registers as saved by syscall + */ +}; + +void handle_vm86_fault(struct kernel_vm86_regs *, long); +int handle_vm86_trap(struct kernel_vm86_regs *, long, int); + +#endif /* __KERNEL__ */ + +#endif diff -ruN linux-2.4.23-pre6/include/asm/xor.h linux-2.4.23-pre6-swsusp/include/asm/xor.h --- linux-2.4.23-pre6/include/asm/xor.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm/xor.h 2002-08-03 09:39:45.000000000 +0900 @@ -0,0 +1,878 @@ +/* + * include/asm-i386/xor.h + * + * Optimized RAID-5 checksumming functions for MMX and SSE. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * You should have received a copy of the GNU General Public License + * (for example /usr/src/linux/COPYING); if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * High-speed RAID5 checksumming functions utilizing MMX instructions. + * Copyright (C) 1998 Ingo Molnar. + */ + +#define FPU_SAVE \ + do { \ + if (!(current->flags & PF_USEDFPU)) \ + __asm__ __volatile__ (" clts;\n"); \ + __asm__ __volatile__ ("fsave %0; fwait": "=m"(fpu_save[0])); \ + } while (0) + +#define FPU_RESTORE \ + do { \ + __asm__ __volatile__ ("frstor %0": : "m"(fpu_save[0])); \ + if (!(current->flags & PF_USEDFPU)) \ + stts(); \ + } while (0) + +#define LD(x,y) " movq 8*("#x")(%1), %%mm"#y" ;\n" +#define ST(x,y) " movq %%mm"#y", 8*("#x")(%1) ;\n" +#define XO1(x,y) " pxor 8*("#x")(%2), %%mm"#y" ;\n" +#define XO2(x,y) " pxor 8*("#x")(%3), %%mm"#y" ;\n" +#define XO3(x,y) " pxor 8*("#x")(%4), %%mm"#y" ;\n" +#define XO4(x,y) " pxor 8*("#x")(%5), %%mm"#y" ;\n" + + +static void +xor_pII_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) +{ + unsigned long lines = bytes >> 7; + char fpu_save[108]; + + FPU_SAVE; + + __asm__ __volatile__ ( +#undef BLOCK +#define BLOCK(i) \ + LD(i,0) \ + LD(i+1,1) \ + LD(i+2,2) \ + LD(i+3,3) \ + XO1(i,0) \ + ST(i,0) \ + XO1(i+1,1) \ + ST(i+1,1) \ + XO1(i+2,2) \ + ST(i+2,2) \ + XO1(i+3,3) \ + ST(i+3,3) + + " .align 32 ;\n" + " 1: ;\n" + + BLOCK(0) + BLOCK(4) + BLOCK(8) + BLOCK(12) + + " addl $128, %1 ;\n" + " addl $128, %2 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r" (p2) + : + : "memory"); + + FPU_RESTORE; +} + +static void +xor_pII_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3) +{ + unsigned long lines = bytes >> 7; + char fpu_save[108]; + + FPU_SAVE; + + __asm__ __volatile__ ( +#undef BLOCK +#define BLOCK(i) \ + LD(i,0) \ + LD(i+1,1) \ + LD(i+2,2) \ + LD(i+3,3) \ + XO1(i,0) \ + XO1(i+1,1) \ + XO1(i+2,2) \ + XO1(i+3,3) \ + XO2(i,0) \ + ST(i,0) \ + XO2(i+1,1) \ + ST(i+1,1) \ + XO2(i+2,2) \ + ST(i+2,2) \ + XO2(i+3,3) \ + ST(i+3,3) + + " .align 32 ;\n" + " 1: ;\n" + + BLOCK(0) + BLOCK(4) + BLOCK(8) + BLOCK(12) + + " addl $128, %1 ;\n" + " addl $128, %2 ;\n" + " addl $128, %3 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r" (p2), "+r" (p3) + : + : "memory"); + + FPU_RESTORE; +} + +static void +xor_pII_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4) +{ + unsigned long lines = bytes >> 7; + char fpu_save[108]; + + FPU_SAVE; + + __asm__ __volatile__ ( +#undef BLOCK +#define BLOCK(i) \ + LD(i,0) \ + LD(i+1,1) \ + LD(i+2,2) \ + LD(i+3,3) \ + XO1(i,0) \ + XO1(i+1,1) \ + XO1(i+2,2) \ + XO1(i+3,3) \ + XO2(i,0) \ + XO2(i+1,1) \ + XO2(i+2,2) \ + XO2(i+3,3) \ + XO3(i,0) \ + ST(i,0) \ + XO3(i+1,1) \ + ST(i+1,1) \ + XO3(i+2,2) \ + ST(i+2,2) \ + XO3(i+3,3) \ + ST(i+3,3) + + " .align 32 ;\n" + " 1: ;\n" + + BLOCK(0) + BLOCK(4) + BLOCK(8) + BLOCK(12) + + " addl $128, %1 ;\n" + " addl $128, %2 ;\n" + " addl $128, %3 ;\n" + " addl $128, %4 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4) + : + : "memory"); + + FPU_RESTORE; +} + + +static void +xor_pII_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4, unsigned long *p5) +{ + unsigned long lines = bytes >> 7; + char fpu_save[108]; + + FPU_SAVE; + + /* need to save/restore p4/p5 manually otherwise gcc's 10 argument + limit gets exceeded (+ counts as two arguments) */ + __asm__ __volatile__ ( + " pushl %4\n" + " pushl %5\n" +#undef BLOCK +#define BLOCK(i) \ + LD(i,0) \ + LD(i+1,1) \ + LD(i+2,2) \ + LD(i+3,3) \ + XO1(i,0) \ + XO1(i+1,1) \ + XO1(i+2,2) \ + XO1(i+3,3) \ + XO2(i,0) \ + XO2(i+1,1) \ + XO2(i+2,2) \ + XO2(i+3,3) \ + XO3(i,0) \ + XO3(i+1,1) \ + XO3(i+2,2) \ + XO3(i+3,3) \ + XO4(i,0) \ + ST(i,0) \ + XO4(i+1,1) \ + ST(i+1,1) \ + XO4(i+2,2) \ + ST(i+2,2) \ + XO4(i+3,3) \ + ST(i+3,3) + + " .align 32 ;\n" + " 1: ;\n" + + BLOCK(0) + BLOCK(4) + BLOCK(8) + BLOCK(12) + + " addl $128, %1 ;\n" + " addl $128, %2 ;\n" + " addl $128, %3 ;\n" + " addl $128, %4 ;\n" + " addl $128, %5 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + " popl %5\n" + " popl %4\n" + : "+r" (lines), + "+r" (p1), "+r" (p2), "+r" (p3) + : "r" (p4), "r" (p5) + : "memory"); + + FPU_RESTORE; +} + +#undef LD +#undef XO1 +#undef XO2 +#undef XO3 +#undef XO4 +#undef ST +#undef BLOCK + +static void +xor_p5_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) +{ + unsigned long lines = bytes >> 6; + char fpu_save[108]; + + FPU_SAVE; + + __asm__ __volatile__ ( + " .align 32 ;\n" + " 1: ;\n" + " movq (%1), %%mm0 ;\n" + " movq 8(%1), %%mm1 ;\n" + " pxor (%2), %%mm0 ;\n" + " movq 16(%1), %%mm2 ;\n" + " movq %%mm0, (%1) ;\n" + " pxor 8(%2), %%mm1 ;\n" + " movq 24(%1), %%mm3 ;\n" + " movq %%mm1, 8(%1) ;\n" + " pxor 16(%2), %%mm2 ;\n" + " movq 32(%1), %%mm4 ;\n" + " movq %%mm2, 16(%1) ;\n" + " pxor 24(%2), %%mm3 ;\n" + " movq 40(%1), %%mm5 ;\n" + " movq %%mm3, 24(%1) ;\n" + " pxor 32(%2), %%mm4 ;\n" + " movq 48(%1), %%mm6 ;\n" + " movq %%mm4, 32(%1) ;\n" + " pxor 40(%2), %%mm5 ;\n" + " movq 56(%1), %%mm7 ;\n" + " movq %%mm5, 40(%1) ;\n" + " pxor 48(%2), %%mm6 ;\n" + " pxor 56(%2), %%mm7 ;\n" + " movq %%mm6, 48(%1) ;\n" + " movq %%mm7, 56(%1) ;\n" + + " addl $64, %1 ;\n" + " addl $64, %2 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r" (p2) + : + : "memory"); + + FPU_RESTORE; +} + +static void +xor_p5_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3) +{ + unsigned long lines = bytes >> 6; + char fpu_save[108]; + + FPU_SAVE; + + __asm__ __volatile__ ( + " .align 32,0x90 ;\n" + " 1: ;\n" + " movq (%1), %%mm0 ;\n" + " movq 8(%1), %%mm1 ;\n" + " pxor (%2), %%mm0 ;\n" + " movq 16(%1), %%mm2 ;\n" + " pxor 8(%2), %%mm1 ;\n" + " pxor (%3), %%mm0 ;\n" + " pxor 16(%2), %%mm2 ;\n" + " movq %%mm0, (%1) ;\n" + " pxor 8(%3), %%mm1 ;\n" + " pxor 16(%3), %%mm2 ;\n" + " movq 24(%1), %%mm3 ;\n" + " movq %%mm1, 8(%1) ;\n" + " movq 32(%1), %%mm4 ;\n" + " movq 40(%1), %%mm5 ;\n" + " pxor 24(%2), %%mm3 ;\n" + " movq %%mm2, 16(%1) ;\n" + " pxor 32(%2), %%mm4 ;\n" + " pxor 24(%3), %%mm3 ;\n" + " pxor 40(%2), %%mm5 ;\n" + " movq %%mm3, 24(%1) ;\n" + " pxor 32(%3), %%mm4 ;\n" + " pxor 40(%3), %%mm5 ;\n" + " movq 48(%1), %%mm6 ;\n" + " movq %%mm4, 32(%1) ;\n" + " movq 56(%1), %%mm7 ;\n" + " pxor 48(%2), %%mm6 ;\n" + " movq %%mm5, 40(%1) ;\n" + " pxor 56(%2), %%mm7 ;\n" + " pxor 48(%3), %%mm6 ;\n" + " pxor 56(%3), %%mm7 ;\n" + " movq %%mm6, 48(%1) ;\n" + " movq %%mm7, 56(%1) ;\n" + + " addl $64, %1 ;\n" + " addl $64, %2 ;\n" + " addl $64, %3 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r" (p2), "+r" (p3) + : + : "memory" ); + + FPU_RESTORE; +} + +static void +xor_p5_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4) +{ + unsigned long lines = bytes >> 6; + char fpu_save[108]; + + FPU_SAVE; + + __asm__ __volatile__ ( + " .align 32,0x90 ;\n" + " 1: ;\n" + " movq (%1), %%mm0 ;\n" + " movq 8(%1), %%mm1 ;\n" + " pxor (%2), %%mm0 ;\n" + " movq 16(%1), %%mm2 ;\n" + " pxor 8(%2), %%mm1 ;\n" + " pxor (%3), %%mm0 ;\n" + " pxor 16(%2), %%mm2 ;\n" + " pxor 8(%3), %%mm1 ;\n" + " pxor (%4), %%mm0 ;\n" + " movq 24(%1), %%mm3 ;\n" + " pxor 16(%3), %%mm2 ;\n" + " pxor 8(%4), %%mm1 ;\n" + " movq %%mm0, (%1) ;\n" + " movq 32(%1), %%mm4 ;\n" + " pxor 24(%2), %%mm3 ;\n" + " pxor 16(%4), %%mm2 ;\n" + " movq %%mm1, 8(%1) ;\n" + " movq 40(%1), %%mm5 ;\n" + " pxor 32(%2), %%mm4 ;\n" + " pxor 24(%3), %%mm3 ;\n" + " movq %%mm2, 16(%1) ;\n" + " pxor 40(%2), %%mm5 ;\n" + " pxor 32(%3), %%mm4 ;\n" + " pxor 24(%4), %%mm3 ;\n" + " movq %%mm3, 24(%1) ;\n" + " movq 56(%1), %%mm7 ;\n" + " movq 48(%1), %%mm6 ;\n" + " pxor 40(%3), %%mm5 ;\n" + " pxor 32(%4), %%mm4 ;\n" + " pxor 48(%2), %%mm6 ;\n" + " movq %%mm4, 32(%1) ;\n" + " pxor 56(%2), %%mm7 ;\n" + " pxor 40(%4), %%mm5 ;\n" + " pxor 48(%3), %%mm6 ;\n" + " pxor 56(%3), %%mm7 ;\n" + " movq %%mm5, 40(%1) ;\n" + " pxor 48(%4), %%mm6 ;\n" + " pxor 56(%4), %%mm7 ;\n" + " movq %%mm6, 48(%1) ;\n" + " movq %%mm7, 56(%1) ;\n" + + " addl $64, %1 ;\n" + " addl $64, %2 ;\n" + " addl $64, %3 ;\n" + " addl $64, %4 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4) + : + : "memory"); + + FPU_RESTORE; +} + +static void +xor_p5_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4, unsigned long *p5) +{ + unsigned long lines = bytes >> 6; + char fpu_save[108]; + + FPU_SAVE; + + /* need to save p4/p5 manually to not exceed gcc's 10 argument limit */ + __asm__ __volatile__ ( + " pushl %4\n" + " pushl %5\n" + " .align 32,0x90 ;\n" + " 1: ;\n" + " movq (%1), %%mm0 ;\n" + " movq 8(%1), %%mm1 ;\n" + " pxor (%2), %%mm0 ;\n" + " pxor 8(%2), %%mm1 ;\n" + " movq 16(%1), %%mm2 ;\n" + " pxor (%3), %%mm0 ;\n" + " pxor 8(%3), %%mm1 ;\n" + " pxor 16(%2), %%mm2 ;\n" + " pxor (%4), %%mm0 ;\n" + " pxor 8(%4), %%mm1 ;\n" + " pxor 16(%3), %%mm2 ;\n" + " movq 24(%1), %%mm3 ;\n" + " pxor (%5), %%mm0 ;\n" + " pxor 8(%5), %%mm1 ;\n" + " movq %%mm0, (%1) ;\n" + " pxor 16(%4), %%mm2 ;\n" + " pxor 24(%2), %%mm3 ;\n" + " movq %%mm1, 8(%1) ;\n" + " pxor 16(%5), %%mm2 ;\n" + " pxor 24(%3), %%mm3 ;\n" + " movq 32(%1), %%mm4 ;\n" + " movq %%mm2, 16(%1) ;\n" + " pxor 24(%4), %%mm3 ;\n" + " pxor 32(%2), %%mm4 ;\n" + " movq 40(%1), %%mm5 ;\n" + " pxor 24(%5), %%mm3 ;\n" + " pxor 32(%3), %%mm4 ;\n" + " pxor 40(%2), %%mm5 ;\n" + " movq %%mm3, 24(%1) ;\n" + " pxor 32(%4), %%mm4 ;\n" + " pxor 40(%3), %%mm5 ;\n" + " movq 48(%1), %%mm6 ;\n" + " movq 56(%1), %%mm7 ;\n" + " pxor 32(%5), %%mm4 ;\n" + " pxor 40(%4), %%mm5 ;\n" + " pxor 48(%2), %%mm6 ;\n" + " pxor 56(%2), %%mm7 ;\n" + " movq %%mm4, 32(%1) ;\n" + " pxor 48(%3), %%mm6 ;\n" + " pxor 56(%3), %%mm7 ;\n" + " pxor 40(%5), %%mm5 ;\n" + " pxor 48(%4), %%mm6 ;\n" + " pxor 56(%4), %%mm7 ;\n" + " movq %%mm5, 40(%1) ;\n" + " pxor 48(%5), %%mm6 ;\n" + " pxor 56(%5), %%mm7 ;\n" + " movq %%mm6, 48(%1) ;\n" + " movq %%mm7, 56(%1) ;\n" + + " addl $64, %1 ;\n" + " addl $64, %2 ;\n" + " addl $64, %3 ;\n" + " addl $64, %4 ;\n" + " addl $64, %5 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + " popl %5\n" + " popl %4\n" + : "+g" (lines), + "+r" (p1), "+r" (p2), "+r" (p3) + : "r" (p4), "r" (p5) + : "memory"); + + FPU_RESTORE; +} + +static struct xor_block_template xor_block_pII_mmx = { + name: "pII_mmx", + do_2: xor_pII_mmx_2, + do_3: xor_pII_mmx_3, + do_4: xor_pII_mmx_4, + do_5: xor_pII_mmx_5, +}; + +static struct xor_block_template xor_block_p5_mmx = { + name: "p5_mmx", + do_2: xor_p5_mmx_2, + do_3: xor_p5_mmx_3, + do_4: xor_p5_mmx_4, + do_5: xor_p5_mmx_5, +}; + +#undef FPU_SAVE +#undef FPU_RESTORE + +/* + * Cache avoiding checksumming functions utilizing KNI instructions + * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo) + */ + +#define XMMS_SAVE \ + __asm__ __volatile__ ( \ + "movl %%cr0,%0 ;\n\t" \ + "clts ;\n\t" \ + "movups %%xmm0,(%1) ;\n\t" \ + "movups %%xmm1,0x10(%1) ;\n\t" \ + "movups %%xmm2,0x20(%1) ;\n\t" \ + "movups %%xmm3,0x30(%1) ;\n\t" \ + : "=&r" (cr0) \ + : "r" (xmm_save) \ + : "memory") + +#define XMMS_RESTORE \ + __asm__ __volatile__ ( \ + "sfence ;\n\t" \ + "movups (%1),%%xmm0 ;\n\t" \ + "movups 0x10(%1),%%xmm1 ;\n\t" \ + "movups 0x20(%1),%%xmm2 ;\n\t" \ + "movups 0x30(%1),%%xmm3 ;\n\t" \ + "movl %0,%%cr0 ;\n\t" \ + : \ + : "r" (cr0), "r" (xmm_save) \ + : "memory") + +#define ALIGN16 __attribute__((aligned(16))) + +#define OFFS(x) "16*("#x")" +#define PF_OFFS(x) "256+16*("#x")" +#define PF0(x) " prefetchnta "PF_OFFS(x)"(%1) ;\n" +#define LD(x,y) " movaps "OFFS(x)"(%1), %%xmm"#y" ;\n" +#define ST(x,y) " movaps %%xmm"#y", "OFFS(x)"(%1) ;\n" +#define PF1(x) " prefetchnta "PF_OFFS(x)"(%2) ;\n" +#define PF2(x) " prefetchnta "PF_OFFS(x)"(%3) ;\n" +#define PF3(x) " prefetchnta "PF_OFFS(x)"(%4) ;\n" +#define PF4(x) " prefetchnta "PF_OFFS(x)"(%5) ;\n" +#define PF5(x) " prefetchnta "PF_OFFS(x)"(%6) ;\n" +#define XO1(x,y) " xorps "OFFS(x)"(%2), %%xmm"#y" ;\n" +#define XO2(x,y) " xorps "OFFS(x)"(%3), %%xmm"#y" ;\n" +#define XO3(x,y) " xorps "OFFS(x)"(%4), %%xmm"#y" ;\n" +#define XO4(x,y) " xorps "OFFS(x)"(%5), %%xmm"#y" ;\n" +#define XO5(x,y) " xorps "OFFS(x)"(%6), %%xmm"#y" ;\n" + + +static void +xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) +{ + unsigned long lines = bytes >> 8; + char xmm_save[16*4] ALIGN16; + int cr0; + + XMMS_SAVE; + + __asm__ __volatile__ ( +#undef BLOCK +#define BLOCK(i) \ + LD(i,0) \ + LD(i+1,1) \ + PF1(i) \ + PF1(i+2) \ + LD(i+2,2) \ + LD(i+3,3) \ + PF0(i+4) \ + PF0(i+6) \ + XO1(i,0) \ + XO1(i+1,1) \ + XO1(i+2,2) \ + XO1(i+3,3) \ + ST(i,0) \ + ST(i+1,1) \ + ST(i+2,2) \ + ST(i+3,3) \ + + + PF0(0) + PF0(2) + + " .align 32 ;\n" + " 1: ;\n" + + BLOCK(0) + BLOCK(4) + BLOCK(8) + BLOCK(12) + + " addl $256, %1 ;\n" + " addl $256, %2 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r" (p2) + : + : "memory"); + + XMMS_RESTORE; +} + +static void +xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3) +{ + unsigned long lines = bytes >> 8; + char xmm_save[16*4] ALIGN16; + int cr0; + + XMMS_SAVE; + + __asm__ __volatile__ ( +#undef BLOCK +#define BLOCK(i) \ + PF1(i) \ + PF1(i+2) \ + LD(i,0) \ + LD(i+1,1) \ + LD(i+2,2) \ + LD(i+3,3) \ + PF2(i) \ + PF2(i+2) \ + PF0(i+4) \ + PF0(i+6) \ + XO1(i,0) \ + XO1(i+1,1) \ + XO1(i+2,2) \ + XO1(i+3,3) \ + XO2(i,0) \ + XO2(i+1,1) \ + XO2(i+2,2) \ + XO2(i+3,3) \ + ST(i,0) \ + ST(i+1,1) \ + ST(i+2,2) \ + ST(i+3,3) \ + + + PF0(0) + PF0(2) + + " .align 32 ;\n" + " 1: ;\n" + + BLOCK(0) + BLOCK(4) + BLOCK(8) + BLOCK(12) + + " addl $256, %1 ;\n" + " addl $256, %2 ;\n" + " addl $256, %3 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r"(p2), "+r"(p3) + : + : "memory" ); + + XMMS_RESTORE; +} + +static void +xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4) +{ + unsigned long lines = bytes >> 8; + char xmm_save[16*4] ALIGN16; + int cr0; + + XMMS_SAVE; + + __asm__ __volatile__ ( +#undef BLOCK +#define BLOCK(i) \ + PF1(i) \ + PF1(i+2) \ + LD(i,0) \ + LD(i+1,1) \ + LD(i+2,2) \ + LD(i+3,3) \ + PF2(i) \ + PF2(i+2) \ + XO1(i,0) \ + XO1(i+1,1) \ + XO1(i+2,2) \ + XO1(i+3,3) \ + PF3(i) \ + PF3(i+2) \ + PF0(i+4) \ + PF0(i+6) \ + XO2(i,0) \ + XO2(i+1,1) \ + XO2(i+2,2) \ + XO2(i+3,3) \ + XO3(i,0) \ + XO3(i+1,1) \ + XO3(i+2,2) \ + XO3(i+3,3) \ + ST(i,0) \ + ST(i+1,1) \ + ST(i+2,2) \ + ST(i+3,3) \ + + + PF0(0) + PF0(2) + + " .align 32 ;\n" + " 1: ;\n" + + BLOCK(0) + BLOCK(4) + BLOCK(8) + BLOCK(12) + + " addl $256, %1 ;\n" + " addl $256, %2 ;\n" + " addl $256, %3 ;\n" + " addl $256, %4 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + : "+r" (lines), + "+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4) + : + : "memory" ); + + XMMS_RESTORE; +} + +static void +xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4, unsigned long *p5) +{ + unsigned long lines = bytes >> 8; + char xmm_save[16*4] ALIGN16; + int cr0; + + XMMS_SAVE; + + /* need to save p4/p5 manually to not exceed gcc's 10 argument limit */ + __asm__ __volatile__ ( + " pushl %4\n" + " pushl %5\n" +#undef BLOCK +#define BLOCK(i) \ + PF1(i) \ + PF1(i+2) \ + LD(i,0) \ + LD(i+1,1) \ + LD(i+2,2) \ + LD(i+3,3) \ + PF2(i) \ + PF2(i+2) \ + XO1(i,0) \ + XO1(i+1,1) \ + XO1(i+2,2) \ + XO1(i+3,3) \ + PF3(i) \ + PF3(i+2) \ + XO2(i,0) \ + XO2(i+1,1) \ + XO2(i+2,2) \ + XO2(i+3,3) \ + PF4(i) \ + PF4(i+2) \ + PF0(i+4) \ + PF0(i+6) \ + XO3(i,0) \ + XO3(i+1,1) \ + XO3(i+2,2) \ + XO3(i+3,3) \ + XO4(i,0) \ + XO4(i+1,1) \ + XO4(i+2,2) \ + XO4(i+3,3) \ + ST(i,0) \ + ST(i+1,1) \ + ST(i+2,2) \ + ST(i+3,3) \ + + + PF0(0) + PF0(2) + + " .align 32 ;\n" + " 1: ;\n" + + BLOCK(0) + BLOCK(4) + BLOCK(8) + BLOCK(12) + + " addl $256, %1 ;\n" + " addl $256, %2 ;\n" + " addl $256, %3 ;\n" + " addl $256, %4 ;\n" + " addl $256, %5 ;\n" + " decl %0 ;\n" + " jnz 1b ;\n" + " popl %5\n" + " popl %4\n" + : "+r" (lines), + "+r" (p1), "+r" (p2), "+r" (p3) + : "r" (p4), "r" (p5) + : "memory"); + + XMMS_RESTORE; +} + +static struct xor_block_template xor_block_pIII_sse = { + name: "pIII_sse", + do_2: xor_sse_2, + do_3: xor_sse_3, + do_4: xor_sse_4, + do_5: xor_sse_5, +}; + +/* Also try the generic routines. */ +#include + +#undef XOR_TRY_TEMPLATES +#define XOR_TRY_TEMPLATES \ + do { \ + xor_speed(&xor_block_8regs); \ + xor_speed(&xor_block_32regs); \ + if (cpu_has_xmm) \ + xor_speed(&xor_block_pIII_sse); \ + if (md_cpu_has_mmx()) { \ + xor_speed(&xor_block_pII_mmx); \ + xor_speed(&xor_block_p5_mmx); \ + } \ + } while (0) + +/* We force the use of the SSE xor block because it can write around L2. + We may also be able to load into the L1 only depending on how the cpu + deals with a load to a line that is being prefetched. */ +#define XOR_SELECT_TEMPLATE(FASTEST) \ + (cpu_has_xmm ? &xor_block_pIII_sse : FASTEST) diff -ruN linux-2.4.23-pre6/include/asm-generic/bitops.h linux-2.4.23-pre6-swsusp/include/asm-generic/bitops.h --- linux-2.4.23-pre6/include/asm-generic/bitops.h 2000-11-28 10:47:38.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm-generic/bitops.h 2003-10-05 03:42:25.000000000 +0900 @@ -51,6 +51,12 @@ return ((mask & *addr) != 0); } +/* + * fls: find last bit set. + */ + +#define fls(x) generic_fls(x) + #ifdef __KERNEL__ /* diff -ruN linux-2.4.23-pre6/include/asm-i386/bitops.h linux-2.4.23-pre6-swsusp/include/asm-i386/bitops.h --- linux-2.4.23-pre6/include/asm-i386/bitops.h 2003-08-25 20:44:43.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm-i386/bitops.h 2003-10-05 03:42:25.000000000 +0900 @@ -330,6 +330,12 @@ return word; } +/* + * fls: find last bit set. + */ + +#define fls(x) generic_fls(x) + #ifdef __KERNEL__ /** diff -ruN linux-2.4.23-pre6/include/asm-i386/cpufeature.h linux-2.4.23-pre6-swsusp/include/asm-i386/cpufeature.h --- linux-2.4.23-pre6/include/asm-i386/cpufeature.h 2003-10-05 04:16:40.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm-i386/cpufeature.h 2003-10-05 03:45:24.000000000 +0900 @@ -84,6 +84,7 @@ #define cpu_has_vme boot_cpu_has(X86_FEATURE_VME) #define cpu_has_de boot_cpu_has(X86_FEATURE_DE) #define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE) +#define cpu_has_pse36 boot_cpu_has(X86_FEATURE_PSE36) #define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC) #define cpu_has_pae boot_cpu_has(X86_FEATURE_PAE) #define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE) diff -ruN linux-2.4.23-pre6/include/asm-i386/mtrr.h linux-2.4.23-pre6-swsusp/include/asm-i386/mtrr.h --- linux-2.4.23-pre6/include/asm-i386/mtrr.h 2001-11-23 04:46:37.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm-i386/mtrr.h 2003-10-05 03:42:25.000000000 +0900 @@ -89,6 +89,10 @@ extern int mtrr_del (int reg, unsigned long base, unsigned long size); extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); +# ifdef CONFIG_SOFTWARE_SUSPEND +extern int *mtrr_suspend(void); +extern int mtrr_resume(int *ptr); +# endif # else static __inline__ int mtrr_add (unsigned long base, unsigned long size, unsigned int type, char increment) diff -ruN linux-2.4.23-pre6/include/asm-i386/suspend.h linux-2.4.23-pre6-swsusp/include/asm-i386/suspend.h --- linux-2.4.23-pre6/include/asm-i386/suspend.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/asm-i386/suspend.h 2003-10-05 03:42:25.000000000 +0900 @@ -0,0 +1,352 @@ + /* + * Copyright 2001-2002 Pavel Machek + * Based on code + * Copyright 2001 Patrick Mochel + */ +#include +#include +#ifdef SUSPEND_C +#include +#endif +/* image of the saved processor state */ +struct saved_context { + u32 eax, ebx, ecx, edx; + u32 esp, ebp, esi, edi; + u16 es, fs, gs, ss; + u32 cr0, cr2, cr3, cr4; + u16 gdt_pad; + u16 gdt_limit; + u32 gdt_base; + u16 idt_pad; + u16 idt_limit; + u32 idt_base; + u16 ldt; + u16 tss; + u32 tr; + u32 safety; + u32 return_address; + u32 eflags; +} __attribute__((packed)); + +struct saved_context saved_context; + +#define loaddebug(thread,register) \ + __asm__("movl %0,%%db" #register \ + : /* no output */ \ + :"r" ((thread)->debugreg[register])) + + +/* + * save_processor_context + * + * Save the state of the processor before we go to sleep. + * + * return_stack is the value of the stack pointer (%esp) as the caller sees it. + * A good way could not be found to obtain it from here (don't want to make _too_ + * many assumptions about the layout of the stack this far down.) Also, the + * handy little __builtin_frame_pointer(level) where level > 0, is blatantly + * buggy - it returns the value of the stack at the proper location, not the + * location, like it should (as of gcc 2.91.66) + * + * Note that the context and timing of this function is pretty critical. + * With a minimal amount of things going on in the caller and in here, gcc + * does a good job of being just a dumb compiler. Watch the assembly output + * if anything changes, though, and make sure everything is going in the right + * place. + */ +static inline void save_processor_context (void) +{ + kernel_fpu_begin(); + + /* + * descriptor tables + */ + asm volatile ("sgdt (%0)" : "=m" (saved_context.gdt_limit)); + asm volatile ("sidt (%0)" : "=m" (saved_context.idt_limit)); + asm volatile ("sldt (%0)" : "=m" (saved_context.ldt)); + asm volatile ("str (%0)" : "=m" (saved_context.tr)); + + /* + * save the general registers. + * note that gcc has constructs to specify output of certain registers, + * but they're not used here, because it assumes that you want to modify + * those registers, so it tries to be smart and save them beforehand. + * It's really not necessary, and kinda fishy (check the assembly output), + * so it's avoided. + */ + asm volatile ("movl %%esp, (%0)" : "=m" (saved_context.esp)); + asm volatile ("movl %%eax, (%0)" : "=m" (saved_context.eax)); + asm volatile ("movl %%ebx, (%0)" : "=m" (saved_context.ebx)); + asm volatile ("movl %%ecx, (%0)" : "=m" (saved_context.ecx)); + asm volatile ("movl %%edx, (%0)" : "=m" (saved_context.edx)); + asm volatile ("movl %%ebp, (%0)" : "=m" (saved_context.ebp)); + asm volatile ("movl %%esi, (%0)" : "=m" (saved_context.esi)); + asm volatile ("movl %%edi, (%0)" : "=m" (saved_context.edi)); + + /* + * segment registers + */ + asm volatile ("movw %%es, %0" : "=r" (saved_context.es)); + asm volatile ("movw %%fs, %0" : "=r" (saved_context.fs)); + asm volatile ("movw %%gs, %0" : "=r" (saved_context.gs)); + asm volatile ("movw %%ss, %0" : "=r" (saved_context.ss)); + + /* + * control registers + */ + asm volatile ("movl %%cr0, %0" : "=r" (saved_context.cr0)); + asm volatile ("movl %%cr2, %0" : "=r" (saved_context.cr2)); + asm volatile ("movl %%cr3, %0" : "=r" (saved_context.cr3)); + asm volatile ("movl %%cr4, %0" : "=r" (saved_context.cr4)); + + /* + * eflags + */ + asm volatile ("pushfl ; popl (%0)" : "=m" (saved_context.eflags)); +} + +void fix_processor_context(void) +{ + int nr = smp_processor_id(); + struct tss_struct * t = &init_tss[nr]; + + set_tss_desc(nr,t); /* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy tsc or some similar stupidity. */ + gdt_table[__TSS(nr)].b &= 0xfffffdff; + + load_TR(nr); /* This does ltr */ + + load_LDT(current->active_mm); /* This does lldt */ + + /* + * Now maybe reload the debug registers + */ + if (current->thread.debugreg[7]){ + loaddebug(¤t->thread, 0); + loaddebug(¤t->thread, 1); + loaddebug(¤t->thread, 2); + loaddebug(¤t->thread, 3); + /* no 4 and 5 */ + loaddebug(¤t->thread, 6); + loaddebug(¤t->thread, 7); + } + +} + +void +do_fpu_end(void) +{ + /* restore FPU regs if necessary */ + /* Do it out of line so that gcc does not move cr0 load to some stupid place */ + kernel_fpu_end(); +} + +/* + * restore_processor_context + * + * Restore the processor context as it was before we went to sleep + * - descriptor tables + * - control registers + * - segment registers + * - flags + * + * Note that it is critical that this function is declared inline. + * It was separated out from restore_state to make that function + * a little clearer, but it needs to be inlined because we won't have a + * stack when we get here (so we can't push a return address). + */ +inline void restore_processor_context (void) +{ + /* + * first restore %ds, so we can access our data properly + */ + asm volatile (".align 4"); + asm volatile ("movw %0, %%ds" :: "r" ((u16)__KERNEL_DS)); + + + /* + * control registers + */ + asm volatile ("movl %0, %%cr4" :: "r" (saved_context.cr4)); + asm volatile ("movl %0, %%cr3" :: "r" (saved_context.cr3)); + asm volatile ("movl %0, %%cr2" :: "r" (saved_context.cr2)); + asm volatile ("movl %0, %%cr0" :: "r" (saved_context.cr0)); + + /* + * segment registers + */ + asm volatile ("movw %0, %%es" :: "r" (saved_context.es)); + asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs)); + asm volatile ("movw %0, %%gs" :: "r" (saved_context.gs)); + asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss)); + + /* + * the other general registers + * + * note that even though gcc has constructs to specify memory + * input into certain registers, it will try to be too smart + * and save them at the beginning of the function. This is esp. + * bad since we don't have a stack set up when we enter, and we + * want to preserve the values on exit. So, we set them manually. + */ + asm volatile ("movl %0, %%esp" :: "m" (saved_context.esp)); + asm volatile ("movl %0, %%ebp" :: "m" (saved_context.ebp)); + asm volatile ("movl %0, %%eax" :: "m" (saved_context.eax)); + asm volatile ("movl %0, %%ebx" :: "m" (saved_context.ebx)); + asm volatile ("movl %0, %%ecx" :: "m" (saved_context.ecx)); + asm volatile ("movl %0, %%edx" :: "m" (saved_context.edx)); + asm volatile ("movl %0, %%esi" :: "m" (saved_context.esi)); + asm volatile ("movl %0, %%edi" :: "m" (saved_context.edi)); + + /* + * now restore the descriptor tables to their proper values + * ltr is done i fix_processor_context(). + */ + asm volatile ("lgdt (%0)" :: "m" (saved_context.gdt_limit)); + asm volatile ("lidt (%0)" :: "m" (saved_context.idt_limit)); + asm volatile ("lldt (%0)" :: "m" (saved_context.ldt)); + + fix_processor_context(); + + /* + * the flags + */ + asm volatile ("pushl %0 ; popfl" :: "m" (saved_context.eflags)); + + do_fpu_end(); +} + +#ifdef SUSPEND_C +/* Local variables for do_magic */ +volatile static int loop __nosavedata = 0; +volatile static int state1 __nosavedata = 0; +volatile static int state2 __nosavedata = 0; +volatile static int state3 __nosavedata = 0; +volatile static struct range *origrange __nosavedata; +volatile static struct range *copyrange __nosavedata; +volatile static int origoffset __nosavedata; +volatile static int copyoffset __nosavedata; +volatile static unsigned long * origpage __nosavedata; +volatile static unsigned long * copypage __nosavedata; +volatile static int orig_min_free __nosavedata; +#ifndef CONFIG_SMP +static unsigned long c_loops_per_jiffy_ref __nosavedata = 0; +static unsigned long cpu_khz_ref __nosavedata = 0; +#endif + +/* + * FIXME: This function should really be written in assembly. Actually + * requirement is that it does not touch stack, because %esp will be + * wrong during resume before restore_processor_context(). Check + * assembly if you modify this. + */ +static void do_suspend_lowlevel(int resume) +{ + if (!resume) { + do_magic_suspend_1(); + PRINTPREEMPTCOUNT("Before save_processor_context."); + save_processor_context(); /* We need to capture registers and memory at "same time" */ + PRINTPREEMPTCOUNT("After save_processor_context."); + do_magic_suspend_2(); /* If everything goes okay, this function does not return */ + return; + } + + /* We want to run from swapper_pg_dir, since swapper_pg_dir is stored in constant + * place in memory + */ + + __asm__( "movl %%ecx,%%cr3\n" ::"c"(__pa(swapper_pg_dir))); + +/* + * Final function for resuming: after copying the pages to their original + * position, it restores the register state. + * + * What about page tables? Writing data pages may toggle + * accessed/dirty bits in our page tables. That should be no problems + * with 4MB page tables. That's why we require have_pse. + * + * This loops destroys stack from under itself, so it better should + * not use any stack space, itself. When this function is entered at + * resume time, we move stack to _old_ place. This is means that this + * function must use no stack and no local variables in registers, + * until calling restore_processor_context(); + * + * Critical section here: noone should touch saved memory after + * do_magic_resume_1; copying works, because nr_copy_pages, + * pagedir_nosave, loop and loop2 are nosavedata. + */ + + do_magic_resume_1(); + +#ifdef CONFIG_PREEMPT + /* + * Preempt disabled in kernel we're about to restore. + * Make sure we match state now. + */ + preempt_disable(); + PRINTPREEMPTCOUNT("Prior to copying old kernel back."); +#endif + + state1 = swsusp_action; + state2 = swsusp_debug_state; + state3 = console_loglevel; + +#ifndef CONFIG_SMP + c_loops_per_jiffy_ref = cpu_data->loops_per_jiffy; + cpu_khz_ref = cpu_khz; +#endif + + origrange = pagedir_nosave.origranges.first; + copyrange = pagedir_nosave.destranges.first; + origoffset = origrange->minimum; + copyoffset = copyrange->minimum; + origpage = (unsigned long *) (page_address(mem_map + origoffset)); + copypage = (unsigned long *) (page_address(mem_map + copyoffset)); + orig_min_free = swsusp_min_free; + + while (origrange) { + for (loop=0; loop < (PAGE_SIZE / sizeof(unsigned long)); loop++) { + *(origpage + loop) = *(copypage + loop); + __flush_tlb(); + } + + if (origoffset < origrange->maximum) { + origoffset++; + origpage += (PAGE_SIZE / sizeof(unsigned long)); + } else { + origrange = origrange->next; + if (origrange) { + origoffset = origrange->minimum; + origpage = (unsigned long *) (page_address(mem_map + origoffset)); + } + } + + if (copyoffset < copyrange->maximum) { + copyoffset++; + copypage += (PAGE_SIZE / sizeof(unsigned long)); + } else { + copyrange = copyrange->next; + if (copyrange) { + copyoffset = copyrange->minimum; + copypage = (unsigned long *) (page_address(mem_map + copyoffset)); + } + } + } + + restore_processor_context(); + +/* Ahah, we now run with our old stack, and with registers copied from + suspend time */ + +#ifndef CONFIG_SMP + cpu_data->loops_per_jiffy = c_loops_per_jiffy_ref; + loops_per_jiffy = c_loops_per_jiffy_ref; + cpu_khz = cpu_khz_ref; +#endif + swsusp_action = state1; + swsusp_debug_state = state2; + console_loglevel = state3; + swsusp_min_free = orig_min_free; + + do_magic_resume_2(); +} +#endif diff -ruN linux-2.4.23-pre6/include/linux/autoconf.h linux-2.4.23-pre6-swsusp/include/linux/autoconf.h --- linux-2.4.23-pre6/include/linux/autoconf.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/autoconf.h 2003-10-05 04:11:09.000000000 +0900 @@ -0,0 +1,1300 @@ +/* + * Automatically generated C config: don't edit + */ +#define AUTOCONF_INCLUDED +#define CONFIG_X86 1 +#undef CONFIG_SBUS +#define CONFIG_UID16 1 + +/* + * Code maturity level options + */ +#define CONFIG_EXPERIMENTAL 1 + +/* + * Loadable module support + */ +#define CONFIG_MODULES 1 +#define CONFIG_MODVERSIONS 1 +#define CONFIG_KMOD 1 + +/* + * Processor type and features + */ +#undef CONFIG_M386 +#undef CONFIG_M486 +#undef CONFIG_M586 +#undef CONFIG_M586TSC +#undef CONFIG_M586MMX +#undef CONFIG_M686 +#undef CONFIG_MPENTIUMIII +#undef CONFIG_MPENTIUM4 +#undef CONFIG_MK6 +#undef CONFIG_MK7 +#undef CONFIG_MK8 +#undef CONFIG_MELAN +#define CONFIG_MCRUSOE 1 +#undef CONFIG_MWINCHIPC6 +#undef CONFIG_MWINCHIP2 +#undef CONFIG_MWINCHIP3D +#undef CONFIG_MCYRIXIII +#undef CONFIG_MVIAC3_2 +#define CONFIG_X86_WP_WORKS_OK 1 +#define CONFIG_X86_INVLPG 1 +#define CONFIG_X86_CMPXCHG 1 +#define CONFIG_X86_XADD 1 +#define CONFIG_X86_BSWAP 1 +#define CONFIG_X86_POPAD_OK 1 +#undef CONFIG_RWSEM_GENERIC_SPINLOCK +#define CONFIG_RWSEM_XCHGADD_ALGORITHM 1 +#define CONFIG_X86_L1_CACHE_SHIFT (5) +#define CONFIG_X86_HAS_TSC 1 +#define CONFIG_X86_F00F_WORKS_OK 1 +#define CONFIG_X86_MCE 1 +#undef CONFIG_TOSHIBA +#define CONFIG_TOSHIBA_MODULE 1 +#undef CONFIG_I8K +#undef CONFIG_MICROCODE +#define CONFIG_MICROCODE_MODULE 1 +#undef CONFIG_X86_MSR +#define CONFIG_X86_MSR_MODULE 1 +#undef CONFIG_X86_CPUID +#define CONFIG_X86_CPUID_MODULE 1 +#define CONFIG_NOHIGHMEM 1 +#undef CONFIG_HIGHMEM4G +#undef CONFIG_HIGHMEM64G +#undef CONFIG_HIGHMEM +#undef CONFIG_MATH_EMULATION +#undef CONFIG_MTRR +#undef CONFIG_SMP +#undef CONFIG_X86_UP_APIC +#undef CONFIG_X86_UP_IOAPIC +#undef CONFIG_X86_TSC_DISABLE +#define CONFIG_X86_TSC 1 + +/* + * General setup + */ +#define CONFIG_NET 1 +#define CONFIG_PCI 1 +#undef CONFIG_PCI_GOBIOS +#undef CONFIG_PCI_GODIRECT +#define CONFIG_PCI_GOANY 1 +#define CONFIG_PCI_BIOS 1 +#define CONFIG_PCI_DIRECT 1 +#define CONFIG_ISA 1 +#define CONFIG_PCI_NAMES 1 +#undef CONFIG_EISA +#undef CONFIG_MCA +#define CONFIG_HOTPLUG 1 + +/* + * PCMCIA/CardBus support + */ +#undef CONFIG_PCMCIA +#define CONFIG_PCMCIA_MODULE 1 +#define CONFIG_CARDBUS 1 +#undef CONFIG_TCIC +#undef CONFIG_I82092 +#undef CONFIG_I82365 + +/* + * PCI Hotplug Support + */ +#undef CONFIG_HOTPLUG_PCI +#undef CONFIG_HOTPLUG_PCI_COMPAQ +#undef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM +#undef CONFIG_HOTPLUG_PCI_ACPI +#define CONFIG_SYSVIPC 1 +#define CONFIG_BSD_PROCESS_ACCT 1 +#define CONFIG_SYSCTL 1 +#define CONFIG_KCORE_ELF 1 +#undef CONFIG_KCORE_AOUT +#undef CONFIG_BINFMT_AOUT +#define CONFIG_BINFMT_AOUT_MODULE 1 +#define CONFIG_BINFMT_ELF 1 +#undef CONFIG_BINFMT_MISC +#define CONFIG_BINFMT_MISC_MODULE 1 +#define CONFIG_PM 1 +#define CONFIG_SOFTWARE_SUSPEND 1 +#undef CONFIG_SOFTWARE_SUSPEND_DEBUG +#undef CONFIG_SOFTWARE_SUSPEND_COMPRESSION +#undef CONFIG_SOFTWARE_SUSPEND_KEEP_IMAGE +#undef CONFIG_SOFTWARE_SUSPEND_RELAXED_PROC +#undef CONFIG_APM + +/* + * ACPI Support + */ +#define CONFIG_ACPI 1 +#define CONFIG_ACPI_BOOT 1 +#define CONFIG_ACPI_BUS 1 +#define CONFIG_ACPI_INTERPRETER 1 +#define CONFIG_ACPI_EC 1 +#define CONFIG_ACPI_POWER 1 +#define CONFIG_ACPI_PCI 1 +#define CONFIG_ACPI_SLEEP 1 +#define CONFIG_ACPI_SYSTEM 1 +#define CONFIG_ACPI_AC 1 +#define CONFIG_ACPI_BATTERY 1 +#define CONFIG_ACPI_BUTTON 1 +#define CONFIG_ACPI_FAN 1 +#define CONFIG_ACPI_PROCESSOR 1 +#define CONFIG_ACPI_THERMAL 1 +#define CONFIG_ACPI_ASUS 1 +#define CONFIG_ACPI_TOSHIBA 1 +#undef CONFIG_ACPI_DEBUG +#undef CONFIG_ACPI_RELAXED_AML + +/* + * Memory Technology Devices (MTD) + */ +#undef CONFIG_MTD + +/* + * Parallel port support + */ +#undef CONFIG_PARPORT + +/* + * Plug and Play configuration + */ +#define CONFIG_PNP 1 +#define CONFIG_ISAPNP 1 + +/* + * Block devices + */ +#undef CONFIG_BLK_DEV_FD +#undef CONFIG_BLK_DEV_XD +#undef CONFIG_PARIDE +#undef CONFIG_BLK_CPQ_DA +#undef CONFIG_BLK_CPQ_CISS_DA +#undef CONFIG_CISS_SCSI_TAPE +#undef CONFIG_CISS_MONITOR_THREAD +#undef CONFIG_BLK_DEV_DAC960 +#undef CONFIG_BLK_DEV_UMEM +#undef CONFIG_BLK_DEV_LOOP +#define CONFIG_BLK_DEV_LOOP_MODULE 1 +#undef CONFIG_BLK_DEV_NBD +#define CONFIG_BLK_DEV_NBD_MODULE 1 +#define CONFIG_BLK_DEV_RAM 1 +#define CONFIG_BLK_DEV_RAM_SIZE (4096) +#define CONFIG_BLK_DEV_INITRD 1 +#define CONFIG_BLK_STATS 1 + +/* + * Multi-device support (RAID and LVM) + */ +#undef CONFIG_MD +#undef CONFIG_BLK_DEV_MD +#undef CONFIG_MD_LINEAR +#undef CONFIG_MD_RAID0 +#undef CONFIG_MD_RAID1 +#undef CONFIG_MD_RAID5 +#undef CONFIG_MD_MULTIPATH +#undef CONFIG_BLK_DEV_LVM + +/* + * Networking options + */ +#define CONFIG_PACKET 1 +#define CONFIG_PACKET_MMAP 1 +#undef CONFIG_NETLINK_DEV +#define CONFIG_NETFILTER 1 +#undef CONFIG_NETFILTER_DEBUG +#define CONFIG_FILTER 1 +#define CONFIG_UNIX 1 +#define CONFIG_INET 1 +#define CONFIG_IP_MULTICAST 1 +#undef CONFIG_IP_ADVANCED_ROUTER +#undef CONFIG_IP_PNP +#undef CONFIG_NET_IPIP +#undef CONFIG_NET_IPGRE +#undef CONFIG_IP_MROUTE +#undef CONFIG_ARPD +#undef CONFIG_INET_ECN +#define CONFIG_SYN_COOKIES 1 + +/* + * IP: Netfilter Configuration + */ +#undef CONFIG_IP_NF_CONNTRACK +#undef CONFIG_IP_NF_QUEUE +#undef CONFIG_IP_NF_IPTABLES +#define CONFIG_IP_NF_IPTABLES_MODULE 1 +#undef CONFIG_IP_NF_MATCH_LIMIT +#define CONFIG_IP_NF_MATCH_LIMIT_MODULE 1 +#undef CONFIG_IP_NF_MATCH_MAC +#define CONFIG_IP_NF_MATCH_MAC_MODULE 1 +#undef CONFIG_IP_NF_MATCH_PKTTYPE +#define CONFIG_IP_NF_MATCH_PKTTYPE_MODULE 1 +#undef CONFIG_IP_NF_MATCH_MARK +#define CONFIG_IP_NF_MATCH_MARK_MODULE 1 +#undef CONFIG_IP_NF_MATCH_MULTIPORT +#define CONFIG_IP_NF_MATCH_MULTIPORT_MODULE 1 +#undef CONFIG_IP_NF_MATCH_TOS +#define CONFIG_IP_NF_MATCH_TOS_MODULE 1 +#undef CONFIG_IP_NF_MATCH_RECENT +#define CONFIG_IP_NF_MATCH_RECENT_MODULE 1 +#undef CONFIG_IP_NF_MATCH_ECN +#define CONFIG_IP_NF_MATCH_ECN_MODULE 1 +#undef CONFIG_IP_NF_MATCH_DSCP +#define CONFIG_IP_NF_MATCH_DSCP_MODULE 1 +#undef CONFIG_IP_NF_MATCH_AH_ESP +#define CONFIG_IP_NF_MATCH_AH_ESP_MODULE 1 +#undef CONFIG_IP_NF_MATCH_LENGTH +#define CONFIG_IP_NF_MATCH_LENGTH_MODULE 1 +#undef CONFIG_IP_NF_MATCH_TTL +#define CONFIG_IP_NF_MATCH_TTL_MODULE 1 +#undef CONFIG_IP_NF_MATCH_TCPMSS +#define CONFIG_IP_NF_MATCH_TCPMSS_MODULE 1 +#undef CONFIG_IP_NF_MATCH_UNCLEAN +#define CONFIG_IP_NF_MATCH_UNCLEAN_MODULE 1 +#undef CONFIG_IP_NF_MATCH_OWNER +#define CONFIG_IP_NF_MATCH_OWNER_MODULE 1 +#undef CONFIG_IP_NF_FILTER +#define CONFIG_IP_NF_FILTER_MODULE 1 +#undef CONFIG_IP_NF_TARGET_REJECT +#define CONFIG_IP_NF_TARGET_REJECT_MODULE 1 +#undef CONFIG_IP_NF_TARGET_MIRROR +#define CONFIG_IP_NF_TARGET_MIRROR_MODULE 1 +#undef CONFIG_IP_NF_MANGLE +#define CONFIG_IP_NF_MANGLE_MODULE 1 +#undef CONFIG_IP_NF_TARGET_TOS +#define CONFIG_IP_NF_TARGET_TOS_MODULE 1 +#undef CONFIG_IP_NF_TARGET_ECN +#define CONFIG_IP_NF_TARGET_ECN_MODULE 1 +#undef CONFIG_IP_NF_TARGET_DSCP +#define CONFIG_IP_NF_TARGET_DSCP_MODULE 1 +#undef CONFIG_IP_NF_TARGET_MARK +#define CONFIG_IP_NF_TARGET_MARK_MODULE 1 +#undef CONFIG_IP_NF_TARGET_LOG +#define CONFIG_IP_NF_TARGET_LOG_MODULE 1 +#undef CONFIG_IP_NF_TARGET_ULOG +#define CONFIG_IP_NF_TARGET_ULOG_MODULE 1 +#undef CONFIG_IP_NF_TARGET_TCPMSS +#define CONFIG_IP_NF_TARGET_TCPMSS_MODULE 1 +#undef CONFIG_IP_NF_ARPTABLES +#define CONFIG_IP_NF_ARPTABLES_MODULE 1 +#undef CONFIG_IP_NF_ARPFILTER +#define CONFIG_IP_NF_ARPFILTER_MODULE 1 +#undef CONFIG_IP_NF_ARP_MANGLE +#define CONFIG_IP_NF_ARP_MANGLE_MODULE 1 +#undef CONFIG_IP_NF_COMPAT_IPCHAINS +#undef CONFIG_IP_NF_COMPAT_IPFWADM + +/* + * IP: Virtual Server Configuration + */ +#undef CONFIG_IP_VS +#undef CONFIG_IPV6 +#undef CONFIG_KHTTPD + +/* + * SCTP Configuration (EXPERIMENTAL) + */ +#define CONFIG_IPV6_SCTP__ 1 +#undef CONFIG_IP_SCTP +#undef CONFIG_ATM +#undef CONFIG_VLAN_8021Q + +/* + * + */ +#undef CONFIG_IPX +#undef CONFIG_ATALK + +/* + * Appletalk devices + */ +#undef CONFIG_DEV_APPLETALK +#undef CONFIG_DECNET +#undef CONFIG_BRIDGE +#undef CONFIG_X25 +#undef CONFIG_LAPB +#undef CONFIG_LLC +#undef CONFIG_NET_DIVERT +#undef CONFIG_ECONET +#undef CONFIG_WAN_ROUTER +#undef CONFIG_NET_FASTROUTE +#undef CONFIG_NET_HW_FLOWCONTROL + +/* + * QoS and/or fair queueing + */ +#define CONFIG_NET_SCHED 1 +#undef CONFIG_NET_SCH_CBQ +#define CONFIG_NET_SCH_CBQ_MODULE 1 +#undef CONFIG_NET_SCH_HTB +#define CONFIG_NET_SCH_HTB_MODULE 1 +#undef CONFIG_NET_SCH_CSZ +#define CONFIG_NET_SCH_CSZ_MODULE 1 +#undef CONFIG_NET_SCH_PRIO +#define CONFIG_NET_SCH_PRIO_MODULE 1 +#undef CONFIG_NET_SCH_RED +#define CONFIG_NET_SCH_RED_MODULE 1 +#undef CONFIG_NET_SCH_SFQ +#define CONFIG_NET_SCH_SFQ_MODULE 1 +#undef CONFIG_NET_SCH_TEQL +#define CONFIG_NET_SCH_TEQL_MODULE 1 +#undef CONFIG_NET_SCH_TBF +#define CONFIG_NET_SCH_TBF_MODULE 1 +#undef CONFIG_NET_SCH_GRED +#define CONFIG_NET_SCH_GRED_MODULE 1 +#undef CONFIG_NET_SCH_DSMARK +#define CONFIG_NET_SCH_DSMARK_MODULE 1 +#undef CONFIG_NET_SCH_INGRESS +#define CONFIG_NET_SCH_INGRESS_MODULE 1 +#define CONFIG_NET_QOS 1 +#define CONFIG_NET_ESTIMATOR 1 +#define CONFIG_NET_CLS 1 +#undef CONFIG_NET_CLS_TCINDEX +#define CONFIG_NET_CLS_TCINDEX_MODULE 1 +#undef CONFIG_NET_CLS_ROUTE4 +#define CONFIG_NET_CLS_ROUTE4_MODULE 1 +#define CONFIG_NET_CLS_ROUTE 1 +#undef CONFIG_NET_CLS_FW +#define CONFIG_NET_CLS_FW_MODULE 1 +#undef CONFIG_NET_CLS_U32 +#define CONFIG_NET_CLS_U32_MODULE 1 +#undef CONFIG_NET_CLS_RSVP +#define CONFIG_NET_CLS_RSVP_MODULE 1 +#undef CONFIG_NET_CLS_RSVP6 +#define CONFIG_NET_CLS_RSVP6_MODULE 1 +#define CONFIG_NET_CLS_POLICE 1 + +/* + * Network testing + */ +#undef CONFIG_NET_PKTGEN + +/* + * Telephony Support + */ +#undef CONFIG_PHONE +#undef CONFIG_PHONE_IXJ +#undef CONFIG_PHONE_IXJ_PCMCIA + +/* + * ATA/IDE/MFM/RLL support + */ +#define CONFIG_IDE 1 + +/* + * IDE, ATA and ATAPI Block devices + */ +#define CONFIG_BLK_DEV_IDE 1 + +/* + * Please see Documentation/ide.txt for help/info on IDE drives + */ +#undef CONFIG_BLK_DEV_HD_IDE +#undef CONFIG_BLK_DEV_HD +#define CONFIG_BLK_DEV_IDEDISK 1 +#define CONFIG_IDEDISK_MULTI_MODE 1 +#undef CONFIG_IDEDISK_STROKE +#undef CONFIG_BLK_DEV_IDECS +#define CONFIG_BLK_DEV_IDECS_MODULE 1 +#undef CONFIG_BLK_DEV_IDECD +#define CONFIG_BLK_DEV_IDECD_MODULE 1 +#undef CONFIG_BLK_DEV_IDETAPE +#undef CONFIG_BLK_DEV_IDEFLOPPY +#undef CONFIG_BLK_DEV_IDESCSI +#define CONFIG_BLK_DEV_IDESCSI_MODULE 1 +#undef CONFIG_IDE_TASK_IOCTL + +/* + * IDE chipset support/bugfixes + */ +#undef CONFIG_BLK_DEV_CMD640 +#undef CONFIG_BLK_DEV_CMD640_ENHANCED +#undef CONFIG_BLK_DEV_ISAPNP +#define CONFIG_BLK_DEV_IDEPCI 1 +#define CONFIG_BLK_DEV_GENERIC 1 +#define CONFIG_IDEPCI_SHARE_IRQ 1 +#define CONFIG_BLK_DEV_IDEDMA_PCI 1 +#undef CONFIG_BLK_DEV_OFFBOARD +#undef CONFIG_BLK_DEV_IDEDMA_FORCED +#define CONFIG_IDEDMA_PCI_AUTO 1 +#undef CONFIG_IDEDMA_ONLYDISK +#define CONFIG_BLK_DEV_IDEDMA 1 +#undef CONFIG_IDEDMA_PCI_WIP +#undef CONFIG_BLK_DEV_ADMA100 +#undef CONFIG_BLK_DEV_AEC62XX +#define CONFIG_BLK_DEV_ALI15X3 1 +#undef CONFIG_WDC_ALI15X3 +#undef CONFIG_BLK_DEV_AMD74XX +#undef CONFIG_AMD74XX_OVERRIDE +#undef CONFIG_BLK_DEV_CMD64X +#undef CONFIG_BLK_DEV_TRIFLEX +#undef CONFIG_BLK_DEV_CY82C693 +#undef CONFIG_BLK_DEV_CS5530 +#undef CONFIG_BLK_DEV_HPT34X +#undef CONFIG_HPT34X_AUTODMA +#undef CONFIG_BLK_DEV_HPT366 +#undef CONFIG_BLK_DEV_PIIX +#undef CONFIG_BLK_DEV_NS87415 +#undef CONFIG_BLK_DEV_OPTI621 +#undef CONFIG_BLK_DEV_PDC202XX_OLD +#undef CONFIG_PDC202XX_BURST +#undef CONFIG_BLK_DEV_PDC202XX_NEW +#undef CONFIG_BLK_DEV_RZ1000 +#undef CONFIG_BLK_DEV_SC1200 +#undef CONFIG_BLK_DEV_SVWKS +#undef CONFIG_BLK_DEV_SIIMAGE +#undef CONFIG_BLK_DEV_SIS5513 +#undef CONFIG_BLK_DEV_SLC90E66 +#undef CONFIG_BLK_DEV_TRM290 +#undef CONFIG_BLK_DEV_VIA82CXXX +#undef CONFIG_IDE_CHIPSETS +#define CONFIG_IDEDMA_AUTO 1 +#undef CONFIG_IDEDMA_IVB +#undef CONFIG_DMA_NONPCI +#define CONFIG_BLK_DEV_IDE_MODES 1 +#undef CONFIG_BLK_DEV_ATARAID +#undef CONFIG_BLK_DEV_ATARAID_PDC +#undef CONFIG_BLK_DEV_ATARAID_HPT +#undef CONFIG_BLK_DEV_ATARAID_SII + +/* + * SCSI support + */ +#undef CONFIG_SCSI +#define CONFIG_SCSI_MODULE 1 + +/* + * SCSI support type (disk, tape, CD-ROM) + */ +#undef CONFIG_BLK_DEV_SD +#define CONFIG_BLK_DEV_SD_MODULE 1 +#define CONFIG_SD_EXTRA_DEVS (40) +#undef CONFIG_CHR_DEV_ST +#undef CONFIG_CHR_DEV_OSST +#undef CONFIG_BLK_DEV_SR +#define CONFIG_BLK_DEV_SR_MODULE 1 +#define CONFIG_BLK_DEV_SR_VENDOR 1 +#define CONFIG_SR_EXTRA_DEVS (4) +#undef CONFIG_CHR_DEV_SG +#define CONFIG_CHR_DEV_SG_MODULE 1 + +/* + * Some SCSI devices (e.g. CD jukebox) support multiple LUNs + */ +#undef CONFIG_SCSI_DEBUG_QUEUES +#undef CONFIG_SCSI_MULTI_LUN +#undef CONFIG_SCSI_CONSTANTS +#undef CONFIG_SCSI_LOGGING + +/* + * SCSI low-level drivers + */ +#undef CONFIG_BLK_DEV_3W_XXXX_RAID +#undef CONFIG_SCSI_7000FASST +#undef CONFIG_SCSI_ACARD +#undef CONFIG_SCSI_AHA152X +#undef CONFIG_SCSI_AHA1542 +#undef CONFIG_SCSI_AHA1740 +#undef CONFIG_SCSI_AACRAID +#undef CONFIG_SCSI_AIC7XXX +#undef CONFIG_SCSI_AIC79XX +#undef CONFIG_SCSI_AIC7XXX_OLD +#undef CONFIG_SCSI_DPT_I2O +#undef CONFIG_SCSI_ADVANSYS +#undef CONFIG_SCSI_IN2000 +#undef CONFIG_SCSI_AM53C974 +#undef CONFIG_SCSI_MEGARAID +#undef CONFIG_SCSI_BUSLOGIC +#undef CONFIG_SCSI_CPQFCTS +#undef CONFIG_SCSI_DMX3191D +#undef CONFIG_SCSI_DTC3280 +#undef CONFIG_SCSI_EATA +#undef CONFIG_SCSI_EATA_DMA +#undef CONFIG_SCSI_EATA_PIO +#undef CONFIG_SCSI_FUTURE_DOMAIN +#undef CONFIG_SCSI_GDTH +#undef CONFIG_SCSI_GENERIC_NCR5380 +#undef CONFIG_SCSI_IPS +#undef CONFIG_SCSI_INITIO +#undef CONFIG_SCSI_INIA100 +#undef CONFIG_SCSI_NCR53C406A +#undef CONFIG_SCSI_NCR53C7xx +#undef CONFIG_SCSI_SYM53C8XX_2 +#undef CONFIG_SCSI_NCR53C8XX +#undef CONFIG_SCSI_SYM53C8XX +#undef CONFIG_SCSI_PAS16 +#undef CONFIG_SCSI_PCI2000 +#undef CONFIG_SCSI_PCI2220I +#undef CONFIG_SCSI_PSI240I +#undef CONFIG_SCSI_QLOGIC_FAS +#undef CONFIG_SCSI_QLOGIC_ISP +#undef CONFIG_SCSI_QLOGIC_FC +#undef CONFIG_SCSI_QLOGIC_1280 +#undef CONFIG_SCSI_SEAGATE +#undef CONFIG_SCSI_SIM710 +#undef CONFIG_SCSI_SYM53C416 +#undef CONFIG_SCSI_DC390T +#undef CONFIG_SCSI_T128 +#undef CONFIG_SCSI_U14_34F +#undef CONFIG_SCSI_ULTRASTOR +#undef CONFIG_SCSI_NSP32 +#undef CONFIG_SCSI_DEBUG + +/* + * PCMCIA SCSI adapter support + */ +#undef CONFIG_SCSI_PCMCIA + +/* + * Fusion MPT device support + */ +#undef CONFIG_FUSION +#undef CONFIG_FUSION_BOOT +#undef CONFIG_FUSION_ISENSE +#undef CONFIG_FUSION_CTL +#undef CONFIG_FUSION_LAN + +/* + * IEEE 1394 (FireWire) support (EXPERIMENTAL) + */ +#undef CONFIG_IEEE1394 + +/* + * I2O device support + */ +#undef CONFIG_I2O +#undef CONFIG_I2O_PCI +#undef CONFIG_I2O_BLOCK +#undef CONFIG_I2O_LAN +#undef CONFIG_I2O_SCSI +#undef CONFIG_I2O_PROC + +/* + * Network device support + */ +#define CONFIG_NETDEVICES 1 + +/* + * ARCnet devices + */ +#undef CONFIG_ARCNET +#undef CONFIG_DUMMY +#define CONFIG_DUMMY_MODULE 1 +#undef CONFIG_BONDING +#undef CONFIG_EQUALIZER +#undef CONFIG_TUN +#undef CONFIG_ETHERTAP +#undef CONFIG_NET_SB1000 + +/* + * Ethernet (10 or 100Mbit) + */ +#define CONFIG_NET_ETHERNET 1 +#undef CONFIG_SUNLANCE +#undef CONFIG_HAPPYMEAL +#undef CONFIG_SUNBMAC +#undef CONFIG_SUNQE +#undef CONFIG_SUNGEM +#undef CONFIG_NET_VENDOR_3COM +#undef CONFIG_LANCE +#undef CONFIG_NET_VENDOR_SMC +#undef CONFIG_NET_VENDOR_RACAL +#undef CONFIG_AT1700 +#undef CONFIG_DEPCA +#undef CONFIG_HP100 +#undef CONFIG_NET_ISA +#define CONFIG_NET_PCI 1 +#undef CONFIG_PCNET32 +#undef CONFIG_AMD8111_ETH +#undef CONFIG_ADAPTEC_STARFIRE +#undef CONFIG_AC3200 +#undef CONFIG_APRICOT +#undef CONFIG_B44 +#undef CONFIG_CS89x0 +#undef CONFIG_TULIP +#undef CONFIG_DE4X5 +#undef CONFIG_DGRS +#undef CONFIG_DM9102 +#undef CONFIG_EEPRO100 +#undef CONFIG_EEPRO100_PIO +#undef CONFIG_E100 +#undef CONFIG_LNE390 +#undef CONFIG_FEALNX +#undef CONFIG_NATSEMI +#undef CONFIG_NE2K_PCI +#undef CONFIG_NE3210 +#undef CONFIG_ES3210 +#undef CONFIG_8139CP +#undef CONFIG_8139TOO +#define CONFIG_8139TOO_MODULE 1 +#undef CONFIG_8139TOO_PIO +#undef CONFIG_8139TOO_TUNE_TWISTER +#undef CONFIG_8139TOO_8129 +#undef CONFIG_8139_OLD_RX_RESET +#undef CONFIG_SIS900 +#undef CONFIG_EPIC100 +#undef CONFIG_SUNDANCE +#undef CONFIG_SUNDANCE_MMIO +#undef CONFIG_TLAN +#undef CONFIG_VIA_RHINE +#undef CONFIG_VIA_RHINE_MMIO +#undef CONFIG_WINBOND_840 +#undef CONFIG_NET_POCKET + +/* + * Ethernet (1000 Mbit) + */ +#undef CONFIG_ACENIC +#undef CONFIG_DL2K +#undef CONFIG_E1000 +#undef CONFIG_MYRI_SBUS +#undef CONFIG_NS83820 +#undef CONFIG_HAMACHI +#undef CONFIG_YELLOWFIN +#undef CONFIG_R8169 +#undef CONFIG_SK98LIN +#undef CONFIG_TIGON3 +#undef CONFIG_FDDI +#undef CONFIG_HIPPI +#undef CONFIG_PLIP +#undef CONFIG_PPP +#define CONFIG_PPP_MODULE 1 +#define CONFIG_PPP_MULTILINK 1 +#define CONFIG_PPP_FILTER 1 +#undef CONFIG_PPP_ASYNC +#define CONFIG_PPP_ASYNC_MODULE 1 +#undef CONFIG_PPP_SYNC_TTY +#define CONFIG_PPP_SYNC_TTY_MODULE 1 +#undef CONFIG_PPP_DEFLATE +#define CONFIG_PPP_DEFLATE_MODULE 1 +#undef CONFIG_PPP_BSDCOMP +#undef CONFIG_PPPOE +#undef CONFIG_SLIP + +/* + * Wireless LAN (non-hamradio) + */ +#define CONFIG_NET_RADIO 1 +#undef CONFIG_STRIP +#undef CONFIG_WAVELAN +#undef CONFIG_ARLAN +#undef CONFIG_AIRONET4500 +#undef CONFIG_AIRONET4500_NONCS +#undef CONFIG_AIRONET4500_PROC +#undef CONFIG_AIRO +#undef CONFIG_HERMES +#define CONFIG_HERMES_MODULE 1 +#undef CONFIG_PLX_HERMES +#undef CONFIG_TMD_HERMES +#undef CONFIG_PCI_HERMES + +/* + * Wireless Pcmcia cards support + */ +#undef CONFIG_PCMCIA_HERMES +#define CONFIG_PCMCIA_HERMES_MODULE 1 +#undef CONFIG_AIRO_CS +#define CONFIG_NET_WIRELESS 1 + +/* + * Token Ring devices + */ +#undef CONFIG_TR +#undef CONFIG_NET_FC +#undef CONFIG_RCPCI +#undef CONFIG_SHAPER + +/* + * Wan interfaces + */ +#undef CONFIG_WAN + +/* + * PCMCIA network device support + */ +#define CONFIG_NET_PCMCIA 1 +#undef CONFIG_PCMCIA_3C589 +#undef CONFIG_PCMCIA_3C574 +#undef CONFIG_PCMCIA_FMVJ18X +#undef CONFIG_PCMCIA_PCNET +#define CONFIG_PCMCIA_PCNET_MODULE 1 +#undef CONFIG_PCMCIA_AXNET +#undef CONFIG_PCMCIA_NMCLAN +#undef CONFIG_PCMCIA_SMC91C92 +#undef CONFIG_PCMCIA_XIRC2PS +#undef CONFIG_ARCNET_COM20020_CS +#undef CONFIG_PCMCIA_IBMTR +#undef CONFIG_PCMCIA_XIRCOM +#undef CONFIG_PCMCIA_XIRTULIP +#define CONFIG_NET_PCMCIA_RADIO 1 +#undef CONFIG_PCMCIA_RAYCS +#undef CONFIG_PCMCIA_NETWAVE +#undef CONFIG_PCMCIA_WAVELAN +#undef CONFIG_AIRONET4500_CS + +/* + * Amateur Radio support + */ +#undef CONFIG_HAMRADIO + +/* + * IrDA (infrared) support + */ +#undef CONFIG_IRDA + +/* + * ISDN subsystem + */ +#undef CONFIG_ISDN + +/* + * Old CD-ROM drivers (not SCSI, not IDE) + */ +#undef CONFIG_CD_NO_IDESCSI + +/* + * Input core support + */ +#undef CONFIG_INPUT +#define CONFIG_INPUT_MODULE 1 +#undef CONFIG_INPUT_KEYBDEV +#define CONFIG_INPUT_KEYBDEV_MODULE 1 +#undef CONFIG_INPUT_MOUSEDEV +#define CONFIG_INPUT_MOUSEDEV_MODULE 1 +#define CONFIG_INPUT_MOUSEDEV_SCREEN_X (1024) +#define CONFIG_INPUT_MOUSEDEV_SCREEN_Y (768) +#undef CONFIG_INPUT_JOYDEV +#undef CONFIG_INPUT_EVDEV +#define CONFIG_INPUT_EVDEV_MODULE 1 + +/* + * Character devices + */ +#define CONFIG_VT 1 +#define CONFIG_VT_CONSOLE 1 +#undef CONFIG_SERIAL +#define CONFIG_SERIAL_MODULE 1 +#undef CONFIG_SERIAL_EXTENDED +#undef CONFIG_SERIAL_NONSTANDARD +#define CONFIG_UNIX98_PTYS 1 +#define CONFIG_UNIX98_PTY_COUNT (512) + +/* + * I2C support + */ +#undef CONFIG_I2C + +/* + * Mice + */ +#undef CONFIG_BUSMOUSE +#define CONFIG_MOUSE 1 +#define CONFIG_PSMOUSE 1 +#undef CONFIG_82C710_MOUSE +#undef CONFIG_PC110_PAD +#undef CONFIG_MK712_MOUSE + +/* + * Joysticks + */ +#undef CONFIG_INPUT_GAMEPORT +#undef CONFIG_INPUT_NS558 +#undef CONFIG_INPUT_LIGHTNING +#undef CONFIG_INPUT_PCIGAME +#undef CONFIG_INPUT_CS461X +#undef CONFIG_INPUT_EMU10K1 +#undef CONFIG_INPUT_SERIO +#undef CONFIG_INPUT_SERPORT + +/* + * Joysticks + */ +#undef CONFIG_INPUT_ANALOG +#undef CONFIG_INPUT_A3D +#undef CONFIG_INPUT_ADI +#undef CONFIG_INPUT_COBRA +#undef CONFIG_INPUT_GF2K +#undef CONFIG_INPUT_GRIP +#undef CONFIG_INPUT_INTERACT +#undef CONFIG_INPUT_TMDC +#undef CONFIG_INPUT_SIDEWINDER +#undef CONFIG_INPUT_IFORCE_USB +#undef CONFIG_INPUT_IFORCE_232 +#undef CONFIG_INPUT_WARRIOR +#undef CONFIG_INPUT_MAGELLAN +#undef CONFIG_INPUT_SPACEORB +#undef CONFIG_INPUT_SPACEBALL +#undef CONFIG_INPUT_STINGER +#undef CONFIG_INPUT_DB9 +#undef CONFIG_INPUT_GAMECON +#undef CONFIG_INPUT_TURBOGRAFX +#undef CONFIG_QIC02_TAPE +#undef CONFIG_IPMI_HANDLER +#undef CONFIG_IPMI_PANIC_EVENT +#undef CONFIG_IPMI_DEVICE_INTERFACE +#undef CONFIG_IPMI_KCS +#undef CONFIG_IPMI_WATCHDOG + +/* + * Watchdog Cards + */ +#undef CONFIG_WATCHDOG +#undef CONFIG_SCx200_GPIO +#undef CONFIG_AMD_RNG +#undef CONFIG_INTEL_RNG +#undef CONFIG_HW_RANDOM +#undef CONFIG_AMD_PM768 +#undef CONFIG_NVRAM +#undef CONFIG_RTC +#define CONFIG_RTC_MODULE 1 +#undef CONFIG_DTLK +#undef CONFIG_R3964 +#undef CONFIG_APPLICOM +#undef CONFIG_SONYPI + +/* + * Ftape, the floppy tape device driver + */ +#undef CONFIG_FTAPE +#undef CONFIG_AGP + +/* + * Direct Rendering Manager (XFree86 DRI support) + */ +#define CONFIG_DRM 1 +#undef CONFIG_DRM_OLD + +/* + * DRM 4.1 drivers + */ +#define CONFIG_DRM_NEW 1 +#undef CONFIG_DRM_TDFX +#undef CONFIG_DRM_GAMMA +#undef CONFIG_DRM_R128 +#undef CONFIG_DRM_RADEON +#undef CONFIG_DRM_I810 +#undef CONFIG_DRM_I810_XFREE_41 +#undef CONFIG_DRM_I830 +#undef CONFIG_DRM_MGA +#undef CONFIG_DRM_SIS + +/* + * PCMCIA character devices + */ +#undef CONFIG_PCMCIA_SERIAL_CS +#define CONFIG_PCMCIA_SERIAL_CS_MODULE 1 +#undef CONFIG_SYNCLINK_CS +#undef CONFIG_MWAVE + +/* + * Multimedia devices + */ +#undef CONFIG_VIDEO_DEV +#define CONFIG_VIDEO_DEV_MODULE 1 + +/* + * Video For Linux + */ +#define CONFIG_VIDEO_PROC_FS 1 +#undef CONFIG_I2C_PARPORT + +/* + * Video Adapters + */ +#undef CONFIG_VIDEO_BT848 +#undef CONFIG_VIDEO_PMS +#undef CONFIG_VIDEO_CPIA +#undef CONFIG_VIDEO_SAA5249 +#undef CONFIG_TUNER_3036 +#undef CONFIG_VIDEO_STRADIS +#undef CONFIG_VIDEO_ZORAN +#undef CONFIG_VIDEO_ZORAN_BUZ +#undef CONFIG_VIDEO_ZORAN_DC10 +#undef CONFIG_VIDEO_ZORAN_LML33 +#undef CONFIG_VIDEO_ZR36120 +#undef CONFIG_VIDEO_MEYE + +/* + * Radio Adapters + */ +#undef CONFIG_RADIO_CADET +#undef CONFIG_RADIO_RTRACK +#undef CONFIG_RADIO_RTRACK2 +#undef CONFIG_RADIO_AZTECH +#undef CONFIG_RADIO_GEMTEK +#undef CONFIG_RADIO_GEMTEK_PCI +#undef CONFIG_RADIO_MAXIRADIO +#undef CONFIG_RADIO_MAESTRO +#undef CONFIG_RADIO_MIROPCM20 +#undef CONFIG_RADIO_MIROPCM20_RDS +#undef CONFIG_RADIO_SF16FMI +#undef CONFIG_RADIO_SF16FMR2 +#undef CONFIG_RADIO_TERRATEC +#undef CONFIG_RADIO_TRUST +#undef CONFIG_RADIO_TYPHOON +#undef CONFIG_RADIO_ZOLTRIX + +/* + * File systems + */ +#define CONFIG_QUOTA 1 +#define CONFIG_QFMT_V2 1 +#undef CONFIG_AUTOFS_FS +#define CONFIG_AUTOFS_FS_MODULE 1 +#undef CONFIG_AUTOFS4_FS +#define CONFIG_AUTOFS4_FS_MODULE 1 +#undef CONFIG_REISERFS_FS +#undef CONFIG_REISERFS_CHECK +#undef CONFIG_REISERFS_PROC_INFO +#undef CONFIG_ADFS_FS +#undef CONFIG_ADFS_FS_RW +#undef CONFIG_AFFS_FS +#undef CONFIG_HFS_FS +#undef CONFIG_HFSPLUS_FS +#undef CONFIG_BEFS_FS +#undef CONFIG_BEFS_DEBUG +#undef CONFIG_BFS_FS +#undef CONFIG_EXT3_FS +#define CONFIG_EXT3_FS_MODULE 1 +#undef CONFIG_JBD +#define CONFIG_JBD_MODULE 1 +#undef CONFIG_JBD_DEBUG +#undef CONFIG_FAT_FS +#define CONFIG_FAT_FS_MODULE 1 +#undef CONFIG_MSDOS_FS +#define CONFIG_MSDOS_FS_MODULE 1 +#undef CONFIG_UMSDOS_FS +#define CONFIG_UMSDOS_FS_MODULE 1 +#undef CONFIG_VFAT_FS +#define CONFIG_VFAT_FS_MODULE 1 +#undef CONFIG_EFS_FS +#undef CONFIG_JFFS_FS +#undef CONFIG_JFFS2_FS +#undef CONFIG_CRAMFS +#define CONFIG_TMPFS 1 +#define CONFIG_RAMFS 1 +#define CONFIG_ISO9660_FS 1 +#define CONFIG_JOLIET 1 +#define CONFIG_ZISOFS 1 +#undef CONFIG_JFS_FS +#undef CONFIG_JFS_DEBUG +#undef CONFIG_JFS_STATISTICS +#undef CONFIG_MINIX_FS +#define CONFIG_MINIX_FS_MODULE 1 +#undef CONFIG_VXFS_FS +#undef CONFIG_NTFS_FS +#define CONFIG_NTFS_FS_MODULE 1 +#undef CONFIG_NTFS_RW +#undef CONFIG_HPFS_FS +#define CONFIG_PROC_FS 1 +#undef CONFIG_DEVFS_FS +#undef CONFIG_DEVFS_MOUNT +#undef CONFIG_DEVFS_DEBUG +#define CONFIG_DEVPTS_FS 1 +#undef CONFIG_QNX4FS_FS +#undef CONFIG_QNX4FS_RW +#undef CONFIG_ROMFS_FS +#define CONFIG_EXT2_FS 1 +#undef CONFIG_SYSV_FS +#undef CONFIG_UDF_FS +#define CONFIG_UDF_FS_MODULE 1 +#define CONFIG_UDF_RW 1 +#undef CONFIG_UFS_FS +#define CONFIG_UFS_FS_MODULE 1 +#undef CONFIG_UFS_FS_WRITE + +/* + * Network File Systems + */ +#undef CONFIG_CODA_FS +#undef CONFIG_INTERMEZZO_FS +#undef CONFIG_NFS_FS +#undef CONFIG_NFS_V3 +#undef CONFIG_NFS_DIRECTIO +#undef CONFIG_ROOT_NFS +#undef CONFIG_NFSD +#undef CONFIG_NFSD_V3 +#undef CONFIG_NFSD_TCP +#undef CONFIG_SUNRPC +#undef CONFIG_LOCKD +#undef CONFIG_SMB_FS +#define CONFIG_SMB_FS_MODULE 1 +#undef CONFIG_SMB_NLS_DEFAULT +#undef CONFIG_NCP_FS +#undef CONFIG_NCPFS_PACKET_SIGNING +#undef CONFIG_NCPFS_IOCTL_LOCKING +#undef CONFIG_NCPFS_STRONG +#undef CONFIG_NCPFS_NFS_NS +#undef CONFIG_NCPFS_OS2_NS +#undef CONFIG_NCPFS_SMALLDOS +#undef CONFIG_NCPFS_NLS +#undef CONFIG_NCPFS_EXTRAS +#define CONFIG_ZISOFS_FS 1 + +/* + * Partition Types + */ +#undef CONFIG_PARTITION_ADVANCED +#define CONFIG_MSDOS_PARTITION 1 +#define CONFIG_SMB_NLS 1 +#define CONFIG_NLS 1 + +/* + * Native Language Support + */ +#define CONFIG_NLS_DEFAULT "iso8859-1" +#undef CONFIG_NLS_CODEPAGE_437 +#undef CONFIG_NLS_CODEPAGE_737 +#undef CONFIG_NLS_CODEPAGE_775 +#undef CONFIG_NLS_CODEPAGE_850 +#undef CONFIG_NLS_CODEPAGE_852 +#undef CONFIG_NLS_CODEPAGE_855 +#undef CONFIG_NLS_CODEPAGE_857 +#undef CONFIG_NLS_CODEPAGE_860 +#undef CONFIG_NLS_CODEPAGE_861 +#undef CONFIG_NLS_CODEPAGE_862 +#undef CONFIG_NLS_CODEPAGE_863 +#undef CONFIG_NLS_CODEPAGE_864 +#undef CONFIG_NLS_CODEPAGE_865 +#undef CONFIG_NLS_CODEPAGE_866 +#undef CONFIG_NLS_CODEPAGE_869 +#undef CONFIG_NLS_CODEPAGE_936 +#undef CONFIG_NLS_CODEPAGE_950 +#undef CONFIG_NLS_CODEPAGE_932 +#define CONFIG_NLS_CODEPAGE_932_MODULE 1 +#undef CONFIG_NLS_CODEPAGE_949 +#undef CONFIG_NLS_CODEPAGE_874 +#undef CONFIG_NLS_ISO8859_8 +#undef CONFIG_NLS_CODEPAGE_1250 +#undef CONFIG_NLS_CODEPAGE_1251 +#undef CONFIG_NLS_ISO8859_1 +#undef CONFIG_NLS_ISO8859_2 +#undef CONFIG_NLS_ISO8859_3 +#undef CONFIG_NLS_ISO8859_4 +#undef CONFIG_NLS_ISO8859_5 +#undef CONFIG_NLS_ISO8859_6 +#undef CONFIG_NLS_ISO8859_7 +#undef CONFIG_NLS_ISO8859_9 +#undef CONFIG_NLS_ISO8859_13 +#undef CONFIG_NLS_ISO8859_14 +#undef CONFIG_NLS_ISO8859_15 +#undef CONFIG_NLS_KOI8_R +#undef CONFIG_NLS_KOI8_U +#undef CONFIG_NLS_UTF8 +#define CONFIG_NLS_UTF8_MODULE 1 + +/* + * Console drivers + */ +#define CONFIG_VGA_CONSOLE 1 +#define CONFIG_VIDEO_SELECT 1 +#undef CONFIG_MDA_CONSOLE + +/* + * Frame-buffer support + */ +#define CONFIG_FB 1 +#define CONFIG_DUMMY_CONSOLE 1 +#undef CONFIG_FB_RIVA +#undef CONFIG_FB_CLGEN +#undef CONFIG_FB_PM2 +#undef CONFIG_FB_PM3 +#undef CONFIG_FB_CYBER2000 +#undef CONFIG_FB_VESA +#undef CONFIG_FB_VGA16 +#undef CONFIG_FB_HGA +#define CONFIG_VIDEO_SELECT 1 +#undef CONFIG_FB_MATROX +#undef CONFIG_FB_ATY +#undef CONFIG_FB_RADEON +#define CONFIG_FB_RADEON_MODULE 1 +#undef CONFIG_FB_ATY128 +#undef CONFIG_FB_INTEL +#undef CONFIG_FB_SIS +#undef CONFIG_FB_NEOMAGIC +#undef CONFIG_FB_3DFX +#undef CONFIG_FB_VOODOO1 +#undef CONFIG_FB_TRIDENT +#undef CONFIG_FB_VIRTUAL +#undef CONFIG_FBCON_ADVANCED +#undef CONFIG_FBCON_CFB8 +#define CONFIG_FBCON_CFB8_MODULE 1 +#undef CONFIG_FBCON_CFB16 +#define CONFIG_FBCON_CFB16_MODULE 1 +#undef CONFIG_FBCON_CFB24 +#define CONFIG_FBCON_CFB24_MODULE 1 +#undef CONFIG_FBCON_CFB32 +#define CONFIG_FBCON_CFB32_MODULE 1 +#undef CONFIG_FBCON_FONTWIDTH8_ONLY +#undef CONFIG_FBCON_FONTS +#define CONFIG_FONT_8x8 1 +#define CONFIG_FONT_8x16 1 + +/* + * Sound + */ +#undef CONFIG_SOUND +#define CONFIG_SOUND_MODULE 1 +#undef CONFIG_SOUND_ALI5455 +#undef CONFIG_SOUND_BT878 +#undef CONFIG_SOUND_CMPCI +#undef CONFIG_SOUND_EMU10K1 +#undef CONFIG_MIDI_EMU10K1 +#undef CONFIG_SOUND_FUSION +#undef CONFIG_SOUND_CS4281 +#undef CONFIG_SOUND_ES1370 +#undef CONFIG_SOUND_ES1371 +#undef CONFIG_SOUND_ESSSOLO1 +#undef CONFIG_SOUND_MAESTRO +#undef CONFIG_SOUND_MAESTRO3 +#undef CONFIG_SOUND_FORTE +#undef CONFIG_SOUND_ICH +#undef CONFIG_SOUND_RME96XX +#undef CONFIG_SOUND_SONICVIBES +#undef CONFIG_SOUND_TRIDENT +#define CONFIG_SOUND_TRIDENT_MODULE 1 +#undef CONFIG_SOUND_MSNDCLAS +#undef CONFIG_SOUND_MSNDPIN +#undef CONFIG_SOUND_VIA82CXXX +#undef CONFIG_MIDI_VIA82CXXX +#undef CONFIG_SOUND_OSS +#undef CONFIG_SOUND_TVMIXER +#undef CONFIG_SOUND_AD1980 +#undef CONFIG_SOUND_WM97XX + +/* + * USB support + */ +#undef CONFIG_USB +#define CONFIG_USB_MODULE 1 +#undef CONFIG_USB_DEBUG + +/* + * Miscellaneous USB options + */ +#define CONFIG_USB_DEVICEFS 1 +#undef CONFIG_USB_BANDWIDTH + +/* + * USB Host Controller Drivers + */ +#undef CONFIG_USB_EHCI_HCD +#undef CONFIG_USB_UHCI +#undef CONFIG_USB_UHCI_ALT +#undef CONFIG_USB_OHCI +#define CONFIG_USB_OHCI_MODULE 1 + +/* + * USB Device Class drivers + */ +#undef CONFIG_USB_AUDIO +#undef CONFIG_USB_EMI26 +#undef CONFIG_USB_BLUETOOTH +#undef CONFIG_USB_MIDI +#undef CONFIG_USB_STORAGE +#define CONFIG_USB_STORAGE_MODULE 1 +#undef CONFIG_USB_STORAGE_DEBUG +#define CONFIG_USB_STORAGE_DATAFAB 1 +#define CONFIG_USB_STORAGE_FREECOM 1 +#define CONFIG_USB_STORAGE_ISD200 1 +#define CONFIG_USB_STORAGE_DPCM 1 +#define CONFIG_USB_STORAGE_HP8200e 1 +#define CONFIG_USB_STORAGE_SDDR09 1 +#define CONFIG_USB_STORAGE_SDDR55 1 +#define CONFIG_USB_STORAGE_JUMPSHOT 1 +#undef CONFIG_USB_ACM +#define CONFIG_USB_ACM_MODULE 1 +#undef CONFIG_USB_PRINTER +#define CONFIG_USB_PRINTER_MODULE 1 + +/* + * USB Human Interface Devices (HID) + */ +#undef CONFIG_USB_HID +#define CONFIG_USB_HID_MODULE 1 +#define CONFIG_USB_HIDINPUT 1 +#undef CONFIG_USB_HIDDEV +#undef CONFIG_USB_KBD +#undef CONFIG_USB_MOUSE +#undef CONFIG_USB_AIPTEK +#undef CONFIG_USB_WACOM +#undef CONFIG_USB_KBTAB +#undef CONFIG_USB_POWERMATE + +/* + * USB Imaging devices + */ +#undef CONFIG_USB_DC2XX +#undef CONFIG_USB_MDC800 +#undef CONFIG_USB_SCANNER +#undef CONFIG_USB_MICROTEK +#undef CONFIG_USB_HPUSBSCSI + +/* + * USB Multimedia devices + */ +#undef CONFIG_USB_IBMCAM +#undef CONFIG_USB_KONICAWC +#undef CONFIG_USB_OV511 +#define CONFIG_USB_OV511_MODULE 1 +#undef CONFIG_USB_PWC +#undef CONFIG_USB_SE401 +#undef CONFIG_USB_STV680 +#undef CONFIG_USB_VICAM +#undef CONFIG_USB_DSBR +#undef CONFIG_USB_DABUSB + +/* + * USB Network adaptors + */ +#undef CONFIG_USB_PEGASUS +#undef CONFIG_USB_RTL8150 +#undef CONFIG_USB_KAWETH +#undef CONFIG_USB_CATC +#undef CONFIG_USB_AX8817X +#undef CONFIG_USB_CDCETHER +#undef CONFIG_USB_USBNET + +/* + * USB port drivers + */ +#undef CONFIG_USB_USS720 + +/* + * USB Serial Converter support + */ +#undef CONFIG_USB_SERIAL + +/* + * USB Miscellaneous drivers + */ +#undef CONFIG_USB_RIO500 +#undef CONFIG_USB_AUERSWALD +#undef CONFIG_USB_TIGL +#undef CONFIG_USB_BRLVGER +#undef CONFIG_USB_LCD + +/* + * Bluetooth support + */ +#undef CONFIG_BLUEZ + +/* + * Kernel hacking + */ +#undef CONFIG_DEBUG_KERNEL +#define CONFIG_LOG_BUF_SHIFT (0) + +/* + * Cryptographic options + */ +#undef CONFIG_CRYPTO + +/* + * Library routines + */ +#undef CONFIG_CRC32 +#define CONFIG_ZLIB_INFLATE 1 +#undef CONFIG_ZLIB_DEFLATE +#define CONFIG_ZLIB_DEFLATE_MODULE 1 +#undef CONFIG_FW_LOADER diff -ruN linux-2.4.23-pre6/include/linux/bitops.h linux-2.4.23-pre6-swsusp/include/linux/bitops.h --- linux-2.4.23-pre6/include/linux/bitops.h 2001-11-23 04:46:18.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/bitops.h 2003-10-05 03:42:26.000000000 +0900 @@ -1,6 +1,6 @@ #ifndef _LINUX_BITOPS_H #define _LINUX_BITOPS_H - +#include /* * ffs: find first bit set. This is defined the same way as @@ -38,6 +38,47 @@ } /* + * fls: find last bit set. + */ + +extern __inline__ int generic_fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000)) { + x <<= 1; + r -= 1; + } + return r; +} + +extern __inline__ int get_bitmask_order(unsigned int count) +{ + int order; + + order = fls(count); + return order; /* We could be slightly more clever with -1 here... */ +} + +/* * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ @@ -66,7 +107,5 @@ return (res & 0x0F) + ((res >> 4) & 0x0F); } -#include - #endif diff -ruN linux-2.4.23-pre6/include/linux/init.h linux-2.4.23-pre6-swsusp/include/linux/init.h --- linux-2.4.23-pre6/include/linux/init.h 2001-12-22 02:42:03.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/init.h 2003-10-05 03:42:26.000000000 +0900 @@ -111,6 +111,9 @@ */ #define module_exit(x) __exitcall(x); +/* Data marked not to be saved by software_suspend() */ +#define __nosavedata __attribute__ ((__section__ (".data.nosave"))) + #else /* MODULE */ #define __init diff -ruN linux-2.4.23-pre6/include/linux/mm.h linux-2.4.23-pre6-swsusp/include/linux/mm.h --- linux-2.4.23-pre6/include/linux/mm.h 2003-10-05 04:16:45.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/mm.h 2003-10-05 03:45:24.000000000 +0900 @@ -610,6 +610,8 @@ #define __GFP_IO 0x40 /* Can start low memory physical IO? */ #define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */ #define __GFP_FS 0x100 /* Can call down to low-level FS? */ +#define __GFP_FAST 0x200 /* fast return in reschedule if out + of page (used in swsusp) */ #define GFP_NOHIGHIO (__GFP_HIGH | __GFP_WAIT | __GFP_IO) #define GFP_NOIO (__GFP_HIGH | __GFP_WAIT) diff -ruN linux-2.4.23-pre6/include/linux/raid/md.h linux-2.4.23-pre6-swsusp/include/linux/raid/md.h --- linux-2.4.23-pre6/include/linux/raid/md.h 2003-06-13 23:51:39.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/raid/md.h 2003-10-05 03:42:26.000000000 +0900 @@ -86,6 +86,8 @@ extern void md_print_devices (void); +extern void md_autostart_arrays(void); + #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } #endif diff -ruN linux-2.4.23-pre6/include/linux/reboot.h linux-2.4.23-pre6-swsusp/include/linux/reboot.h --- linux-2.4.23-pre6/include/linux/reboot.h 2001-02-10 07:46:13.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/reboot.h 2003-10-05 03:42:26.000000000 +0900 @@ -20,6 +20,7 @@ * CAD_OFF Ctrl-Alt-Del sequence sends SIGINT to init task. * POWER_OFF Stop OS and remove all power from system, if possible. * RESTART2 Restart system using given command string. + * SW_SUSPEND Suspend system using Software Suspend if compiled in */ #define LINUX_REBOOT_CMD_RESTART 0x01234567 @@ -28,6 +29,7 @@ #define LINUX_REBOOT_CMD_CAD_OFF 0x00000000 #define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4 +#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2 #ifdef __KERNEL__ @@ -46,6 +48,12 @@ extern void machine_halt(void); extern void machine_power_off(void); +/* + * Architecture-independent suspend facility + */ + +#include + #endif #endif /* _LINUX_REBOOT_H */ diff -ruN linux-2.4.23-pre6/include/linux/sched.h linux-2.4.23-pre6-swsusp/include/linux/sched.h --- linux-2.4.23-pre6/include/linux/sched.h 2003-10-05 04:16:45.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/sched.h 2003-10-05 03:45:24.000000000 +0900 @@ -431,8 +431,13 @@ #define PF_MEMALLOC 0x00000800 /* Allocating memory */ #define PF_FREE_PAGES 0x00002000 /* per process page freeing */ #define PF_NOIO 0x00004000 /* avoid generating further I/O */ - +#define PF_FROZEN 0x00010000 /* frozen for system suspend */ +#define PF_FREEZE 0x00020000 /* trying to freeze this task */ +#define PF_SYNCTHREAD 0x00040000 /* this thread can start activity during the + early part of freezing processes */ +#define PF_FRIDGE_WAIT 0x00080000 /* this thread is currently doing I/O */ #define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ +#define PF_NOFREEZE 0x00200000 /* this thread should never be frozen */ /* * Ptrace flags diff -ruN linux-2.4.23-pre6/include/linux/selection.h linux-2.4.23-pre6-swsusp/include/linux/selection.h --- linux-2.4.23-pre6/include/linux/selection.h 2001-11-23 04:47:23.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/selection.h 2003-10-05 03:42:26.000000000 +0900 @@ -35,8 +35,8 @@ extern void complement_pos(int currcons, int offset); extern void invert_screen(int currcons, int offset, int count, int shift); -extern void getconsxy(int currcons, char *p); -extern void putconsxy(int currcons, char *p); +extern void getconsxy(int currcons, unsigned char *p); +extern void putconsxy(int currcons, unsigned char *p); extern u16 vcs_scr_readw(int currcons, const u16 *org); extern void vcs_scr_writew(int currcons, u16 val, u16 *org); diff -ruN linux-2.4.23-pre6/include/linux/suspend-common.h linux-2.4.23-pre6-swsusp/include/linux/suspend-common.h --- linux-2.4.23-pre6/include/linux/suspend-common.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.4.23-pre6-swsusp/include/linux/suspend-common.h 2003-10-05 03:42:26.000000000 +0900 @@ -0,0 +1,523 @@ +/* + * Software Suspend. + * + * Module level definitions. + * + */ + +#ifndef SWSUSP_COMMON_H +#define SWSUSP_COMMON_H + +#include +#include +#include +#include +#include +#if defined(CONFIG_FBCON_SPLASHSCREEN) +#include +#include