Commit ff31dc0b authored by Linus Torvalds's avatar Linus Torvalds

v2.4.5.6 -> v2.4.5.7

  - Patrick Mochel: PCI documentation, and PM cleanups
  - mtd: export nand ECC functions
  - Jes Sorenson: acenic driver update
  - Alan Cox: fix vxfs merge boo-boo
  - me: undo page_launder() LRU changes, they have nasty side effects
  - wanrouter: fix error code
parent 29f279c7
......@@ -1993,6 +1993,13 @@ S: 1805 Marquette
S: Richardson, Texas 75081
S: USA
N: Patrick Mochel
E: mochel@transmeta.com
D: PCI Power Management, ACPI work
S: 3940 Freedom Circle
S: Santa Clara, CA 95054
S: USA
N: Eberhard Moenkeberg
E: emoenke@gwdg.de
D: CDROM driver "sbpcd" (Matsushita/Panasonic/Soundblaster)
......
......@@ -3,7 +3,7 @@
Understanding the Linux Kernel.
Juan-Mariano de Goyeneche < jmseyas@dit.upm.es>
Juan-Mariano de Goyeneche <jmseyas@dit.upm.es>
/*
* The latest version of this document may be found at:
......@@ -41,7 +41,7 @@
* Title: "The Linux Kernel"
Author: David A. Rusling.
URL: http://sunsite.unc.edu/linux/LDP/tlk/tlk.html
URL: http://www.linuxdoc.org/LDP/tlk/tlk.html
Keywords: everything!, book.
Description: On line, 200 pages book describing most aspects of
the Linux Kernel. Probably, the first reference for beginners.
......@@ -57,7 +57,7 @@
* Title: "The Linux Kernel Hackers' Guide"
Author: Michael K.Johnson and others.
URL: http://khg.redhat.com/HyperNews/get/khg.html
URL: http://www.linuxdoc.org/LDP/khg/HyperNews/get/khg.html
Keywords: everything!
Description: No more Postscript book-like version. Only HTML now.
Many people have contributed. The interface is similar to web
......@@ -99,15 +99,15 @@
Author: Richard Gooch.
URL: http://www.atnf.csiro.au/~rgooch/linux/vfs.txt
Keywords: VFS, File System, mounting filesystems, opening files,
dentries,
dcache. Description: Brief introduction to the Linux Virtual File
System. What is it, how it works, operations taken when opening a
file or mounting a file system and description of important data
dentries, dcache.
Description: Brief introduction to the Linux Virtual File System.
What is it, how it works, operations taken when opening a file or
mounting a file system and description of important data
structures explaining the purpose of each of their entries.
* Title: "The Linux RAID-1, 4, 5 Code"
Author: Ingo Molnar, Gadi Oxman and Miguel de Icaza.
URL: http://www.ssc.com/lj/issue44/2391.html
URL: http://www2.linuxjournal.com/lj-issues/issue44/2391.html
Keywords: RAID, MD driver.
Description: Linux Journal Kernel Korner article. Here is it's
abstract: "A description of the implementation of the RAID-1,
......@@ -117,7 +117,7 @@
* Title: "Dynamic Kernels: Modularized Device Drivers"
Author: Alessandro Rubini.
URL: http://www.ssc.com/lj/issue23/1219.html
URL: http://www2.linuxjournal.com/lj-issues/issue23/1219.html
Keywords: device driver, module, loading/unloading modules,
allocating resources.
Description: Linux Journal Kernel Korner article. Here is it's
......@@ -132,8 +132,8 @@
Author: Alessandro Rubini.
URL: http://www2.linuxjournal.com/lj-issues/issue24/1220.html
Keywords: character driver, init_module, clean_up module,
autodetection,
mayor number, minor number, file operations, open(), close().
autodetection, mayor number, minor number, file operations,
open(), close().
Description: Linux Journal Kernel Korner article. Here is it's
abstract: "This article, the second of four, introduces part of
the actual code to create custom module implementing a character
......@@ -152,7 +152,7 @@
* Title: "Dissecting Interrupts and Browsing DMA"
Author: Alessandro Rubini and Georg v. Zezschwitz.
URL: http://www.ssc.com/lj/issue26/interrupt.html
URL: http://www2.linuxjournal.com/lj-issues/issue26/1222.html
Keywords: interrupts, irqs, DMA, bottom halves, task queues.
Description: Linux Journal Kernel Korner article. Here is it's
abstract: "This is the fourth in a series of articles about
......@@ -187,26 +187,9 @@
simple---most of the complexity (other than talking to the
hardware) involves managing network packets in memory".
* Title: "An Introduction to the Linux 1.3.x Networking Code"
Author: Vipul Gupta.
URL: http://anchor.cs.binghamton.edu/courses/cs628/linux-net.html
Keywords: files, sk_buffs.
Description: A short description of files under the net/
directory. Each file has a one or two lines paragraph description.
sk_buffs explained, too, with some beautiful pictures. A little
bit outdated.
* Title: "Linux ioctl() Primer"
Author: Vipul Gupta.
URL: http://anchor.cs.binghamton.edu/courses/cs628/ioctl.html
Keywords: ioctl, socket.
Description: Little description and examples on the use and
implementation of the ioctl() system call. A little bit biased
towards sockets.
* Title: "Writing Linux Device Drivers"
Author: Michael K. Johnson.
URL: http://www.redhat.com/~johnsonm/devices.html
URL: http://people.redhat.com/johnsonm/devices.html
Keywords: files, VFS, file operations, kernel interface, character
vs block devices, I/O access, hardware interrupts, DMA, access to
user memory, memory allocation, timers.
......@@ -241,7 +224,7 @@
URL:
ftp://ftp.llp.fu-berlin.de/pub/linux/LINUX-LAB/whitepapers/drivers
.ps.gz
Keywords: character device drivers, I/O, signals, DMA, accesing
Keywords: character device drivers, I/O, signals, DMA, accessing
ports in user space, kernel environment.
Description: 68 pages paper on writing character drivers. A little
bit old (1.993, 1.994) although still useful.
......@@ -260,24 +243,17 @@
Notes: This paper was first published in the Proceedings of the
First Dutch International Symposium on Linux, ISBN 90-367-0385-9.
* Title: "The Second Extended Filesystem"
Author: Matthew Wilcox.
URL: http://pocket.fluff.org/~mrw/linux/ext2.txt
Keywords: ext2, filesystem.
Description: Description of ext2's blocks, directories, inodes...
Notes: Seems to be DOWN. Anyone knows another link for it?
* Title: "Analysis of the Ext2fs structure"
Author: Louis-Dominique Dubeau.
URL: http://step.polymtl.ca/~ldd/ext2fs/ext2fs_toc.html
Keywords: ext2, filesystem, ext2fs.
Description: Description of ext2's blocks, directories, inodes,
bitmaps, invariants ...
bitmaps, invariants...
* Title: "Journaling the Linux ext2fs Filesystem"
Author: Stephen C. Tweedie.
URL:
ftp://ftp.uk.linux.org:/pub/linux/sct/fs/jfs/journal-design.ps.gz
ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/journal-design.ps.gz
Keywords: ext3, journaling.
Description: Excellent 8-pages paper explaining the journaling
capabilities added to ext2 by the author, showing different
......@@ -291,13 +267,13 @@
Description: Kernel functions/structures/variables which changed
from 2.0.x to 2.2.x.
* Title: "Kernel API changes from 2.2 to 2.3"
* Title: "Kernel API changes from 2.2 to 2.4"
Author: Richard Gooch.
URL:
http://www.atnf.csiro.au/~rgooch/linux/docs/porting-to-2.3.html
Keywords: 2.3, changes.
http://www.atnf.csiro.au/~rgooch/linux/docs/porting-to-2.4.html
Keywords: 2.4, changes.
Description: Kernel functions/structures/variables which changed
from 2.2.x to 2.3.x.
from 2.2.x to 2.4.x.
* Title: "Linux Kernel Module Programming Guide"
Author: Ori Pomerantz.
......@@ -333,7 +309,9 @@
* Title: "The Kernel Hacking HOWTO"
Author: Various Talented People, and Rusty.
URL: http://www.samba.org/~netfilter/kernel-hacking-HOWTO.html
URL:
http://www.lisoleg.net/doc/Kernel-Hacking-HOWTO/kernel-hacking-HOW
TO.html
Keywords: HOWTO, kernel contexts, deadlock, locking, modules,
symbols, return conventions.
Description: From the Introduction: "Please understand that I
......@@ -345,7 +323,7 @@
routines. This document assumes familiarity with C, and an
understanding of what the kernel is, and how it is used. It was
originally written for the 2.3 kernels, but nearly all of it
applies to 2.2 too; 2.0 is slightly different. ".
applies to 2.2 too; 2.0 is slightly different".
* Title: "ALSA 0.5.0 Developer documentation"
Author: Stephan 'Jumpy' Bartels .
......@@ -478,21 +456,101 @@
Description: The title says it all.
* Title: "Linux 2.4 Kernel Internals"
Author: Tigran Aivazian.
Author: Tigran Aivazian and Christoph Hellwig.
URL: http://www.moses.uklinux.net/patches/lki.html
Keywords: Linux, kernel, VFS, SMP boot
Description: A little book used for a short training course
I gave on this subject at VERITAS. Covers building the kernel
image, booting (including SMP), process management, VFS and more.
Keywords: Linux, kernel, booting, SMB boot, VFS, page cache.
Description: A little book used for a short training course.
Covers building the kernel image, booting (including SMP bootup),
process management, VFS and more.
* Title: "Linux IP Networking. A Guide to the Implementation and
Modification of the Linux Protocol Stack."
Author: Glenn Herrin.
URL:
http://kernelnewbies.org/documents/ipnetworking/linuxipnetworking.
html
Keywords: network, networking, protocol, IP, UDP, TCP, connection,
socket, receiving, transmitting, forwarding, routing, packets,
modules, /proc, sk_buff, FIB, tags.
Description: Excellent paper devoted to the Linux IP Networking,
explaining anything from the kernel's to the user space
configuration tools' code. Very good to get a general overview of
the kernel networking implementation and understand all steps
packets follow from the time they are received at the network
device till they are delivered to applications. The studied kernel
code is from 2.2.14 version. Provides code for a working packet
dropper example.
* Title: "Get those boards talking under Linux."
Author: Alex Ivchenko.
URL: http://www.ednmag.com/ednmag/reg/2000/06222000/13df2.htm
Keywords: data-acquisition boards, drivers, modules, interrupts,
memory allocation.
Description: Article written for people wishing to make their data
acquisition boards work on their GNU/Linux machines. Gives a basic
overview on writting drivers, from the naming of functions to
interrupt handling.
Notes: Two-parts article. Part II is at
http://www.ednmag.com/ednmag/reg/2000/07062000/14df.htm
* Title: "Linux PCMCIA Programmer's Guide"
Author: David Hinds.
URL: http://pcmcia-cs.sourceforge.net/ftp/doc/PCMCIA-PROG.html
Keywords: PCMCIA.
Description: "This document describes how to write kernel device
drivers for the Linux PCMCIA Card Services interface. It also
describes how to write user-mode utilities for communicating with
Card Services.
* Title: "The Linux Kernel NFSD Implementation"
Author: Neil Brown.
URL:
http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/nfsd.html
Keywords: knfsd, nfsd, NFS, RPC, lockd, mountd, statd.
Description: The title says it all.
Notes: Covers knfsd's version 1.4.7 (patch against 2.2.7 kernel).
* Title: "A Linux vm README"
Author: Kanoj Sarcar.
URL: http://reality.sgi.com/kanoj_engr/vm229.html
Keywords: virtual memory, mm, pgd, vma, page, page flags, page
cache, swap cache, kswapd.
Description: Telegraphic, short descriptions and definitions
relating the Linux virtual memory implementation.
* Title: "(nearly) Complete Linux Loadable Kernel Modules. The
definitive guide for hackers, virus coders and system
administrators."
Author: pragmatic/THC.
URL: http://packetstorm.securify.com/groups/thc/LKM_HACKING.html
Keywords: syscalls, intercept, hide, abuse, symbol table.
Description: Interesting paper on how to abuse the Linux kernel in
order to intercept and modify syscalls, make
files/directories/processes invisible, become root, hijack ttys,
write kernel modules based virus... and solutions for admins to
avoid all those abuses.
Notes: For 2.0.x kernels. Gives guidances to port it to 2.2.x
kernels. Also available in txt format at
http://www.blacknemesis.org/hacking/txt/cllkm.txt
BOOKS: (Not on-line)
* Title: "Linux Device Drivers"
Author: Alessandro Rubini.
Publisher: O'Reilly &Associates.
Publisher: O'Reilly & Associates.
Date: 1998.
Pages: 439.
ISBN: 1-56592-292-1
* Title: "Linux Device Drivers, 2nd Edition"
Author: Alessandro Rubini and Jonathan Corbet.
Publisher: O'Reilly & Associates.
Date: 2001.
Pages: 586.
ISBN: 0-59600-008-1
Notes: Further information in
http://www.oreilly.com/catalog/linuxdrive2/
* Title: "Linux Kernel Internals"
Author: Michael Beck.
Publisher: Addison-Wesley.
......@@ -580,8 +638,26 @@
Notes: Though not being directly about Linux, Linux aims to be
POSIX. Good reference.
* Title: "Understanding the Linux Kernel"
Author: Daniel P. Bovet and Marco Cesati.
Publisher: O'Reilly & Associates, Inc..
Date: 2000.
Pages: 702.
ISBN: 0-596-00002-2
Notes: Further information in
http://www.oreilly.com/catalog/linuxkernel/
MISCELLANEOUS:
* Name: linux/Documentation
Author: Many.
URL: Just look inside your kernel sources.
Keywords: anything, DocBook.
Description: Documentation that comes with the kernel sources,
inside the Documentation directory. Some pages from this document
(including this document itself) have been moved there, and might
be more up to date than the web version.
* Name: "Linux Source Driver"
URL: http://lsd.linux.cz
Keywords: Browsing source code.
......@@ -593,6 +669,16 @@
and variables) and LSD can generate patches for you on the fly
(files, directories or kernel)".
* Name: "Linux Kernel Source Reference"
Author: Thomas Graichen.
URL: http://innominate.org/~graichen/projects/lksr/
Keywords: CVS, web, cvsweb, browsing source code.
Description: Web interface to a CVS server with the kernel
sources. "Here you can have a look at any file of the Linux kernel
sources of any version starting from 1.0 up to the (daily updated)
current version available. Also you can check the differences
between two versions of a file".
* Name: "Cross-Referencing Linux"
URL: http://lxr.linux.no/source/
Keywords: Browsing source code.
......@@ -608,7 +694,7 @@
produced during the week. Published every Thursday.
* Name: "Kernel Traffic"
URL: http://kt.zork.net
URL: http://kt.zork.net/kernel-traffic/
Keywords: linux-kernel mailing list, weekly kernel news.
Description: Weekly newsletter covering the most relevant
discussions of the linux-kernel mailing list.
......@@ -622,10 +708,7 @@
too.
* Name: "New linux-kernel Mailing List FAQ"
URL: Original site:
http://www.altern.org/andrebalsa/doc/lkml-faq.html
URL: U.S. mirror site:
http://www.ececs.uc.edu/~rreilova/linux/lkml-faq.html
URL: http://www.tux.org/lkml/
Keywords: linux-kernel mailing list FAQ.
Description: linux-kernel is a mailing list for developers to
communicate. This FAQ builds on the previous linux-kernel mailing
......@@ -636,34 +719,34 @@
* Name: "Linux Virtual File System"
Author: Peter J. Braam.
URL: http://www.coda.cs.cmu.edu/doc/talks/linuxvfs
URL: http://www.coda.cs.cmu.edu/doc/talks/linuxvfs/
Keywords: slides, VFS, inode, superblock, dentry, dcache.
Description: Set of slides, presumably from a presentation on the
Linux VFS layer. Covers version 2.1.x, with dentries and the
dcache.
* Name: "Gary's Enciclopedia - The Linux Kernel"
* Name: "Gary's Encyclopedia - The Linux Kernel"
Author: Gary (I suppose...).
URL: http://members.aa.net/~swear/pedia/kernel.html
Keywords: links, not found here?.
Description: Gary's Enciclopedia exists to allow the rapid finding
Description: Gary's Encyclopedia exists to allow the rapid finding
of documentation and other information of interest to GNU/Linux
users. It has about 4000 links to external pages in 150 major
categories. This link is for kernel-specific links, documents,
sites... Look there if you could not find here whar you were
sites... Look there if you could not find here what you were
looking for.
* Name: "The home page of Linux-MM"
Author: The Linux-MM team.
URL: http://www.linux.eu.org/Linux-MM/
URL: http://linux-mm.org/
Keywords: memory management, Linux-MM, mm patches, TODO, docs,
mailing list.
Description: Site devoted to Linux Memory Mangement development.
Description: Site devoted to Linux Memory Management development.
Memory related patches, HOWTOs, links, mm developers... Don't miss
it if you are interested in memory management development!
* Name: "Kernel Newbies IRC Channel"
URL: http://www.surriel.com/kernelnewbies.shtml
URL: http://www.kernelnewbies.org
Keywords: IRC, newbies, channel, asking doubts.
Description: #kernelnewbies on irc.openprojects.net. From the web
page: "#kernelnewbies is an IRC network dedicated to the 'newbie'
......@@ -672,7 +755,8 @@
professional kernel hackers that want to help less seasoned kernel
people. [...] #kernelnewbies is on the Open Projects IRC Network,
try irc.openprojects.net or irc.<country>.openprojects.net as your
server and then /join #kernelnewbies".
server and then /join #kernelnewbies". It also hosts articles,
documents, FAQs...
* Name: "linux-kernel mailing list archives and search engines"
URL: http://www.uwsg.indiana.edu/hypermail/linux/kernel/index.html
......@@ -683,4 +767,4 @@
you have a better/another one, please let me know.
_________________________________________________________________
Document last updated on Thu Jun 1 21:58:18 CEST 2000DATE$
Document last updated on Thu Jun 28 15:09:39 CEST 2001
......@@ -62,8 +62,13 @@ contains:
deregistration of the driver or when it's manually pulled
out of a hot-pluggable slot). This function always gets
called from process context, so it can sleep.
suspend, Power management hooks -- called when the device goes to
resume sleep or is resumed.
save_state Save a device's state before it's suspend.
suspend Put device into low power state.
resume Wake device from low power state.
enable_wake Enable device to generate wake events from a low power state.
(Please see Documentation/power/pci.txt for descriptions
of PCI Power Management and the related functions)
The ID table is an array of struct pci_device_id ending with a all-zero entry.
Each entry consists of:
......
PCI Power Management
~~~~~~~~~~~~~~~~~~~~
An overview of the concepts and the related functions in the Linux kernel
Patrick Mochel <mochel@transmeta.com>
---------------------------------------------------------------------------
1. Overview
2. How the PCI Subsystem Does Power Management
3. PCI Utility Functions
4. PCI Device Drivers
5. Resources
1. Overview
~~~~~~~~~~~
The PCI Power Management Specification was introduced between the PCI 2.1 and
PCI 2.2 Specifications. It a standard interface for controlling various
power management operations.
Implementation of the PCI PM Spec is optional, as are several sub-components of
it. If a device supports the PCI PM Spec, the device will have an 8 byte
capability field in its PCI configuration space. This field is used to describe
and control the standard PCI power management features.
The PCI PM spec defines 4 operating states for devices (D0 - D3) and for buses
(B0 - B3). The higher the number, the less power the device consumes. However,
the higher the number, the longer the latency is for the device to return to
an operational state (D0).
Bus power management is not covered in this version of this document.
Note that all PCI devices support D0 and D3 by default, regardless of whether or
not they implement any of the PCI PM spec.
The possible state transitions that a device can undergo are:
+---------------------------+
| Current State | New State |
+---------------------------+
| D0 | D1, D2, D3|
+---------------------------+
| D1 | D2, D3 |
+---------------------------+
| D2 | D3 |
+---------------------------+
| D1, D2, D3 | D0 |
+---------------------------+
Note that when the system is entering a global suspend state, all devices will be
placed into D3 and when resuming, all devices will be placed into D0. However,
when the system is running, other state transitions are possible.
2. How The PCI Subsystem Handles Power Management
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The PCI suspend/resume functionality is accessed indirectly via the Power Management
subsystem. At boot, the PCI driver registers a power management callback with that layer.
Upon entering a suspend state, the PM layer iterates through all of its registered
callbacks. This currently takes place only during APM state transitions.
Upon going to sleep, the PCI subsystem walks its device tree twice. Both times, it does
a depth first walk of the device tree. The first walk saves each of the device's state
and checks for devices that will prevent the system from entering a global power state.
The next walk then places the devices in a low power state.
The first walk allows a graceful recovery in the event of a failure, since none of the
devices have actually been powered down.
In both walks, in particular the second, all children of a bridge are touched before the
actual bridge itself. This allows the bridge to retain power while its children are being
accessed.
Upon resuming from sleep, just the opposite must be true: all bridges must be powered on
and restored before their children are powered on. This is easily accomplished with a
breadth-first walk of the PCI device tree.
3. PCI Utility Functions
~~~~~~~~~~~~~~~~~~~~~~~~
These are helper functions designed to be called by individual device drivers.
Assuming that a device behaves as advertised, these should be applicable in most
cases. However, results may vary.
Note that these functions are never implicitly called for the driver. The driver is always
responsible for deciding when and if to call these.
pci_save_state
--------------
Usage:
pci_save_state(dev, buffer);
Description:
Save first 64 bytes of PCI config space. Buffer must be allocated by caller.
pci_restore_state
-----------------
Usage:
pci_restore_state(dev,buffer);
Description:
Restore previously saved config space. (First 64 bytes only);
If buffer is NULL, then restore what information we know about the device
from bootup: BARs and interrupt line.
pci_set_power_state
-------------------
Usage:
pci_set_power_state(dev,state);
Description:
Transition device to low power state using PCI PM Capabilities registers.
Will fail under one of the following conditions:
- If state is less than current state, but not D0 (illegal transition)
- Device doesn't support PM Capabilities
- Device does not support requested state
pci_enable_wake
---------------
Usage:
pci_enable_wake(dev,state,enable);
Description:
Enable device to generate PME# during low power state using PCI PM
Capabilities.
Checks whether if device supports generating PME# from requested state and fail
if it does not, unless enable == 0 (request is to disable wake events, which
is implicit if it doesn't even support it in the first place).
Note that the PMC Register in the device's PM Capabilties has a bitmask of
the states it supports generating PME# from. D3hot is bit 3 and D3cold is bit
4. So, while a value of 4 as the state may not seem semantically correct, it
is.
4. PCI Device Drivers
~~~~~~~~~~~~~~~~~~~~~
These functions are intended for use by individual drivers, and are defined in
struct pci_driver:
int (*save_state) (struct pci_dev *dev, u32 state);
int (*suspend)(struct pci_dev *dev, u32 state);
int (*resume) (struct pci_dev *dev);
int (*enable_wake) (struct pci_dev *dev, u32 state, int enable);
save_state
----------
Usage:
if (dev->driver && dev->driver->save_state)
dev->driver->save_state(dev,state);
The driver should use this callback to save device state. It should take into
account the current state of the device and the requested state in order to avoid
any unnecessary operations.
For example, a video card that supports all 4 states (D0-D3), all controller context
is preserved when entering D1, but the screen is placed into a low power state
(blanked).
The driver can also interpret this function as a notification that it may be entering
a sleep state in the near future. If it knows that the device cannot enter the
requested state, either because of lack of support for it, or because the devices is
middle of some critical operation, then it should fail.
This function should not be used to set any state in the device or the driver because
the device may not actually enter the sleep state (e.g. another driver later causes
causes a global state transition to fail).
Note that in intermediate low power states, a device's I/O and memory spaces may be
disabled and may not be available in subsequent transitions to lower power states.
suspend
-------
Usage:
if (dev->driver && dev->driver->suspend)
dev->driver->suspend(dev,state);
A driver uses this function to actually transition the device into a low power
state. This may include disabling I/O, memory and bus-mastering, as well as physically
transitioning the device to a lower power state.
Bus mastering may be disabled by doing:
pci_disable_device(dev);
For devices that support the PCI PM Spec, this may be used to set the device's power
state:
pci_set_power_state(dev,state);
The driver is also responsible for disabling any other device-specific features
(e.g blanking screen, turning off on-card memory, etc).
The driver should be sure to track the current state of the device, as it may obviate
the need for some operations.
The driver should update the current_state field in its pci_dev structure in this
function.
resume
------
Usage:
if (dev->driver && dev->driver->suspend)
dev->driver->resume(dev)
The resume callback may be called from any power state, and is always meant to
transition the device to the D0 state.
The driver is responsible for reenabling any features of the device that had
been disabled during previous suspend calls and restoring all state that was saved
in previous save_state calls.
If the device is currently in D3, it must be completely reinitialized, as it must be
assumed that the device has lost all of its context (even that of its PCI config
space). For almost all current drivers, this means that the initialization code that
the driver does at boot must be separated out and called again from the resume
callback. Note that some values for the device may not have to be probed for this
time around if they are saved before entering the low power state.
If the device supports the PCI PM Spec, it can use this to physically transition the
device to D0:
pci_set_power_state(dev,0);
Note that if the entire system is transitioning out of a global sleep state, all
devices will be placed in the D0 state, so this is not necessary. However, in the
event that the device is placed in the D3 state during normal operation, this call
is necessary. It is impossible to determine which of the two events is taking place
in the driver, so it is always a good idea to make that call.
The driver should take note of the state that it is resuming from in order to ensure
correct (and speedy) operation.
The driver should update the current_state field in its pci_dev structure in this
function.
enable_wake
-----------
Usage:
if (dev->driver && dev->driver->enable_wake)
dev->driver->enable_wake(dev,state,enable);
This callback is generally only relevant for devices that support the PCI PM
spec and have the ability to generate a PME# (Power Management Event Signal)
to wake the system up. (However, it is possible that a device may support
some non-standard way of generating a wake event on sleep.)
Bits 15:11 of the PMC (Power Mgmt Capabilities) Register in a device's
PM Capabilties describe what power states the device supports generating a
wake event from:
+------------------+
| Bit | State |
+------------------+
| 15 | D0 |
| 14 | D1 |
| 13 | D2 |
| 12 | D3hot |
| 11 | D3cold |
+------------------+
A device can use this to enable wake events:
pci_enable_wake(dev,state,enable);
Note that to enable PME# from D3cold, a value of 4 should be passed to
pci_enable_wake (since it uses an index into a bitmask). If a driver gets
a request to enable wake events from D3, two calls should be made to
pci_enable_wake (one for both D3hot and D3cold).
5. Resources
~~~~~~~~~~~~
PCI Local Bus Specification
PCI Bus Power Management Interface Specification
http://pcisig.org
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 6
EXTRAVERSION =-pre6
EXTRAVERSION =-pre7
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......
......@@ -63,7 +63,6 @@
#include <asm/uaccess.h>
#include <asm/string.h>
#include <asm/byteorder.h>
#include <math.h>
#include <linux/vmalloc.h>
#include "iphase.h"
#include "suni.h"
......
#
# linux/drivers/nand/Makefile
#
# $Id: Makefile,v 1.3 2001/04/19 23:54:48 dwmw2 Exp $
# $Id: Makefile,v 1.4 2001/06/28 10:49:45 dwmw2 Exp $
O_TARGET := nandlink.o
export-objs := nand.o
export-objs := nand.o nand_ecc.o
obj-$(CONFIG_MTD_NAND) += nand.o
obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o
......
......@@ -4,7 +4,7 @@
* Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
* Toshiba America Electronics Components, Inc.
*
* $Id: nand_ecc.c,v 1.4 2001/01/03 20:02:20 mgadbois Exp $
* $Id: nand_ecc.c,v 1.6 2001/06/28 10:52:26 dwmw2 Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -15,11 +15,13 @@
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
/*
* Pre-calculated 256-way 1 byte column parity
*/
const u_char nand_ecc_precalc_table[] = {
static const u_char nand_ecc_precalc_table[] = {
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
......@@ -42,7 +44,7 @@ const u_char nand_ecc_precalc_table[] = {
/*
* Creates non-inverted ECC code from line parity
*/
void nand_trans_result(u_char reg2, u_char reg3,
static void nand_trans_result(u_char reg2, u_char reg3,
u_char *ecc_code)
{
u_char a, b, i, tmp1, tmp2;
......@@ -202,3 +204,6 @@ int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
/* Should never happen */
return -1;
}
EXPORT_SYMBOL(nand_calculate_ecc);
EXPORT_SYMBOL(nand_correct_data);
......@@ -157,6 +157,9 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
#define __devinit __init
#endif
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef SMP_CACHE_BYTES
#define SMP_CACHE_BYTES L1_CACHE_BYTES
......@@ -260,6 +263,11 @@ static inline void tasklet_init(struct tasklet_struct *tasklet,
#define ace_if_down(dev) {do{} while(0);}
#endif
#ifndef pci_set_dma_mask
#define pci_set_dma_mask(dev, mask) dev->dma_mask = mask;
#endif
#if (LINUX_VERSION_CODE >= 0x02031b)
#define NEW_NETINIT
#define ACE_PROBE_ARG void
......@@ -510,7 +518,7 @@ static int tx_ratio[ACE_MAX_MOD_PARMS];
static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
static char version[] __initdata =
"acenic.c: v0.80 03/08/2001 Jes Sorensen, linux-acenic@SunSITE.dk\n"
"acenic.c: v0.81 04/20/2001 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
static struct net_device *root_dev;
......@@ -740,7 +748,8 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
}
MODULE_AUTHOR("Jes Sorensen <jes@linuxcare.com>");
#ifdef MODULE
MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>");
MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
MODULE_PARM(link, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i");
......@@ -748,12 +757,7 @@ MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i");
MODULE_PARM_DESC(link, "Acenic/3C985/NetGear link state");
MODULE_PARM_DESC(trace, "Acenic/3C985/NetGear firmware trace level");
MODULE_PARM_DESC(tx_coal_tick, "Acenic/3C985/NetGear maximum clock ticks to wait for packets");
MODULE_PARM_DESC(max_tx_desc, "Acenic/3C985/NetGear maximum number of transmit descriptors");
MODULE_PARM_DESC(rx_coal_tick, "Acenic/3C985/NetGear maximum clock ticks to wait for packets");
MODULE_PARM_DESC(max_rx_desc, "Acenic/3C985/NetGear maximum number of receive descriptors");
#endif
static void __exit ace_module_cleanup(void)
......@@ -1040,7 +1044,7 @@ static int __init ace_init(struct net_device *dev)
u32 tig_ver, mac1, mac2, tmp, pci_state;
int board_idx, ecode = 0;
short i;
unsigned char cache;
unsigned char cache_size;
ap = dev->priv;
regs = ap->regs;
......@@ -1173,14 +1177,19 @@ static int __init ace_init(struct net_device *dev)
* Ie. having two NICs in the machine, one will have the cache
* line set at boot time, the other will not.
*/
pci_read_config_byte(ap->pdev, PCI_CACHE_LINE_SIZE, &cache);
if ((cache << 2) != SMP_CACHE_BYTES) {
pci_read_config_byte(ap->pdev, PCI_CACHE_LINE_SIZE, &cache_size);
cache_size <<= 2;
if (cache_size != SMP_CACHE_BYTES) {
printk(KERN_INFO " PCI cache line size set incorrectly "
"(%i bytes) by BIOS/FW, correcting to %i\n",
(cache << 2), SMP_CACHE_BYTES);
"(%i bytes) by BIOS/FW, ", cache_size);
if (cache_size > SMP_CACHE_BYTES)
printk("expecting %i\n", SMP_CACHE_BYTES);
else {
printk("correcting to %i\n", SMP_CACHE_BYTES);
pci_write_config_byte(ap->pdev, PCI_CACHE_LINE_SIZE,
SMP_CACHE_BYTES >> 2);
}
}
pci_state = readl(&regs->PciState);
printk(KERN_INFO " PCI bus width: %i bits, speed: %iMHz, "
......@@ -1189,6 +1198,12 @@ static int __init ace_init(struct net_device *dev)
(pci_state & PCI_66MHZ) ? 66 : 33,
ap->pci_latency);
/*
* Make sure to enable the 64 bit DMA mask if we're in a 64bit slot
*/
if (!(pci_state & PCI_32BIT))
pci_set_dma_mask(ap->pdev, (dma_addr_t)~0ULL);
/*
* Set the max DMA transfer size. Seems that for most systems
* the performance is better when no MAX parameter is
......@@ -1214,21 +1229,10 @@ static int __init ace_init(struct net_device *dev)
printk(KERN_INFO " Disabling PCI memory "
"write and invalidate\n");
}
#ifdef __alpha__
/* This maximizes throughput on my alpha. */
tmp |= DMA_WRITE_MAX_128;
#endif
} else if (ap->pci_command & PCI_COMMAND_INVALIDATE) {
printk(KERN_INFO " PCI memory write & invalidate "
"enabled by BIOS, enabling counter measures\n");
#ifdef __alpha__
/* All the docs sy MUST NOT. Well, I did.
* Nothing terrible happens, if we load wrong size.
* Bit w&i still works better!
*/
tmp |= DMA_WRITE_MAX_128;
#else
switch(SMP_CACHE_BYTES) {
case 16:
tmp |= DMA_WRITE_MAX_16;
......@@ -1239,6 +1243,9 @@ static int __init ace_init(struct net_device *dev)
case 64:
tmp |= DMA_WRITE_MAX_64;
break;
case 128:
tmp |= DMA_WRITE_MAX_128;
break;
default:
printk(KERN_INFO " Cache line size %i not "
"supported, PCI write and invalidate "
......@@ -1247,7 +1254,6 @@ static int __init ace_init(struct net_device *dev)
pci_write_config_word(ap->pdev, PCI_COMMAND,
ap->pci_command);
}
#endif
}
}
......@@ -1263,12 +1269,19 @@ static int __init ace_init(struct net_device *dev)
* set will give the PCI controller proper hints about
* prefetching.
*/
tmp = tmp & ~DMA_READ_WRITE_MASK;
tmp &= ~DMA_READ_WRITE_MASK;
tmp |= DMA_READ_MAX_64;
tmp |= DMA_WRITE_MAX_64;
#endif
#ifdef __alpha__
tmp &= ~DMA_READ_WRITE_MASK;
tmp |= DMA_READ_MAX_128;
/*
* All the docs sy MUST NOT. Well, I did.
* Nothing terrible happens, if we load wrong size.
* Bit w&i still works better!
*/
tmp |= DMA_WRITE_MAX_128;
#endif
writel(tmp, &regs->PciState);
......@@ -3322,6 +3335,6 @@ static int __init read_eeprom_byte(struct net_device *dev,
/*
* Local variables:
* compile-command: "gcc -D__KERNEL__ -DMODULE -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -DMODVERSIONS -include ../../include/linux/modversions.h -c -o acenic.o acenic.c"
* compile-command: "gcc -D__SMP__ -D__KERNEL__ -DMODULE -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -DMODVERSIONS -include ../../include/linux/modversions.h -c -o acenic.o acenic.c"
* End:
*/
......@@ -207,8 +207,8 @@ typedef struct {
/*
* udelay() values for when clocking the eeprom
*/
#define ACE_SHORT_DELAY 1
#define ACE_LONG_DELAY 2
#define ACE_SHORT_DELAY 2
#define ACE_LONG_DELAY 4
/*
......
......@@ -275,8 +275,9 @@ pci_set_power_state(struct pci_dev *dev, int state)
else if (state == 2 && !(pmc & PCI_PM_CAP_D2)) return -EIO;
}
/* If we're in D3, force entire word to 0, since we can't access the
* PCI config space for the device
/* If we're in D3, force entire word to 0.
* This doesn't affect PME_Status, disables PME_En, and
* sets PowerState to 0.
*/
if (dev->current_state == 3)
pmcsr = 0;
......@@ -369,10 +370,8 @@ pci_enable_device(struct pci_dev *dev)
* @dev: PCI device to be disabled
*
* Signal to the system that the PCI device is not in use by the system
* anymore. Currently this only involves disabling PCI busmastering,
* if active.
* anymore. This only involves disabling PCI bus-mastering, if active.
*/
void
pci_disable_device(struct pci_dev *dev)
{
......@@ -405,18 +404,23 @@ int pci_enable_wake(struct pci_dev *dev, u32 state, int enable)
/* find PCI PM capability in list */
pm = pci_find_capability(dev, PCI_CAP_ID_PM);
if (!pm) return -EIO; /* this device cannot poweroff - up to bridge to cut power */
/* make sure device supports wake events (from any state) */
/* If device doesn't support PM Capabilities, but request is to disable
* wake events, it's a nop; otherwise fail */
if (!pm)
return enable ? -EIO : 0;
/* Check device's ability to generate PME# */
pci_read_config_word(dev,pm+PCI_PM_PMC,&value);
if (!(value & PCI_PM_CAP_PME_MASK)) return -EINVAL; /* doesn't support wake events */
value &= PCI_PM_CAP_PME_MASK;
value >>= ffs(value); /* First bit of mask */
/*
* XXX - We're assuming that device can generate wake events from whatever
* state it may be entering.
* We're not actually checking what state we're going into to.
*/
/* Check if it can generate PME# from requested state. */
if (!value || !(value & (1 << state)))
return enable ? -EINVAL : 0;
/* Enable PME# Generation */
pci_read_config_word(dev, pm + PCI_PM_CTRL, &value);
if (enable) value |= PCI_PM_CTRL_PME_STATUS;
......@@ -1385,6 +1389,18 @@ struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata
* easily implement them (ie just have a suspend function that calls
* the pci_set_power_state() function).
*/
static int pci_pm_save_state_device(struct pci_dev *dev, u32 state)
{
int error = 0;
if (dev) {
struct pci_driver *driver = dev->driver;
if (driver && driver->save_state)
error = driver->save_state(dev,state);
}
return error;
}
static int pci_pm_suspend_device(struct pci_dev *dev, u32 state)
{
int error = 0;
......@@ -1407,7 +1423,21 @@ static int pci_pm_resume_device(struct pci_dev *dev)
return error;
}
/* take care to suspend/resume bridges only once */
static int pci_pm_save_state_bus(struct pci_bus *bus, u32 state)
{
struct list_head *list;
int error = 0;
list_for_each(list, &bus->children) {
error = pci_pm_save_state_bus(pci_bus_b(list),state);
if (error) return error;
}
list_for_each(list, &bus->devices) {
error = pci_pm_save_state_device(pci_dev_b(list),state);
if (error) return error;
}
return 0;
}
static int pci_pm_suspend_bus(struct pci_bus *bus, u32 state)
{
......@@ -1437,6 +1467,21 @@ static int pci_pm_resume_bus(struct pci_bus *bus)
return 0;
}
static int pci_pm_save_state(u32 state)
{
struct list_head *list;
struct pci_bus *bus;
int error = 0;
list_for_each(list, &pci_root_buses) {
bus = pci_bus_b(list);
error = pci_pm_save_state_bus(bus,state);
if (!error)
error = pci_pm_save_state_device(bus->self,state);
}
return error;
}
static int pci_pm_suspend(u32 state)
{
struct list_head *list;
......@@ -1466,15 +1511,23 @@ static int pci_pm_resume(void)
static int
pci_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data)
{
int error = 0;
switch (rqst) {
case PM_SAVE_STATE:
error = pci_pm_save_state((u32)data);
break;
case PM_SUSPEND:
return pci_pm_suspend((u32)data);
error = pci_pm_suspend((u32)data);
break;
case PM_RESUME:
return pci_pm_resume();
error = pci_pm_resume();
break;
default: break;
}
return 0;
return error;
}
#endif
/*
......
......@@ -47,7 +47,6 @@ extern struct address_space_operations vxfs_immed_aops;
extern struct inode_operations vxfs_immed_symlink_iops;
static struct file_operations vxfs_file_operations = {
.llseek = generic_file_llseek,
.read = generic_file_read,
.mmap = generic_file_mmap,
};
......
......@@ -478,6 +478,7 @@ struct pci_driver {
const struct pci_device_id *id_table; /* NULL if wants all devices */
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
int (*save_state) (struct pci_dev *dev, u32 state); /* Save Device Context */
int (*suspend)(struct pci_dev *dev, u32 state); /* Device suspended */
int (*resume) (struct pci_dev *dev); /* Device woken up */
int (*enable_wake) (struct pci_dev *dev, u32 state, int enable); /* Enable wake event */
......@@ -647,6 +648,12 @@ static inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir;
static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
/* Power management related routines */
static inline int pci_save_state(struct pci_dev *dev, u32 *buffer) { return 0; }
static inline int pci_restore_state(struct pci_dev *dev, u32 *buffer) { return 0; }
static inline int pci_set_power_state(struct pci_dev *dev, int state) { return 0; }
static inline int pci_enable_wake(struct pci_dev *dev, u32 state, int enable) { return 0; }
#define pci_for_each_dev(dev) \
for(dev = NULL; 0; )
......
......@@ -34,6 +34,8 @@ enum
PM_SUSPEND, /* enter D1-D3 */
PM_RESUME, /* enter D0 */
PM_SAVE_STATE, /* save device's state */
/* enable wake-on */
PM_SET_WAKEUP,
......
......@@ -205,16 +205,6 @@ extern spinlock_t pagemap_lru_lock;
page->zone->inactive_dirty_pages++; \
}
/* Like the above, but add us after the bookmark. */
#define add_page_to_inactive_dirty_list_marker(page) { \
DEBUG_ADD_PAGE \
ZERO_PAGE_BUG \
SetPageInactiveDirty(page); \
list_add(&(page)->lru, marker_lru); \
nr_inactive_dirty_pages++; \
page->zone->inactive_dirty_pages++; \
}
#define add_page_to_inactive_clean_list(page) { \
DEBUG_ADD_PAGE \
ZERO_PAGE_BUG \
......
......@@ -426,61 +426,23 @@ struct page * reclaim_page(zone_t * zone)
#define MAX_LAUNDER (4 * (1 << page_cluster))
#define CAN_DO_IO (gfp_mask & __GFP_IO)
#define CAN_DO_BUFFERS (gfp_mask & __GFP_BUFFER)
#define marker_lru (&marker_page_struct.lru)
int page_launder(int gfp_mask, int sync)
{
static int cannot_free_pages;
int launder_loop, maxscan, cleaned_pages, maxlaunder;
struct list_head * page_lru;
struct page * page;
/* Our bookmark of where we are in the inactive_dirty list. */
struct page marker_page_struct = { zone: NULL };
launder_loop = 0;
maxlaunder = 0;
cleaned_pages = 0;
dirty_page_rescan:
spin_lock(&pagemap_lru_lock);
/*
* By not scanning all inactive dirty pages we'll write out
* really old dirty pages before evicting newer clean pages.
* This should cause some LRU behaviour if we have a large
* amount of inactive pages (due to eg. drop behind).
*
* It also makes us accumulate dirty pages until we have enough
* to be worth writing to disk without causing excessive disk
* seeks and eliminates the infinite penalty clean pages incurred
* vs. dirty pages.
*/
maxscan = nr_inactive_dirty_pages / 4;
if (launder_loop)
maxscan *= 2;
list_add_tail(marker_lru, &inactive_dirty_list);
for (;;) {
page_lru = marker_lru->prev;
if (page_lru == &inactive_dirty_list)
break;
if (--maxscan < 0)
break;
if (!free_shortage())
break;
maxscan = nr_inactive_dirty_pages;
while ((page_lru = inactive_dirty_list.prev) != &inactive_dirty_list &&
maxscan-- > 0) {
page = list_entry(page_lru, struct page, lru);
/* Move the bookmark backwards.. */
list_del(marker_lru);
list_add_tail(marker_lru, page_lru);
/* Don't waste CPU if chances are we cannot free anything. */
if (launder_loop && maxlaunder < 0 && cannot_free_pages)
break;
/* Skip other people's marker pages. */
if (!page->zone)
continue;
/* Wrong page on list?! (list corruption, should not happen) */
if (!PageInactiveDirty(page)) {
printk("VM: page_launder, wrong page on list.\n");
......@@ -501,9 +463,11 @@ int page_launder(int gfp_mask, int sync)
/*
* The page is locked. IO in progress?
* Skip the page, we'll take a look when it unlocks.
* Move it to the back of the list.
*/
if (TryLockPage(page)) {
list_del(page_lru);
list_add(page_lru, &inactive_dirty_list);
continue;
}
......@@ -517,8 +481,10 @@ int page_launder(int gfp_mask, int sync)
if (!writepage)
goto page_active;
/* First time through? Skip the page. */
/* First time through? Move it to the back of the list */
if (!launder_loop || !CAN_DO_IO) {
list_del(page_lru);
list_add(page_lru, &inactive_dirty_list);
UnlockPage(page);
continue;
}
......@@ -531,8 +497,6 @@ int page_launder(int gfp_mask, int sync)
writepage(page);
page_cache_release(page);
maxlaunder--;
/* And re-start the thing.. */
spin_lock(&pagemap_lru_lock);
continue;
......@@ -560,12 +524,13 @@ int page_launder(int gfp_mask, int sync)
spin_unlock(&pagemap_lru_lock);
/* Will we do (asynchronous) IO? */
if (launder_loop && maxlaunder-- == 0 && sync)
wait = 0; /* No IO */
if (launder_loop) {
if (maxlaunder == 0 && sync)
wait = 2; /* Synchrounous IO */
else if (launder_loop && maxlaunder > 0)
else if (maxlaunder-- > 0)
wait = 1; /* Async IO */
else
wait = 0; /* No IO */
}
/* Try to free the page buffers. */
clearedbuf = try_to_free_buffers(page, wait);
......@@ -579,7 +544,7 @@ int page_launder(int gfp_mask, int sync)
/* The buffers were not freed. */
if (!clearedbuf) {
add_page_to_inactive_dirty_list_marker(page);
add_page_to_inactive_dirty_list(page);
/* The page was only in the buffer cache. */
} else if (!page->mapping) {
......@@ -635,8 +600,6 @@ int page_launder(int gfp_mask, int sync)
UnlockPage(page);
}
}
/* Remove our marker. */
list_del(marker_lru);
spin_unlock(&pagemap_lru_lock);
/*
......@@ -652,29 +615,16 @@ int page_launder(int gfp_mask, int sync)
*/
if ((CAN_DO_IO || CAN_DO_BUFFERS) && !launder_loop && free_shortage()) {
launder_loop = 1;
/*
* If we, or the previous process running page_launder(),
* managed to free any pages we never do synchronous IO.
*/
if (cleaned_pages || !cannot_free_pages)
/* If we cleaned pages, never do synchronous IO. */
if (cleaned_pages)
sync = 0;
/* Else, do synchronous IO (if we are allowed to). */
else if (sync)
sync = 1;
/* We only do a few "out of order" flushes. */
maxlaunder = MAX_LAUNDER;
/* Let bdflush take care of the rest. */
/* Kflushd takes care of the rest. */
wakeup_bdflush(0);
goto dirty_page_rescan;
}
/*
* If we failed to free pages (because all pages are dirty)
* we remember this for the next time. This will prevent us
* from wasting too much CPU here.
*/
cannot_free_pages = !cleaned_pages;
/* Return the number of pages moved to the inactive_clean list. */
return cleaned_pages;
}
......@@ -902,7 +852,7 @@ static int do_try_to_free_pages(unsigned int gfp_mask, int user)
* list, so this is a relatively cheap operation.
*/
if (free_shortage()) {
ret += page_launder(gfp_mask, 1);
ret += page_launder(gfp_mask, user);
shrink_dcache_memory(DEF_PRIORITY, gfp_mask);
shrink_icache_memory(DEF_PRIORITY, gfp_mask);
}
......
......@@ -2633,7 +2633,7 @@ static int wanpipe_connect(struct socket *sock, struct sockaddr *uaddr, int addr
return -EINVAL;
if (sk->state == WANSOCK_CONNECTED)
return EISCONN; /* No reconnect on a seqpacket socket */
return -EISCONN; /* No reconnect on a seqpacket socket */
if (sk->state != WAN_DISCONNECTED){
printk(KERN_INFO "wansock: Trying to connect on channel NON DISCONNECT\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment