提交 c4c0c56a 编写于 作者: I Ingo Molnar

Merge branch 'linus' into core/rcu

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
...@@ -317,6 +317,14 @@ S: 2322 37th Ave SW ...@@ -317,6 +317,14 @@ S: 2322 37th Ave SW
S: Seattle, Washington 98126-2010 S: Seattle, Washington 98126-2010
S: USA S: USA
N: Muli Ben-Yehuda
E: mulix@mulix.org
E: muli@il.ibm.com
W: http://www.mulix.org
D: trident OSS sound driver, x86-64 dma-ops and Calgary IOMMU,
D: KVM and Xen bits and other misc. hackery.
S: Haifa, Israel
N: Johannes Berg N: Johannes Berg
E: johannes@sipsolutions.net E: johannes@sipsolutions.net
W: http://johannes.sipsolutions.net/ W: http://johannes.sipsolutions.net/
...@@ -3344,8 +3352,7 @@ S: Spain ...@@ -3344,8 +3352,7 @@ S: Spain
N: Linus Torvalds N: Linus Torvalds
E: torvalds@linux-foundation.org E: torvalds@linux-foundation.org
D: Original kernel hacker D: Original kernel hacker
S: 12725 SW Millikan Way, Suite 400 S: Portland, Oregon 97005
S: Beaverton, Oregon 97005
S: USA S: USA
N: Marcelo Tosatti N: Marcelo Tosatti
......
...@@ -89,8 +89,6 @@ cciss.txt ...@@ -89,8 +89,6 @@ cciss.txt
- info, major/minor #'s for Compaq's SMART Array Controllers. - info, major/minor #'s for Compaq's SMART Array Controllers.
cdrom/ cdrom/
- directory with information on the CD-ROM drivers that Linux has. - directory with information on the CD-ROM drivers that Linux has.
cli-sti-removal.txt
- cli()/sti() removal guide.
computone.txt computone.txt
- info on Computone Intelliport II/Plus Multiport Serial Driver. - info on Computone Intelliport II/Plus Multiport Serial Driver.
connector/ connector/
...@@ -361,8 +359,6 @@ telephony/ ...@@ -361,8 +359,6 @@ telephony/
- directory with info on telephony (e.g. voice over IP) support. - directory with info on telephony (e.g. voice over IP) support.
time_interpolators.txt time_interpolators.txt
- info on time interpolators. - info on time interpolators.
tipar.txt
- information about Parallel link cable for Texas Instruments handhelds.
tty.txt tty.txt
- guide to the locking policies of the tty layer. - guide to the locking policies of the tty layer.
uml/ uml/
......
What: /sys/class/regulator/.../state
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
state. This holds the regulator output state.
This will be one of the following strings:
'enabled'
'disabled'
'unknown'
'enabled' means the regulator output is ON and is supplying
power to the system.
'disabled' means the regulator output is OFF and is not
supplying power to the system..
'unknown' means software cannot determine the state.
NOTE: this field can be used in conjunction with microvolts
and microamps to determine regulator output levels.
What: /sys/class/regulator/.../type
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
type. This holds the regulator type.
This will be one of the following strings:
'voltage'
'current'
'unknown'
'voltage' means the regulator output voltage can be controlled
by software.
'current' means the regulator output current limit can be
controlled by software.
'unknown' means software cannot control either voltage or
current limit.
What: /sys/class/regulator/.../microvolts
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
microvolts. This holds the regulator output voltage setting
measured in microvolts (i.e. E-6 Volts).
NOTE: This value should not be used to determine the regulator
output voltage level as this value is the same regardless of
whether the regulator is enabled or disabled.
What: /sys/class/regulator/.../microamps
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
microamps. This holds the regulator output current limit
setting measured in microamps (i.e. E-6 Amps).
NOTE: This value should not be used to determine the regulator
output current level as this value is the same regardless of
whether the regulator is enabled or disabled.
What: /sys/class/regulator/.../opmode
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
opmode. This holds the regulator operating mode setting.
The opmode value can be one of the following strings:
'fast'
'normal'
'idle'
'standby'
'unknown'
The modes are described in include/linux/regulator/regulator.h
NOTE: This value should not be used to determine the regulator
output operating mode as this value is the same regardless of
whether the regulator is enabled or disabled.
What: /sys/class/regulator/.../min_microvolts
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
min_microvolts. This holds the minimum safe working regulator
output voltage setting for this domain measured in microvolts.
NOTE: this will return the string 'constraint not defined' if
the power domain has no min microvolts constraint defined by
platform code.
What: /sys/class/regulator/.../max_microvolts
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
max_microvolts. This holds the maximum safe working regulator
output voltage setting for this domain measured in microvolts.
NOTE: this will return the string 'constraint not defined' if
the power domain has no max microvolts constraint defined by
platform code.
What: /sys/class/regulator/.../min_microamps
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
min_microamps. This holds the minimum safe working regulator
output current limit setting for this domain measured in
microamps.
NOTE: this will return the string 'constraint not defined' if
the power domain has no min microamps constraint defined by
platform code.
What: /sys/class/regulator/.../max_microamps
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
max_microamps. This holds the maximum safe working regulator
output current limit setting for this domain measured in
microamps.
NOTE: this will return the string 'constraint not defined' if
the power domain has no max microamps constraint defined by
platform code.
What: /sys/class/regulator/.../num_users
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
num_users. This holds the number of consumer devices that
have called regulator_enable() on this regulator.
What: /sys/class/regulator/.../requested_microamps
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
requested_microamps. This holds the total requested load
current in microamps for this regulator from all its consumer
devices.
What: /sys/class/regulator/.../parent
Date: April 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Some regulator directories will contain a link called parent.
This points to the parent or supply regulator if one exists.
What: /sys/class/regulator/.../suspend_mem_microvolts
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_mem_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when
the system is suspended to memory.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to memory voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_disk_microvolts
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_disk_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when
the system is suspended to disk.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to disk voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_standby_microvolts
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_standby_microvolts. This holds the regulator output
voltage setting for this domain measured in microvolts when
the system is suspended to standby.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to standby voltage defined by
platform code.
What: /sys/class/regulator/.../suspend_mem_mode
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_mem_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to
memory.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to memory mode defined by
platform code.
What: /sys/class/regulator/.../suspend_disk_mode
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_disk_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to disk.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to disk mode defined by
platform code.
What: /sys/class/regulator/.../suspend_standby_mode
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_standby_mode. This holds the regulator operating mode
setting for this domain when the system is suspended to
standby.
NOTE: this will return the string 'not defined' if
the power domain has no suspend to standby mode defined by
platform code.
What: /sys/class/regulator/.../suspend_mem_state
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_mem_state. This holds the regulator operating state
when suspended to memory.
This will be one of the following strings:
'enabled'
'disabled'
'not defined'
What: /sys/class/regulator/.../suspend_disk_state
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_disk_state. This holds the regulator operating state
when suspended to disk.
This will be one of the following strings:
'enabled'
'disabled'
'not defined'
What: /sys/class/regulator/.../suspend_standby_state
Date: May 2008
KernelVersion: 2.6.26
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Description:
Each regulator directory will contain a field called
suspend_standby_state. This holds the regulator operating
state when suspended to standby.
This will be one of the following strings:
'enabled'
'disabled'
'not defined'
What: /sys/dev
Date: April 2008
KernelVersion: 2.6.26
Contact: Dan Williams <dan.j.williams@intel.com>
Description: The /sys/dev tree provides a method to look up the sysfs
path for a device using the information returned from
stat(2). There are two directories, 'block' and 'char',
beneath /sys/dev containing symbolic links with names of
the form "<major>:<minor>". These links point to the
corresponding sysfs path for the given device.
Example:
$ readlink /sys/dev/block/8:32
../../block/sdc
Entries in /sys/dev/char and /sys/dev/block will be
dynamically created and destroyed as devices enter and
leave the system.
Users: mdadm <linux-raid@vger.kernel.org>
What: /sys/devices/system/memory
Date: June 2008
Contact: Badari Pulavarty <pbadari@us.ibm.com>
Description:
The /sys/devices/system/memory contains a snapshot of the
internal state of the kernel memory blocks. Files could be
added or removed dynamically to represent hot-add/remove
operations.
Users: hotplug memory add/remove tools
https://w3.opensource.ibm.com/projects/powerpc-utils/
What: /sys/devices/system/memory/memoryX/removable
Date: June 2008
Contact: Badari Pulavarty <pbadari@us.ibm.com>
Description:
The file /sys/devices/system/memory/memoryX/removable
indicates whether this memory block is removable or not.
This is useful for a user-level agent to determine
identify removable sections of the memory before attempting
potentially expensive hot-remove memory operation
Users: hotplug memory remove tools
https://w3.opensource.ibm.com/projects/powerpc-utils/
What: /sys/kernel/mm
Date: July 2008
Contact: Nishanth Aravamudan <nacc@us.ibm.com>, VM maintainers
Description:
/sys/kernel/mm/ should contain any and all VM
related information in /sys/kernel/.
What: /sys/kernel/mm/hugepages/
Date: June 2008
Contact: Nishanth Aravamudan <nacc@us.ibm.com>, hugetlb maintainers
Description:
/sys/kernel/mm/hugepages/ contains a number of subdirectories
of the form hugepages-<size>kB, where <size> is the page size
of the hugepages supported by the kernel/CPU combination.
Under these directories are a number of files:
nr_hugepages
nr_overcommit_hugepages
free_hugepages
surplus_hugepages
resv_hugepages
See Documentation/vm/hugetlbpage.txt for details.
...@@ -474,25 +474,29 @@ make a good program). ...@@ -474,25 +474,29 @@ make a good program).
So, you can either get rid of GNU emacs, or change it to use saner So, you can either get rid of GNU emacs, or change it to use saner
values. To do the latter, you can stick the following in your .emacs file: values. To do the latter, you can stick the following in your .emacs file:
(defun linux-c-mode () (defun c-lineup-arglist-tabs-only (ignored)
"C mode with adjusted defaults for use with the Linux kernel." "Line up argument lists by tabs, not spaces"
(interactive) (let* ((anchor (c-langelem-pos c-syntactic-element))
(c-mode) (column (c-langelem-2nd-pos c-syntactic-element))
(c-set-style "K&R") (offset (- (1+ column) anchor))
(setq tab-width 8) (steps (floor offset c-basic-offset)))
(setq indent-tabs-mode t) (* (max steps 1)
(setq c-basic-offset 8)) c-basic-offset)))
This will define the M-x linux-c-mode command. When hacking on a (add-hook 'c-mode-hook
module, if you put the string -*- linux-c -*- somewhere on the first (lambda ()
two lines, this mode will be automatically invoked. Also, you may want (let ((filename (buffer-file-name)))
to add ;; Enable kernel mode for the appropriate files
(when (and filename
(setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode) (string-match "~/src/linux-trees" filename))
auto-mode-alist)) (setq indent-tabs-mode t)
(c-set-style "linux")
to your .emacs file if you want to have linux-c-mode switched on (c-set-offset 'arglist-cont-nonempty
automagically when you edit source files under /usr/src/linux. '(c-lineup-gcc-asm-reg
c-lineup-arglist-tabs-only))))))
This will make emacs go better with the kernel coding style for C
files below ~/src/linux-trees.
But even if you fail in getting emacs to do sane formatting, not But even if you fail in getting emacs to do sane formatting, not
everything is lost: use "indent". everything is lost: use "indent".
......
...@@ -298,10 +298,10 @@ recommended that you never use these unless you really know what the ...@@ -298,10 +298,10 @@ recommended that you never use these unless you really know what the
cache width is. cache width is.
int int
dma_mapping_error(dma_addr_t dma_addr) dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
int int
pci_dma_mapping_error(dma_addr_t dma_addr) pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr)
In some circumstances dma_map_single and dma_map_page will fail to create In some circumstances dma_map_single and dma_map_page will fail to create
a mapping. A driver can check for these errors by testing the returned a mapping. A driver can check for these errors by testing the returned
......
...@@ -22,3 +22,12 @@ ready and available in memory. The DMA of the "completion indication" ...@@ -22,3 +22,12 @@ ready and available in memory. The DMA of the "completion indication"
could race with data DMA. Mapping the memory used for completion could race with data DMA. Mapping the memory used for completion
indications with DMA_ATTR_WRITE_BARRIER would prevent the race. indications with DMA_ATTR_WRITE_BARRIER would prevent the race.
DMA_ATTR_WEAK_ORDERING
----------------------
DMA_ATTR_WEAK_ORDERING specifies that reads and writes to the mapping
may be weakly ordered, that is that reads and writes may pass each other.
Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING,
those that do not will simply ignore the attribute and exhibit default
behavior.
...@@ -12,7 +12,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ ...@@ -12,7 +12,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
mac80211.xml debugobjects.xml mac80211.xml debugobjects.xml sh.xml
### ###
# The build process is as follows (targets): # The build process is as follows (targets):
......
...@@ -524,6 +524,44 @@ These utilities include endpoint autoconfiguration. ...@@ -524,6 +524,44 @@ These utilities include endpoint autoconfiguration.
<!-- !Edrivers/usb/gadget/epautoconf.c --> <!-- !Edrivers/usb/gadget/epautoconf.c -->
</sect1> </sect1>
<sect1 id="composite"><title>Composite Device Framework</title>
<para>The core API is sufficient for writing drivers for composite
USB devices (with more than one function in a given configuration),
and also multi-configuration devices (also more than one function,
but not necessarily sharing a given configuration).
There is however an optional framework which makes it easier to
reuse and combine functions.
</para>
<para>Devices using this framework provide a <emphasis>struct
usb_composite_driver</emphasis>, which in turn provides one or
more <emphasis>struct usb_configuration</emphasis> instances.
Each such configuration includes at least one
<emphasis>struct usb_function</emphasis>, which packages a user
visible role such as "network link" or "mass storage device".
Management functions may also exist, such as "Device Firmware
Upgrade".
</para>
!Iinclude/linux/usb/composite.h
!Edrivers/usb/gadget/composite.c
</sect1>
<sect1 id="functions"><title>Composite Device Functions</title>
<para>At this writing, a few of the current gadget drivers have
been converted to this framework.
Near-term plans include converting all of them, except for "gadgetfs".
</para>
!Edrivers/usb/gadget/f_acm.c
!Edrivers/usb/gadget/f_serial.c
</sect1>
</chapter> </chapter>
<chapter id="controllers"><title>Peripheral Controller Drivers</title> <chapter id="controllers"><title>Peripheral Controller Drivers</title>
......
...@@ -219,10 +219,10 @@ ...@@ -219,10 +219,10 @@
</para> </para>
<sect1 id="lock-intro"> <sect1 id="lock-intro">
<title>Three Main Types of Kernel Locks: Spinlocks, Mutexes and Semaphores</title> <title>Two Main Types of Kernel Locks: Spinlocks and Mutexes</title>
<para> <para>
There are three main types of kernel locks. The fundamental type There are two main types of kernel locks. The fundamental type
is the spinlock is the spinlock
(<filename class="headerfile">include/asm/spinlock.h</filename>), (<filename class="headerfile">include/asm/spinlock.h</filename>),
which is a very simple single-holder lock: if you can't get the which is a very simple single-holder lock: if you can't get the
...@@ -239,14 +239,6 @@ ...@@ -239,14 +239,6 @@
can't sleep (see <xref linkend="sleeping-things"/>), and so have to can't sleep (see <xref linkend="sleeping-things"/>), and so have to
use a spinlock instead. use a spinlock instead.
</para> </para>
<para>
The third type is a semaphore
(<filename class="headerfile">include/linux/semaphore.h</filename>): it
can have more than one holder at any time (the number decided at
initialization time), although it is most commonly used as a
single-holder lock (a mutex). If you can't get a semaphore, your
task will be suspended and later on woken up - just like for mutexes.
</para>
<para> <para>
Neither type of lock is recursive: see Neither type of lock is recursive: see
<xref linkend="deadlock"/>. <xref linkend="deadlock"/>.
...@@ -278,7 +270,7 @@ ...@@ -278,7 +270,7 @@
</para> </para>
<para> <para>
Semaphores still exist, because they are required for Mutexes still exist, because they are required for
synchronization between <firstterm linkend="gloss-usercontext">user synchronization between <firstterm linkend="gloss-usercontext">user
contexts</firstterm>, as we will see below. contexts</firstterm>, as we will see below.
</para> </para>
...@@ -289,18 +281,17 @@ ...@@ -289,18 +281,17 @@
<para> <para>
If you have a data structure which is only ever accessed from If you have a data structure which is only ever accessed from
user context, then you can use a simple semaphore user context, then you can use a simple mutex
(<filename>linux/linux/semaphore.h</filename>) to protect it. This (<filename>include/linux/mutex.h</filename>) to protect it. This
is the most trivial case: you initialize the semaphore to the number is the most trivial case: you initialize the mutex. Then you can
of resources available (usually 1), and call call <function>mutex_lock_interruptible()</function> to grab the mutex,
<function>down_interruptible()</function> to grab the semaphore, and and <function>mutex_unlock()</function> to release it. There is also a
<function>up()</function> to release it. There is also a <function>mutex_lock()</function>, which should be avoided, because it
<function>down()</function>, which should be avoided, because it
will not return if a signal is received. will not return if a signal is received.
</para> </para>
<para> <para>
Example: <filename>linux/net/core/netfilter.c</filename> allows Example: <filename>net/netfilter/nf_sockopt.c</filename> allows
registration of new <function>setsockopt()</function> and registration of new <function>setsockopt()</function> and
<function>getsockopt()</function> calls, with <function>getsockopt()</function> calls, with
<function>nf_register_sockopt()</function>. Registration and <function>nf_register_sockopt()</function>. Registration and
...@@ -515,7 +506,7 @@ ...@@ -515,7 +506,7 @@
<listitem> <listitem>
<para> <para>
If you are in a process context (any syscall) and want to If you are in a process context (any syscall) and want to
lock other process out, use a semaphore. You can take a semaphore lock other process out, use a mutex. You can take a mutex
and sleep (<function>copy_from_user*(</function> or and sleep (<function>copy_from_user*(</function> or
<function>kmalloc(x,GFP_KERNEL)</function>). <function>kmalloc(x,GFP_KERNEL)</function>).
</para> </para>
...@@ -662,7 +653,7 @@ ...@@ -662,7 +653,7 @@
<entry>SLBH</entry> <entry>SLBH</entry>
<entry>SLBH</entry> <entry>SLBH</entry>
<entry>SLBH</entry> <entry>SLBH</entry>
<entry>DI</entry> <entry>MLI</entry>
<entry>None</entry> <entry>None</entry>
</row> </row>
...@@ -692,8 +683,8 @@ ...@@ -692,8 +683,8 @@
<entry>spin_lock_bh</entry> <entry>spin_lock_bh</entry>
</row> </row>
<row> <row>
<entry>DI</entry> <entry>MLI</entry>
<entry>down_interruptible</entry> <entry>mutex_lock_interruptible</entry>
</row> </row>
</tbody> </tbody>
...@@ -1310,7 +1301,7 @@ as Alan Cox says, <quote>Lock data, not code</quote>. ...@@ -1310,7 +1301,7 @@ as Alan Cox says, <quote>Lock data, not code</quote>.
<para> <para>
There is a coding bug where a piece of code tries to grab a There is a coding bug where a piece of code tries to grab a
spinlock twice: it will spin forever, waiting for the lock to spinlock twice: it will spin forever, waiting for the lock to
be released (spinlocks, rwlocks and semaphores are not be released (spinlocks, rwlocks and mutexes are not
recursive in Linux). This is trivial to diagnose: not a recursive in Linux). This is trivial to diagnose: not a
stay-up-five-nights-talk-to-fluffy-code-bunnies kind of stay-up-five-nights-talk-to-fluffy-code-bunnies kind of
problem. problem.
...@@ -1335,7 +1326,7 @@ as Alan Cox says, <quote>Lock data, not code</quote>. ...@@ -1335,7 +1326,7 @@ as Alan Cox says, <quote>Lock data, not code</quote>.
<para> <para>
This complete lockup is easy to diagnose: on SMP boxes the This complete lockup is easy to diagnose: on SMP boxes the
watchdog timer or compiling with <symbol>DEBUG_SPINLOCKS</symbol> set watchdog timer or compiling with <symbol>DEBUG_SPINLOCK</symbol> set
(<filename>include/linux/spinlock.h</filename>) will show this up (<filename>include/linux/spinlock.h</filename>) will show this up
immediately when it happens. immediately when it happens.
</para> </para>
...@@ -1558,7 +1549,7 @@ the amount of locking which needs to be done. ...@@ -1558,7 +1549,7 @@ the amount of locking which needs to be done.
<title>Read/Write Lock Variants</title> <title>Read/Write Lock Variants</title>
<para> <para>
Both spinlocks and semaphores have read/write variants: Both spinlocks and mutexes have read/write variants:
<type>rwlock_t</type> and <structname>struct rw_semaphore</structname>. <type>rwlock_t</type> and <structname>struct rw_semaphore</structname>.
These divide users into two classes: the readers and the writers. If These divide users into two classes: the readers and the writers. If
you are only reading the data, you can get a read lock, but to write to you are only reading the data, you can get a read lock, but to write to
...@@ -1681,7 +1672,7 @@ the amount of locking which needs to be done. ...@@ -1681,7 +1672,7 @@ the amount of locking which needs to be done.
#include &lt;linux/slab.h&gt; #include &lt;linux/slab.h&gt;
#include &lt;linux/string.h&gt; #include &lt;linux/string.h&gt;
+#include &lt;linux/rcupdate.h&gt; +#include &lt;linux/rcupdate.h&gt;
#include &lt;linux/semaphore.h&gt; #include &lt;linux/mutex.h&gt;
#include &lt;asm/errno.h&gt; #include &lt;asm/errno.h&gt;
struct object struct object
...@@ -1913,7 +1904,7 @@ machines due to caching. ...@@ -1913,7 +1904,7 @@ machines due to caching.
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<function> put_user()</function> <function>put_user()</function>
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
...@@ -1927,13 +1918,13 @@ machines due to caching. ...@@ -1927,13 +1918,13 @@ machines due to caching.
<listitem> <listitem>
<para> <para>
<function>down_interruptible()</function> and <function>mutex_lock_interruptible()</function> and
<function>down()</function> <function>mutex_lock()</function>
</para> </para>
<para> <para>
There is a <function>down_trylock()</function> which can be There is a <function>mutex_trylock()</function> which can be
used inside interrupt context, as it will not sleep. used inside interrupt context, as it will not sleep.
<function>up()</function> will also never sleep. <function>mutex_unlock()</function> will also never sleep.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
...@@ -2023,7 +2014,7 @@ machines due to caching. ...@@ -2023,7 +2014,7 @@ machines due to caching.
<para> <para>
Prior to 2.5, or when <symbol>CONFIG_PREEMPT</symbol> is Prior to 2.5, or when <symbol>CONFIG_PREEMPT</symbol> is
unset, processes in user context inside the kernel would not unset, processes in user context inside the kernel would not
preempt each other (ie. you had that CPU until you have it up, preempt each other (ie. you had that CPU until you gave it up,
except for interrupts). With the addition of except for interrupts). With the addition of
<symbol>CONFIG_PREEMPT</symbol> in 2.5.4, this changed: when <symbol>CONFIG_PREEMPT</symbol> in 2.5.4, this changed: when
in user context, higher priority tasks can "cut in": spinlocks in user context, higher priority tasks can "cut in": spinlocks
......
...@@ -98,6 +98,24 @@ ...@@ -98,6 +98,24 @@
"Kernel debugging" select "KGDB: kernel debugging with remote gdb". "Kernel debugging" select "KGDB: kernel debugging with remote gdb".
</para> </para>
<para> <para>
It is advised, but not required that you turn on the
CONFIG_FRAME_POINTER kernel option. This option inserts code to
into the compiled executable which saves the frame information in
registers or on the stack at different points which will allow a
debugger such as gdb to more accurately construct stack back traces
while debugging the kernel.
</para>
<para>
If the architecture that you are using supports the kernel option
CONFIG_DEBUG_RODATA, you should consider turning it off. This
option will prevent the use of software breakpoints because it
marks certain regions of the kernel's memory space as read-only.
If kgdb supports it for the architecture you are using, you can
use hardware breakpoints if you desire to run with the
CONFIG_DEBUG_RODATA option turned on, else you need to turn off
this option.
</para>
<para>
Next you should choose one of more I/O drivers to interconnect debugging Next you should choose one of more I/O drivers to interconnect debugging
host and debugged target. Early boot debugging requires a KGDB host and debugged target. Early boot debugging requires a KGDB
I/O driver that supports early debugging and the driver must be I/O driver that supports early debugging and the driver must be
......
...@@ -29,12 +29,12 @@ ...@@ -29,12 +29,12 @@
<revhistory> <revhistory>
<revision> <revision>
<revnumber>1.0&nbsp;</revnumber> <revnumber>1.0</revnumber>
<date>May 30, 2001</date> <date>May 30, 2001</date>
<revremark>Initial revision posted to linux-kernel</revremark> <revremark>Initial revision posted to linux-kernel</revremark>
</revision> </revision>
<revision> <revision>
<revnumber>1.1&nbsp;</revnumber> <revnumber>1.1</revnumber>
<date>June 3, 2001</date> <date>June 3, 2001</date>
<revremark>Revised after comments from linux-kernel</revremark> <revremark>Revised after comments from linux-kernel</revremark>
</revision> </revision>
......
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
the hardware structures represented here, please consult the Principles the hardware structures represented here, please consult the Principles
of Operation. of Operation.
</para> </para>
!Iinclude/asm-s390/cio.h !Iarch/s390/include/asm/cio.h
</sect1> </sect1>
<sect1 id="ccwdev"> <sect1 id="ccwdev">
<title>ccw devices</title> <title>ccw devices</title>
...@@ -114,7 +114,7 @@ ...@@ -114,7 +114,7 @@
ccw device structure. Device drivers must not bypass those functions ccw device structure. Device drivers must not bypass those functions
or strange side effects may happen. or strange side effects may happen.
</para> </para>
!Iinclude/asm-s390/ccwdev.h !Iarch/s390/include/asm/ccwdev.h
!Edrivers/s390/cio/device.c !Edrivers/s390/cio/device.c
!Edrivers/s390/cio/device_ops.c !Edrivers/s390/cio/device_ops.c
</sect1> </sect1>
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
measurement data which is made available by the channel subsystem measurement data which is made available by the channel subsystem
for each channel attached device. for each channel attached device.
</para> </para>
!Iinclude/asm-s390/cmb.h !Iarch/s390/include/asm/cmb.h
!Edrivers/s390/cio/cmf.c !Edrivers/s390/cio/cmf.c
</sect1> </sect1>
</chapter> </chapter>
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
</para> </para>
<sect1 id="ccwgroupdevices"> <sect1 id="ccwgroupdevices">
<title>ccw group devices</title> <title>ccw group devices</title>
!Iinclude/asm-s390/ccwgroup.h !Iarch/s390/include/asm/ccwgroup.h
!Edrivers/s390/cio/ccwgroup.c !Edrivers/s390/cio/ccwgroup.c
</sect1> </sect1>
</chapter> </chapter>
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<book id="sh-drivers">
<bookinfo>
<title>SuperH Interfaces Guide</title>
<authorgroup>
<author>
<firstname>Paul</firstname>
<surname>Mundt</surname>
<affiliation>
<address>
<email>lethal@linux-sh.org</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2008</year>
<holder>Paul Mundt</holder>
</copyright>
<copyright>
<year>2008</year>
<holder>Renesas Technology Corp.</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License version 2 as published by the Free Software Foundation.
</para>
<para>
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc></toc>
<chapter id="mm">
<title>Memory Management</title>
<sect1 id="sh4">
<title>SH-4</title>
<sect2 id="sq">
<title>Store Queue API</title>
!Earch/sh/kernel/cpu/sh4/sq.c
</sect2>
</sect1>
<sect1 id="sh5">
<title>SH-5</title>
<sect2 id="tlb">
<title>TLB Interfaces</title>
!Iarch/sh/mm/tlb-sh5.c
!Iarch/sh/include/asm/tlb_64.h
</sect2>
</sect1>
</chapter>
<chapter id="clk">
<title>Clock Framework Extensions</title>
!Iarch/sh/include/asm/clock.h
</chapter>
<chapter id="mach">
<title>Machine Specific Interfaces</title>
<sect1 id="dreamcast">
<title>mach-dreamcast</title>
!Iarch/sh/boards/mach-dreamcast/rtc.c
</sect1>
<sect1 id="x3proto">
<title>mach-x3proto</title>
!Earch/sh/boards/mach-x3proto/ilsel.c
</sect1>
</chapter>
<chapter id="busses">
<title>Busses</title>
<sect1 id="superhyway">
<title>SuperHyway</title>
!Edrivers/sh/superhyway/superhyway.c
</sect1>
<sect1 id="maple">
<title>Maple</title>
!Edrivers/sh/maple/maple.c
</sect1>
</chapter>
</book>
...@@ -21,6 +21,18 @@ ...@@ -21,6 +21,18 @@
</affiliation> </affiliation>
</author> </author>
<copyright>
<year>2006-2008</year>
<holder>Hans-Jürgen Koch.</holder>
</copyright>
<legalnotice>
<para>
This documentation is Free Software licensed under the terms of the
GPL version 2.
</para>
</legalnotice>
<pubdate>2006-12-11</pubdate> <pubdate>2006-12-11</pubdate>
<abstract> <abstract>
...@@ -29,6 +41,12 @@ ...@@ -29,6 +41,12 @@
</abstract> </abstract>
<revhistory> <revhistory>
<revision>
<revnumber>0.5</revnumber>
<date>2008-05-22</date>
<authorinitials>hjk</authorinitials>
<revremark>Added description of write() function.</revremark>
</revision>
<revision> <revision>
<revnumber>0.4</revnumber> <revnumber>0.4</revnumber>
<date>2007-11-26</date> <date>2007-11-26</date>
...@@ -57,20 +75,9 @@ ...@@ -57,20 +75,9 @@
</bookinfo> </bookinfo>
<chapter id="aboutthisdoc"> <chapter id="aboutthisdoc">
<?dbhtml filename="about.html"?> <?dbhtml filename="aboutthis.html"?>
<title>About this document</title> <title>About this document</title>
<sect1 id="copyright">
<?dbhtml filename="copyright.html"?>
<title>Copyright and License</title>
<para>
Copyright (c) 2006 by Hans-Jürgen Koch.</para>
<para>
This documentation is Free Software licensed under the terms of the
GPL version 2.
</para>
</sect1>
<sect1 id="translations"> <sect1 id="translations">
<?dbhtml filename="translations.html"?> <?dbhtml filename="translations.html"?>
<title>Translations</title> <title>Translations</title>
...@@ -189,6 +196,30 @@ interested in translating it, please email me ...@@ -189,6 +196,30 @@ interested in translating it, please email me
represents the total interrupt count. You can use this number represents the total interrupt count. You can use this number
to figure out if you missed some interrupts. to figure out if you missed some interrupts.
</para> </para>
<para>
For some hardware that has more than one interrupt source internally,
but not separate IRQ mask and status registers, there might be
situations where userspace cannot determine what the interrupt source
was if the kernel handler disables them by writing to the chip's IRQ
register. In such a case, the kernel has to disable the IRQ completely
to leave the chip's register untouched. Now the userspace part can
determine the cause of the interrupt, but it cannot re-enable
interrupts. Another cornercase is chips where re-enabling interrupts
is a read-modify-write operation to a combined IRQ status/acknowledge
register. This would be racy if a new interrupt occurred
simultaneously.
</para>
<para>
To address these problems, UIO also implements a write() function. It
is normally not used and can be ignored for hardware that has only a
single interrupt source or has separate IRQ mask and status registers.
If you need it, however, a write to <filename>/dev/uioX</filename>
will call the <function>irqcontrol()</function> function implemented
by the driver. You have to write a 32-bit value that is usually either
0 or 1 to disable or enable interrupts. If a driver does not implement
<function>irqcontrol()</function>, <function>write()</function> will
return with <varname>-ENOSYS</varname>.
</para>
<para> <para>
To handle interrupts properly, your custom kernel module can To handle interrupts properly, your custom kernel module can
...@@ -362,6 +393,14 @@ device is actually used. ...@@ -362,6 +393,14 @@ device is actually used.
<function>open()</function>, you will probably also want a custom <function>open()</function>, you will probably also want a custom
<function>release()</function> function. <function>release()</function> function.
</para></listitem> </para></listitem>
<listitem><para>
<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on)
</varname>: Optional. If you need to be able to enable or disable
interrupts from userspace by writing to <filename>/dev/uioX</filename>,
you can implement this function. The parameter <varname>irq_on</varname>
will be 0 to disable interrupts and 1 to enable them.
</para></listitem>
</itemizedlist> </itemizedlist>
<para> <para>
......
...@@ -1648,7 +1648,7 @@ static struct video_buffer capture_fb; ...@@ -1648,7 +1648,7 @@ static struct video_buffer capture_fb;
<chapter id="pubfunctions"> <chapter id="pubfunctions">
<title>Public Functions Provided</title> <title>Public Functions Provided</title>
!Edrivers/media/video/videodev.c !Edrivers/media/video/v4l2-dev.c
</chapter> </chapter>
</book> </book>
...@@ -69,12 +69,6 @@ ...@@ -69,12 +69,6 @@
device to be used as both a tty interface and as a synchronous device to be used as both a tty interface and as a synchronous
controller is a project for Linux post the 2.4 release controller is a project for Linux post the 2.4 release
</para> </para>
<para>
The support code handles most common card configurations and
supports running both Cisco HDLC and Synchronous PPP. With extra
glue the frame relay and X.25 protocols can also be used with this
driver.
</para>
</chapter> </chapter>
<chapter id="Driver_Modes"> <chapter id="Driver_Modes">
...@@ -179,35 +173,27 @@ ...@@ -179,35 +173,27 @@
<para> <para>
If you wish to use the network interface facilities of the driver, If you wish to use the network interface facilities of the driver,
then you need to attach a network device to each channel that is then you need to attach a network device to each channel that is
present and in use. In addition to use the SyncPPP and Cisco HDLC present and in use. In addition to use the generic HDLC
you need to follow some additional plumbing rules. They may seem you need to follow some additional plumbing rules. They may seem
complex but a look at the example hostess_sv11 driver should complex but a look at the example hostess_sv11 driver should
reassure you. reassure you.
</para> </para>
<para> <para>
The network device used for each channel should be pointed to by The network device used for each channel should be pointed to by
the netdevice field of each channel. The dev-&gt; priv field of the the netdevice field of each channel. The hdlc-&gt; priv field of the
network device points to your private data - you will need to be network device points to your private data - you will need to be
able to find your ppp device from this. In addition to use the able to find your private data from this.
sync ppp layer the private data must start with a void * pointer
to the syncppp structures.
</para> </para>
<para> <para>
The way most drivers approach this particular problem is to The way most drivers approach this particular problem is to
create a structure holding the Z8530 device definition and create a structure holding the Z8530 device definition and
put that and the syncppp pointer into the private field of put that into the private field of the network device. The
the network device. The network device fields of the channels network device fields of the channels then point back to the
then point back to the network devices. The ppp_device can also network devices.
be put in the private structure conveniently.
</para> </para>
<para> <para>
If you wish to use the synchronous ppp then you need to attach If you wish to use the generic HDLC then you need to register
the syncppp layer to the network device. You should do this before the HDLC device.
you register the network device. The
<function>sppp_attach</function> requires that the first void *
pointer in your private data is pointing to an empty struct
ppp_device. The function fills in the initial data for the
ppp/hdlc layer.
</para> </para>
<para> <para>
Before you register your network device you will also need to Before you register your network device you will also need to
...@@ -314,10 +300,10 @@ ...@@ -314,10 +300,10 @@
buffer in sk_buff format and queues it for transmission. The buffer in sk_buff format and queues it for transmission. The
caller must provide the entire packet with the exception of the caller must provide the entire packet with the exception of the
bitstuffing and CRC. This is normally done by the caller via bitstuffing and CRC. This is normally done by the caller via
the syncppp interface layer. It returns 0 if the buffer has been the generic HDLC interface layer. It returns 0 if the buffer has been
queued and non zero values for queue full. If the function accepts queued and non zero values for queue full. If the function accepts
the buffer it becomes property of the Z8530 layer and the caller the buffer it becomes property of the Z8530 layer and the caller
should not free it. should not free it.
</para> </para>
<para> <para>
The function <function>z8530_get_stats</function> returns a pointer The function <function>z8530_get_stats</function> returns a pointer
......
...@@ -358,7 +358,7 @@ Here is a list of some of the different kernel trees available: ...@@ -358,7 +358,7 @@ Here is a list of some of the different kernel trees available:
- pcmcia, Dominik Brodowski <linux@dominikbrodowski.net> - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
- SCSI, James Bottomley <James.Bottomley@SteelEye.com> - SCSI, James Bottomley <James.Bottomley@hansenpartnership.com>
git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
- x86, Ingo Molnar <mingo@elte.hu> - x86, Ingo Molnar <mingo@elte.hu>
......
...@@ -48,7 +48,7 @@ IOVA generation is pretty generic. We used the same technique as vmalloc() ...@@ -48,7 +48,7 @@ IOVA generation is pretty generic. We used the same technique as vmalloc()
but these are not global address spaces, but separate for each domain. but these are not global address spaces, but separate for each domain.
Different DMA engines may support different number of domains. Different DMA engines may support different number of domains.
We also allocate gaurd pages with each mapping, so we can attempt to catch We also allocate guard pages with each mapping, so we can attempt to catch
any overflow that might happen. any overflow that might happen.
...@@ -112,4 +112,4 @@ TBD ...@@ -112,4 +112,4 @@ TBD
- For compatibility testing, could use unity map domain for all devices, just - For compatibility testing, could use unity map domain for all devices, just
provide a 1-1 for all useful memory under a single domain for all devices. provide a 1-1 for all useful memory under a single domain for all devices.
- API for paravirt ops for abstracting functionlity for VMM folks. - API for paravirt ops for abstracting functionality for VMM folks.
...@@ -528,7 +528,33 @@ See more details on the proper patch format in the following ...@@ -528,7 +528,33 @@ See more details on the proper patch format in the following
references. references.
16) Sending "git pull" requests (from Linus emails)
Please write the git repo address and branch name alone on the same line
so that I can't even by mistake pull from the wrong branch, and so
that a triple-click just selects the whole thing.
So the proper format is something along the lines of:
"Please pull from
git://jdelvare.pck.nerim.net/jdelvare-2.6 i2c-for-linus
to get these changes:"
so that I don't have to hunt-and-peck for the address and inevitably
get it wrong (actually, I've only gotten it wrong a few times, and
checking against the diffstat tells me when I get it wrong, but I'm
just a lot more comfortable when I don't have to "look for" the right
thing to pull, and double-check that I have the right branch-name).
Please use "git diff -M --stat --summary" to generate the diffstat:
the -M enables rename detection, and the summary enables a summary of
new/deleted or renamed files.
With rename detection, the statistics are rather different [...]
because git will notice that a fair number of the changes are renames.
----------------------------------- -----------------------------------
SECTION 2 - HINTS, TIPS, AND TRICKS SECTION 2 - HINTS, TIPS, AND TRICKS
......
...@@ -11,6 +11,7 @@ the delays experienced by a task while ...@@ -11,6 +11,7 @@ the delays experienced by a task while
a) waiting for a CPU (while being runnable) a) waiting for a CPU (while being runnable)
b) completion of synchronous block I/O initiated by the task b) completion of synchronous block I/O initiated by the task
c) swapping in pages c) swapping in pages
d) memory reclaim
and makes these statistics available to userspace through and makes these statistics available to userspace through
the taskstats interface. the taskstats interface.
...@@ -41,7 +42,7 @@ this structure. See ...@@ -41,7 +42,7 @@ this structure. See
include/linux/taskstats.h include/linux/taskstats.h
for a description of the fields pertaining to delay accounting. for a description of the fields pertaining to delay accounting.
It will generally be in the form of counters returning the cumulative It will generally be in the form of counters returning the cumulative
delay seen for cpu, sync block I/O, swapin etc. delay seen for cpu, sync block I/O, swapin, memory reclaim etc.
Taking the difference of two successive readings of a given Taking the difference of two successive readings of a given
counter (say cpu_delay_total) for a task will give the delay counter (say cpu_delay_total) for a task will give the delay
...@@ -94,7 +95,9 @@ CPU count real total virtual total delay total ...@@ -94,7 +95,9 @@ CPU count real total virtual total delay total
7876 92005750 100000000 24001500 7876 92005750 100000000 24001500
IO count delay total IO count delay total
0 0 0 0
MEM count delay total SWAP count delay total
0 0
RECLAIM count delay total
0 0 0 0
Get delays seen in executing a given simple command Get delays seen in executing a given simple command
...@@ -108,5 +111,7 @@ CPU count real total virtual total delay total ...@@ -108,5 +111,7 @@ CPU count real total virtual total delay total
6 4000250 4000000 0 6 4000250 4000000 0
IO count delay total IO count delay total
0 0 0 0
MEM count delay total SWAP count delay total
0 0
RECLAIM count delay total
0 0 0 0
...@@ -196,14 +196,18 @@ void print_delayacct(struct taskstats *t) ...@@ -196,14 +196,18 @@ void print_delayacct(struct taskstats *t)
" %15llu%15llu%15llu%15llu\n" " %15llu%15llu%15llu%15llu\n"
"IO %15s%15s\n" "IO %15s%15s\n"
" %15llu%15llu\n" " %15llu%15llu\n"
"MEM %15s%15s\n" "SWAP %15s%15s\n"
" %15llu%15llu\n"
"RECLAIM %12s%15s\n"
" %15llu%15llu\n", " %15llu%15llu\n",
"count", "real total", "virtual total", "delay total", "count", "real total", "virtual total", "delay total",
t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total, t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
t->cpu_delay_total, t->cpu_delay_total,
"count", "delay total", "count", "delay total",
t->blkio_count, t->blkio_delay_total, t->blkio_count, t->blkio_delay_total,
"count", "delay total", t->swapin_count, t->swapin_delay_total); "count", "delay total", t->swapin_count, t->swapin_delay_total,
"count", "delay total",
t->freepages_count, t->freepages_delay_total);
} }
void task_context_switch_counts(struct taskstats *t) void task_context_switch_counts(struct taskstats *t)
......
...@@ -6,7 +6,7 @@ This document contains an explanation of the struct taskstats fields. ...@@ -6,7 +6,7 @@ This document contains an explanation of the struct taskstats fields.
There are three different groups of fields in the struct taskstats: There are three different groups of fields in the struct taskstats:
1) Common and basic accounting fields 1) Common and basic accounting fields
If CONFIG_TASKSTATS is set, the taskstats inteface is enabled and If CONFIG_TASKSTATS is set, the taskstats interface is enabled and
the common fields and basic accounting fields are collected for the common fields and basic accounting fields are collected for
delivery at do_exit() of a task. delivery at do_exit() of a task.
2) Delay accounting fields 2) Delay accounting fields
...@@ -26,6 +26,8 @@ There are three different groups of fields in the struct taskstats: ...@@ -26,6 +26,8 @@ There are three different groups of fields in the struct taskstats:
5) Time accounting for SMT machines 5) Time accounting for SMT machines
6) Extended delay accounting fields for memory reclaim
Future extension should add fields to the end of the taskstats struct, and Future extension should add fields to the end of the taskstats struct, and
should not change the relative position of each field within the struct. should not change the relative position of each field within the struct.
...@@ -170,4 +172,9 @@ struct taskstats { ...@@ -170,4 +172,9 @@ struct taskstats {
__u64 ac_utimescaled; /* utime scaled on frequency etc */ __u64 ac_utimescaled; /* utime scaled on frequency etc */
__u64 ac_stimescaled; /* stime scaled on frequency etc */ __u64 ac_stimescaled; /* stime scaled on frequency etc */
__u64 cpu_scaled_run_real_total; /* scaled cpu_run_real_total */ __u64 cpu_scaled_run_real_total; /* scaled cpu_run_real_total */
6) Extended delay accounting fields for memory reclaim
/* Delay waiting for memory reclaim */
__u64 freepages_count;
__u64 freepages_delay_total;
} }
...@@ -32,7 +32,7 @@ Linux currently supports the following features on the IXP4xx chips: ...@@ -32,7 +32,7 @@ Linux currently supports the following features on the IXP4xx chips:
- Flash access (MTD/JFFS) - Flash access (MTD/JFFS)
- I2C through GPIO on IXP42x - I2C through GPIO on IXP42x
- GPIO for input/output/interrupts - GPIO for input/output/interrupts
See include/asm-arm/arch-ixp4xx/platform.h for access functions. See arch/arm/mach-ixp4xx/include/mach/platform.h for access functions.
- Timers (watchdog, OS) - Timers (watchdog, OS)
The following components of the chips are not supported by Linux and The following components of the chips are not supported by Linux and
......
...@@ -138,14 +138,8 @@ So, what's changed? ...@@ -138,14 +138,8 @@ So, what's changed?
Set active the IRQ edge(s)/level. This replaces the Set active the IRQ edge(s)/level. This replaces the
SA1111 INTPOL manipulation, and the set_GPIO_IRQ_edge() SA1111 INTPOL manipulation, and the set_GPIO_IRQ_edge()
function. Type should be one of the following: function. Type should be one of IRQ_TYPE_xxx defined in
<linux/irq.h>
#define IRQT_NOEDGE (0)
#define IRQT_RISING (__IRQT_RISEDGE)
#define IRQT_FALLING (__IRQT_FALEDGE)
#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE)
#define IRQT_LOW (__IRQT_LOWLVL)
#define IRQT_HIGH (__IRQT_HIGHLVL)
3. set_GPIO_IRQ_edge() is obsolete, and should be replaced by set_irq_type. 3. set_GPIO_IRQ_edge() is obsolete, and should be replaced by set_irq_type.
...@@ -164,7 +158,7 @@ So, what's changed? ...@@ -164,7 +158,7 @@ So, what's changed?
be re-checked for pending events. (see the Neponset IRQ handler for be re-checked for pending events. (see the Neponset IRQ handler for
details). details).
7. fixup_irq() is gone, as is include/asm-arm/arch-*/irq.h 7. fixup_irq() is gone, as is arch/arm/mach-*/include/mach/irq.h
Please note that this will not solve all problems - some of them are Please note that this will not solve all problems - some of them are
hardware based. Mixing level-based and edge-based IRQs on the same hardware based. Mixing level-based and edge-based IRQs on the same
......
...@@ -79,7 +79,7 @@ Machine/Platform support ...@@ -79,7 +79,7 @@ Machine/Platform support
To this end, we now have arch/arm/mach-$(MACHINE) directories which are To this end, we now have arch/arm/mach-$(MACHINE) directories which are
designed to house the non-driver files for a particular machine (eg, PCI, designed to house the non-driver files for a particular machine (eg, PCI,
memory management, architecture definitions etc). For all future memory management, architecture definitions etc). For all future
machines, there should be a corresponding include/asm-arm/arch-$(MACHINE) machines, there should be a corresponding arch/arm/mach-$(MACHINE)/include/mach
directory. directory.
...@@ -176,7 +176,7 @@ Kernel entry (head.S) ...@@ -176,7 +176,7 @@ Kernel entry (head.S)
class typically based around one or more system on a chip devices, and class typically based around one or more system on a chip devices, and
acts as a natural container around the actual implementations. These acts as a natural container around the actual implementations. These
classes are given directories - arch/arm/mach-<class> and classes are given directories - arch/arm/mach-<class> and
include/asm-arm/arch-<class> - which contain the source files to arch/arm/mach-<class> - which contain the source files to/include/mach
support the machine class. This directories also contain any machine support the machine class. This directories also contain any machine
specific supporting code. specific supporting code.
......
...@@ -16,13 +16,13 @@ Introduction ...@@ -16,13 +16,13 @@ Introduction
Headers Headers
------- -------
See include/asm-arm/arch-s3c2410/regs-gpio.h for the list See arch/arm/mach-s3c2410/include/mach/regs-gpio.h for the list
of GPIO pins, and the configuration values for them. This of GPIO pins, and the configuration values for them. This
is included by using #include <asm/arch/regs-gpio.h> is included by using #include <mach/regs-gpio.h>
The GPIO management functions are defined in the hardware The GPIO management functions are defined in the hardware
header include/asm-arm/arch-s3c2410/hardware.h which can be header arch/arm/mach-s3c2410/include/mach/hardware.h which can be
included by #include <asm/arch/hardware.h> included by #include <mach/hardware.h>
A useful amount of documentation can be found in the hardware A useful amount of documentation can be found in the hardware
header on how the GPIO functions (and others) work. header on how the GPIO functions (and others) work.
......
...@@ -36,7 +36,7 @@ Layout ...@@ -36,7 +36,7 @@ Layout
in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440 in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440
Register, kernel and platform data definitions are held in the Register, kernel and platform data definitions are held in the
include/asm-arm/arch-s3c2410 directory. arch/arm/mach-s3c2410 directory./include/mach
Machines Machines
......
...@@ -49,7 +49,7 @@ Board Support ...@@ -49,7 +49,7 @@ Board Support
Platform Data Platform Data
------------- -------------
See linux/include/asm-arm/arch-s3c2410/usb-control.h for the See arch/arm/mach-s3c2410/include/mach/usb-control.h for the
descriptions of the platform device data. An implementation descriptions of the platform device data. An implementation
can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c . can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c .
......
===============================================================
== BT8XXGPIO driver ==
== ==
== A driver for a selfmade cheap BT8xx based PCI GPIO-card ==
== ==
== For advanced documentation, see ==
== http://www.bu3sch.de/btgpio.php ==
===============================================================
A generic digital 24-port PCI GPIO card can be built out of an ordinary
Brooktree bt848, bt849, bt878 or bt879 based analog TV tuner card. The
Brooktree chip is used in old analog Hauppauge WinTV PCI cards. You can easily
find them used for low prices on the net.
The bt8xx chip does have 24 digital GPIO ports.
These ports are accessible via 24 pins on the SMD chip package.
==============================================
== How to physically access the GPIO pins ==
==============================================
The are several ways to access these pins. One might unsolder the whole chip
and put it on a custom PCI board, or one might only unsolder each individual
GPIO pin and solder that to some tiny wire. As the chip package really is tiny
there are some advanced soldering skills needed in any case.
The physical pinouts are drawn in the following ASCII art.
The GPIO pins are marked with G00-G23
G G G G G G G G G G G G G G G G G G
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
---------------------------------------------------------------------------
--| ^ ^ |--
--| pin 86 pin 67 |--
--| |--
--| pin 61 > |-- G18
--| |-- G19
--| |-- G20
--| |-- G21
--| |-- G22
--| pin 56 > |-- G23
--| |--
--| Brooktree 878/879 |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| |--
--| O |--
--| |--
---------------------------------------------------------------------------
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
^
This is pin 1
...@@ -112,27 +112,18 @@ Hot plug support for SCSI tape drives ...@@ -112,27 +112,18 @@ Hot plug support for SCSI tape drives
Hot plugging of SCSI tape drives is supported, with some caveats. Hot plugging of SCSI tape drives is supported, with some caveats.
The cciss driver must be informed that changes to the SCSI bus The cciss driver must be informed that changes to the SCSI bus
have been made, in addition to and prior to informing the SCSI have been made. This may be done via the /proc filesystem.
mid layer. This may be done via the /proc filesystem. For example: For example:
echo "rescan" > /proc/scsi/cciss0/1 echo "rescan" > /proc/scsi/cciss0/1
This causes the adapter to query the adapter about changes to the This causes the driver to query the adapter about changes to the
physical SCSI buses and/or fibre channel arbitrated loop and the physical SCSI buses and/or fibre channel arbitrated loop and the
driver to make note of any new or removed sequential access devices driver to make note of any new or removed sequential access devices
or medium changers. The driver will output messages indicating what or medium changers. The driver will output messages indicating what
devices have been added or removed and the controller, bus, target and devices have been added or removed and the controller, bus, target and
lun used to address the device. Once this is done, the SCSI mid layer lun used to address the device. It then notifies the SCSI mid layer
can be informed of changes to the virtual SCSI bus which the driver of these changes.
presents to it in the usual way. For example:
echo scsi add-single-device 3 2 1 0 > /proc/scsi/scsi
to add a device on controller 3, bus 2, target 1, lun 0. Note that
the driver makes an effort to preserve the devices positions
in the virtual SCSI bus, so if you are only moving tape drives
around on the same adapter and not adding or removing tape drives
from the adapter, informing the SCSI mid layer may not be necessary.
Note that the naming convention of the /proc filesystem entries Note that the naming convention of the /proc filesystem entries
contains a number in addition to the driver name. (E.g. "cciss0" contains a number in addition to the driver name. (E.g. "cciss0"
......
#### cli()/sti() removal guide, started by Ingo Molnar <mingo@redhat.com>
as of 2.5.28, five popular macros have been removed on SMP, and
are being phased out on UP:
cli(), sti(), save_flags(flags), save_flags_cli(flags), restore_flags(flags)
until now it was possible to protect driver code against interrupt
handlers via a cli(), but from now on other, more lightweight methods
have to be used for synchronization, such as spinlocks or semaphores.
for example, driver code that used to do something like:
struct driver_data;
irq_handler (...)
{
....
driver_data.finish = 1;
driver_data.new_work = 0;
....
}
...
ioctl_func (...)
{
...
cli();
...
driver_data.finish = 0;
driver_data.new_work = 2;
...
sti();
...
}
was SMP-correct because the cli() function ensured that no
interrupt handler (amongst them the above irq_handler()) function
would execute while the cli()-ed section is executing.
but from now on a more direct method of locking has to be used:
DEFINE_SPINLOCK(driver_lock);
struct driver_data;
irq_handler (...)
{
unsigned long flags;
....
spin_lock_irqsave(&driver_lock, flags);
....
driver_data.finish = 1;
driver_data.new_work = 0;
....
spin_unlock_irqrestore(&driver_lock, flags);
....
}
...
ioctl_func (...)
{
...
spin_lock_irq(&driver_lock);
...
driver_data.finish = 0;
driver_data.new_work = 2;
...
spin_unlock_irq(&driver_lock);
...
}
the above code has a number of advantages:
- the locking relation is easier to understand - actual lock usage
pinpoints the critical sections. cli() usage is too opaque.
Easier to understand means it's easier to debug.
- it's faster, because spinlocks are faster to acquire than the
potentially heavily-used IRQ lock. Furthermore, your driver does
not have to wait eg. for a big heavy SCSI interrupt to finish,
because the driver_lock spinlock is only used by your driver.
cli() on the other hand was used by many drivers, and extended
the critical section to the whole IRQ handler function - creating
serious lock contention.
to make the transition easier, we've still kept the cli(), sti(),
save_flags(), save_flags_cli() and restore_flags() macros defined
on UP systems - but their usage will be phased out until 2.6 is
released.
drivers that want to disable local interrupts (interrupts on the
current CPU), can use the following five macros:
local_irq_disable(), local_irq_enable(), local_save_flags(flags),
local_irq_save(flags), local_irq_restore(flags)
but beware, their meaning and semantics are much simpler, far from
that of the old cli(), sti(), save_flags(flags) and restore_flags(flags)
SMP meaning:
local_irq_disable() => turn local IRQs off
local_irq_enable() => turn local IRQs on
local_save_flags(flags) => save the current IRQ state into flags. The
state can be on or off. (on some
architectures there's even more bits in it.)
local_irq_save(flags) => save the current IRQ state into flags and
disable interrupts.
local_irq_restore(flags) => restore the IRQ state from flags.
(local_irq_save can save both irqs on and irqs off state, and
local_irq_restore can restore into both irqs on and irqs off state.)
another related change is that synchronize_irq() now takes a parameter:
synchronize_irq(irq). This change too has the purpose of making SMP
synchronization more lightweight - this way you can wait for your own
interrupt handler to finish, no need to wait for other IRQ sources.
why were these changes done? The main reason was the architectural burden
of maintaining the cli()/sti() interface - it became a real problem. The
new interrupt system is much more streamlined, easier to understand, debug,
and it's also a bit faster - the same happened to it that will happen to
cli()/sti() using drivers once they convert to spinlocks :-)
...@@ -242,8 +242,7 @@ rmdir() if there are no tasks. ...@@ -242,8 +242,7 @@ rmdir() if there are no tasks.
1. Add support for accounting huge pages (as a separate controller) 1. Add support for accounting huge pages (as a separate controller)
2. Make per-cgroup scanner reclaim not-shared pages first 2. Make per-cgroup scanner reclaim not-shared pages first
3. Teach controller to account for shared-pages 3. Teach controller to account for shared-pages
4. Start reclamation when the limit is lowered 4. Start reclamation in the background when the limit is
5. Start reclamation in the background when the limit is
not yet hit but the usage is getting closer not yet hit but the usage is getting closer
Summary Summary
......
...@@ -122,7 +122,7 @@ around '10000' or more. ...@@ -122,7 +122,7 @@ around '10000' or more.
show_sampling_rate_(min|max): the minimum and maximum sampling rates show_sampling_rate_(min|max): the minimum and maximum sampling rates
available that you may set 'sampling_rate' to. available that you may set 'sampling_rate' to.
up_threshold: defines what the average CPU usaged between the samplings up_threshold: defines what the average CPU usage between the samplings
of 'sampling_rate' needs to be for the kernel to make a decision on of 'sampling_rate' needs to be for the kernel to make a decision on
whether it should increase the frequency. For example when it is set whether it should increase the frequency. For example when it is set
to its default value of '80' it means that between the checking to its default value of '80' it means that between the checking
......
...@@ -222,74 +222,9 @@ both csrow2 and csrow3 are populated, this indicates a dual ranked ...@@ -222,74 +222,9 @@ both csrow2 and csrow3 are populated, this indicates a dual ranked
set of DIMMs for channels 0 and 1. set of DIMMs for channels 0 and 1.
Within each of the 'mc','mcX' and 'csrowX' directories are several Within each of the 'mcX' and 'csrowX' directories are several
EDAC control and attribute files. EDAC control and attribute files.
============================================================================
DIRECTORY 'mc'
In directory 'mc' are EDAC system overall control and attribute files:
Panic on UE control file:
'edac_mc_panic_on_ue'
An uncorrectable error will cause a machine panic. This is usually
desirable. It is a bad idea to continue when an uncorrectable error
occurs - it is indeterminate what was uncorrected and the operating
system context might be so mangled that continuing will lead to further
corruption. If the kernel has MCE configured, then EDAC will never
notice the UE.
LOAD TIME: module/kernel parameter: panic_on_ue=[0|1]
RUN TIME: echo "1" >/sys/devices/system/edac/mc/edac_mc_panic_on_ue
Log UE control file:
'edac_mc_log_ue'
Generate kernel messages describing uncorrectable errors. These errors
are reported through the system message log system. UE statistics
will be accumulated even when UE logging is disabled.
LOAD TIME: module/kernel parameter: log_ue=[0|1]
RUN TIME: echo "1" >/sys/devices/system/edac/mc/edac_mc_log_ue
Log CE control file:
'edac_mc_log_ce'
Generate kernel messages describing correctable errors. These
errors are reported through the system message log system.
CE statistics will be accumulated even when CE logging is disabled.
LOAD TIME: module/kernel parameter: log_ce=[0|1]
RUN TIME: echo "1" >/sys/devices/system/edac/mc/edac_mc_log_ce
Polling period control file:
'edac_mc_poll_msec'
The time period, in milliseconds, for polling for error information.
Too small a value wastes resources. Too large a value might delay
necessary handling of errors and might loose valuable information for
locating the error. 1000 milliseconds (once each second) is the current
default. Systems which require all the bandwidth they can get, may
increase this.
LOAD TIME: module/kernel parameter: poll_msec=[0|1]
RUN TIME: echo "1000" >/sys/devices/system/edac/mc/edac_mc_poll_msec
============================================================================ ============================================================================
'mcX' DIRECTORIES 'mcX' DIRECTORIES
...@@ -392,7 +327,7 @@ Sdram memory scrubbing rate: ...@@ -392,7 +327,7 @@ Sdram memory scrubbing rate:
'sdram_scrub_rate' 'sdram_scrub_rate'
Read/Write attribute file that controls memory scrubbing. The scrubbing Read/Write attribute file that controls memory scrubbing. The scrubbing
rate is set by writing a minimum bandwith in bytes/sec to the attribute rate is set by writing a minimum bandwidth in bytes/sec to the attribute
file. The rate will be translated to an internal value that gives at file. The rate will be translated to an internal value that gives at
least the specified rate. least the specified rate.
...@@ -537,7 +472,6 @@ Channel 1 DIMM Label control file: ...@@ -537,7 +472,6 @@ Channel 1 DIMM Label control file:
motherboard specific and determination of this information motherboard specific and determination of this information
must occur in userland at this time. must occur in userland at this time.
============================================================================ ============================================================================
SYSTEM LOGGING SYSTEM LOGGING
...@@ -570,7 +504,6 @@ error type, a notice of "no info" and then an optional, ...@@ -570,7 +504,6 @@ error type, a notice of "no info" and then an optional,
driver-specific error message. driver-specific error message.
============================================================================ ============================================================================
PCI Bus Parity Detection PCI Bus Parity Detection
...@@ -604,6 +537,74 @@ Enable/Disable PCI Parity checking control file: ...@@ -604,6 +537,74 @@ Enable/Disable PCI Parity checking control file:
echo "0" >/sys/devices/system/edac/pci/check_pci_parity echo "0" >/sys/devices/system/edac/pci/check_pci_parity
Parity Count:
'pci_parity_count'
This attribute file will display the number of parity errors that
have been detected.
============================================================================
MODULE PARAMETERS
Panic on UE control file:
'edac_mc_panic_on_ue'
An uncorrectable error will cause a machine panic. This is usually
desirable. It is a bad idea to continue when an uncorrectable error
occurs - it is indeterminate what was uncorrected and the operating
system context might be so mangled that continuing will lead to further
corruption. If the kernel has MCE configured, then EDAC will never
notice the UE.
LOAD TIME: module/kernel parameter: edac_mc_panic_on_ue=[0|1]
RUN TIME: echo "1" > /sys/module/edac_core/parameters/edac_mc_panic_on_ue
Log UE control file:
'edac_mc_log_ue'
Generate kernel messages describing uncorrectable errors. These errors
are reported through the system message log system. UE statistics
will be accumulated even when UE logging is disabled.
LOAD TIME: module/kernel parameter: edac_mc_log_ue=[0|1]
RUN TIME: echo "1" > /sys/module/edac_core/parameters/edac_mc_log_ue
Log CE control file:
'edac_mc_log_ce'
Generate kernel messages describing correctable errors. These
errors are reported through the system message log system.
CE statistics will be accumulated even when CE logging is disabled.
LOAD TIME: module/kernel parameter: edac_mc_log_ce=[0|1]
RUN TIME: echo "1" > /sys/module/edac_core/parameters/edac_mc_log_ce
Polling period control file:
'edac_mc_poll_msec'
The time period, in milliseconds, for polling for error information.
Too small a value wastes resources. Too large a value might delay
necessary handling of errors and might loose valuable information for
locating the error. 1000 milliseconds (once each second) is the current
default. Systems which require all the bandwidth they can get, may
increase this.
LOAD TIME: module/kernel parameter: edac_mc_poll_msec=[0|1]
RUN TIME: echo "1000" > /sys/module/edac_core/parameters/edac_mc_poll_msec
Panic on PCI PARITY Error: Panic on PCI PARITY Error:
...@@ -614,21 +615,13 @@ Panic on PCI PARITY Error: ...@@ -614,21 +615,13 @@ Panic on PCI PARITY Error:
error has been detected. error has been detected.
module/kernel parameter: panic_on_pci_parity=[0|1] module/kernel parameter: edac_panic_on_pci_pe=[0|1]
Enable: Enable:
echo "1" >/sys/devices/system/edac/pci/panic_on_pci_parity echo "1" > /sys/module/edac_core/parameters/edac_panic_on_pci_pe
Disable: Disable:
echo "0" >/sys/devices/system/edac/pci/panic_on_pci_parity echo "0" > /sys/module/edac_core/parameters/edac_panic_on_pci_pe
Parity Count:
'pci_parity_count'
This attribute file will display the number of parity errors that
have been detected.
......
SH7760/SH7763 integrated LCDC Framebuffer driver
================================================
0. Overwiew
-----------
The SH7760/SH7763 have an integrated LCD Display controller (LCDC) which
supports (in theory) resolutions ranging from 1x1 to 1024x1024,
with color depths ranging from 1 to 16 bits, on STN, DSTN and TFT Panels.
Caveats:
* Framebuffer memory must be a large chunk allocated at the top
of Area3 (HW requirement). Because of this requirement you should NOT
make the driver a module since at runtime it may become impossible to
get a large enough contiguous chunk of memory.
* The driver does not support changing resolution while loaded
(displays aren't hotpluggable anyway)
* Heavy flickering may be observed
a) if you're using 15/16bit color modes at >= 640x480 px resolutions,
b) during PCMCIA (or any other slow bus) activity.
* Rotation works only 90degress clockwise, and only if horizontal
resolution is <= 320 pixels.
files: drivers/video/sh7760fb.c
include/asm-sh/sh7760fb.h
Documentation/fb/sh7760fb.txt
1. Platform setup
-----------------
SH7760:
Video data is fetched via the DMABRG DMA engine, so you have to
configure the SH DMAC for DMABRG mode (write 0x94808080 to the
DMARSRA register somewhere at boot).
PFC registers PCCR and PCDR must be set to peripheral mode.
(write zeros to both).
The driver does NOT do the above for you since board setup is, well, job
of the board setup code.
2. Panel definitions
--------------------
The LCDC must explicitly be told about the type of LCD panel
attached. Data must be wrapped in a "struct sh7760fb_platdata" and
passed to the driver as platform_data.
Suggest you take a closer look at the SH7760 Manual, Section 30.
(http://documentation.renesas.com/eng/products/mpumcu/e602291_sh7760.pdf)
The following code illustrates what needs to be done to
get the framebuffer working on a 640x480 TFT:
====================== cut here ======================================
#include <linux/fb.h>
#include <asm/sh7760fb.h>
/*
* NEC NL6440bc26-01 640x480 TFT
* dotclock 25175 kHz
* Xres 640 Yres 480
* Htotal 800 Vtotal 525
* HsynStart 656 VsynStart 490
* HsynLenn 30 VsynLenn 2
*
* The linux framebuffer layer does not use the syncstart/synclen
* values but right/left/upper/lower margin values. The comments
* for the x_margin explain how to calculate those from given
* panel sync timings.
*/
static struct fb_videomode nl6448bc26 = {
.name = "NL6448BC26",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39683, /* in picoseconds! */
.hsync_len = 30,
.vsync_len = 2,
.left_margin = 114, /* HTOT - (HSYNSLEN + HSYNSTART) */
.right_margin = 16, /* HSYNSTART - XRES */
.upper_margin = 33, /* VTOT - (VSYNLEN + VSYNSTART) */
.lower_margin = 10, /* VSYNSTART - YRES */
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
.flag = 0,
};
static struct sh7760fb_platdata sh7760fb_nl6448 = {
.def_mode = &nl6448bc26,
.ldmtr = LDMTR_TFT_COLOR_16, /* 16bit TFT panel */
.lddfr = LDDFR_8BPP, /* we want 8bit output */
.ldpmmr = 0x0070,
.ldpspr = 0x0500,
.ldaclnr = 0,
.ldickr = LDICKR_CLKSRC(LCDC_CLKSRC_EXTERNAL) |
LDICKR_CLKDIV(1),
.rotate = 0,
.novsync = 1,
.blank = NULL,
};
/* SH7760:
* 0xFE300800: 256 * 4byte xRGB palette ram
* 0xFE300C00: 42 bytes ctrl registers
*/
static struct resource sh7760_lcdc_res[] = {
[0] = {
.start = 0xFE300800,
.end = 0xFE300CFF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 65,
.end = 65,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device sh7760_lcdc_dev = {
.dev = {
.platform_data = &sh7760fb_nl6448,
},
.name = "sh7760-lcdc",
.id = -1,
.resource = sh7760_lcdc_res,
.num_resources = ARRAY_SIZE(sh7760_lcdc_res),
};
====================== cut here ======================================
...@@ -3,11 +3,25 @@ Tridentfb is a framebuffer driver for some Trident chip based cards. ...@@ -3,11 +3,25 @@ Tridentfb is a framebuffer driver for some Trident chip based cards.
The following list of chips is thought to be supported although not all are The following list of chips is thought to be supported although not all are
tested: tested:
those from the Image series with Cyber in their names - accelerated those from the TGUI series 9440/96XX and with Cyber in their names
those with Blade in their names (Blade3D,CyberBlade...) - accelerated those from the Image series and with Cyber in their names
the newer CyberBladeXP family - nonaccelerated those with Blade in their names (Blade3D,CyberBlade...)
the newer CyberBladeXP family
Only PCI/AGP based cards are supported, none of the older Tridents.
All families are accelerated. Only PCI/AGP based cards are supported,
none of the older Tridents.
The driver supports 8, 16 and 32 bits per pixel depths.
The TGUI family requires a line length to be power of 2 if acceleration
is enabled. This means that range of possible resolutions and bpp is
limited comparing to the range if acceleration is disabled (see list
of parameters below).
Known bugs:
1. The driver randomly locks up on 3DImage975 chip with acceleration
enabled. The same happens in X11 (Xorg).
2. The ramdac speeds require some more fine tuning. It is possible to
switch resolution which the chip does not support at some depths for
older chips.
How to use it? How to use it?
============== ==============
...@@ -17,12 +31,11 @@ video=tridentfb ...@@ -17,12 +31,11 @@ video=tridentfb
The parameters for tridentfb are concatenated with a ':' as in this example. The parameters for tridentfb are concatenated with a ':' as in this example.
video=tridentfb:800x600,bpp=16,noaccel video=tridentfb:800x600-16@75,noaccel
The second level parameters that tridentfb understands are: The second level parameters that tridentfb understands are:
noaccel - turns off acceleration (when it doesn't work for your card) noaccel - turns off acceleration (when it doesn't work for your card)
accel - force text acceleration (for boards which by default are noacceled)
fp - use flat panel related stuff fp - use flat panel related stuff
crt - assume monitor is present instead of fp crt - assume monitor is present instead of fp
...@@ -31,21 +44,24 @@ center - for flat panels and resolutions smaller than native size center the ...@@ -31,21 +44,24 @@ center - for flat panels and resolutions smaller than native size center the
image, otherwise use image, otherwise use
stretch stretch
memsize - integer value in Kb, use if your card's memory size is misdetected. memsize - integer value in KB, use if your card's memory size is misdetected.
look at the driver output to see what it says when initializing. look at the driver output to see what it says when initializing.
memdiff - integer value in Kb,should be nonzero if your card reports
more memory than it actually has.For instance mine is 192K less than memdiff - integer value in KB, should be nonzero if your card reports
more memory than it actually has. For instance mine is 192K less than
detection says in all three BIOS selectable situations 2M, 4M, 8M. detection says in all three BIOS selectable situations 2M, 4M, 8M.
Only use if your video memory is taken from main memory hence of Only use if your video memory is taken from main memory hence of
configurable size.Otherwise use memsize. configurable size. Otherwise use memsize.
If in some modes which barely fit the memory you see garbage at the bottom If in some modes which barely fit the memory you see garbage
this might help by not letting change to that mode anymore. at the bottom this might help by not letting change to that mode
anymore.
nativex - the width in pixels of the flat panel.If you know it (usually 1024 nativex - the width in pixels of the flat panel.If you know it (usually 1024
800 or 1280) and it is not what the driver seems to detect use it. 800 or 1280) and it is not what the driver seems to detect use it.
bpp - bits per pixel (8,16 or 32) bpp - bits per pixel (8,16 or 32)
mode - a mode name like 800x600 (as described in Documentation/fb/modedb.txt) mode - a mode name like 800x600-8@75 as described in
Documentation/fb/modedb.txt
Using insane values for the above parameters will probably result in driver Using insane values for the above parameters will probably result in driver
misbehaviour so take care(for instance memsize=12345678 or memdiff=23784 or misbehaviour so take care(for instance memsize=12345678 or memdiff=23784 or
......
...@@ -47,6 +47,30 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org> ...@@ -47,6 +47,30 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org>
--------------------------- ---------------------------
What: old tuner-3036 i2c driver
When: 2.6.28
Why: This driver is for VERY old i2c-over-parallel port teletext receiver
boxes. Rather then spending effort on converting this driver to V4L2,
and since it is extremely unlikely that anyone still uses one of these
devices, it was decided to drop it.
Who: Hans Verkuil <hverkuil@xs4all.nl>
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: V4L2 dpc7146 driver
When: 2.6.28
Why: Old driver for the dpc7146 demonstration board that is no longer
relevant. The last time this was tested on actual hardware was
probably around 2002. Since this is a driver for a demonstration
board the decision was made to remove it rather than spending a
lot of effort continually updating this driver to stay in sync
with the latest internal V4L2 or I2C API.
Who: Hans Verkuil <hverkuil@xs4all.nl>
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
When: November 2005 When: November 2005
Files: drivers/pcmcia/: pcmcia_ioctl.c Files: drivers/pcmcia/: pcmcia_ioctl.c
...@@ -138,24 +162,6 @@ Who: Kay Sievers <kay.sievers@suse.de> ...@@ -138,24 +162,6 @@ Who: Kay Sievers <kay.sievers@suse.de>
--------------------------- ---------------------------
What: find_task_by_pid
When: 2.6.26
Why: With pid namespaces, calling this funciton will return the
wrong task when called from inside a namespace.
The best way to save a task pid and find a task by this
pid later, is to find this task's struct pid pointer (or get
it directly from the task) and call pid_task() later.
If someone really needs to get a task by its pid_t, then
he most likely needs the find_task_by_vpid() to get the
task from the same namespace as the current task is in, but
this may be not so in general.
Who: Pavel Emelyanov <xemul@openvz.org>
---------------------------
What: ACPI procfs interface What: ACPI procfs interface
When: July 2008 When: July 2008
Why: ACPI sysfs conversion should be finished by January 2008. Why: ACPI sysfs conversion should be finished by January 2008.
...@@ -300,11 +306,15 @@ Who: ocfs2-devel@oss.oracle.com ...@@ -300,11 +306,15 @@ Who: ocfs2-devel@oss.oracle.com
--------------------------- ---------------------------
What: asm/semaphore.h What: SCTP_GET_PEER_ADDRS_NUM_OLD, SCTP_GET_PEER_ADDRS_OLD,
When: 2.6.26 SCTP_GET_LOCAL_ADDRS_NUM_OLD, SCTP_GET_LOCAL_ADDRS_OLD
Why: Implementation became generic; users should now include When: June 2009
linux/semaphore.h instead. Why: A newer version of the options have been introduced in 2005 that
Who: Matthew Wilcox <willy@linux.intel.com> removes the limitions of the old API. The sctp library has been
converted to use these new options at the same time. Any user
space app that directly uses the old options should convert to using
the new options.
Who: Vlad Yasevich <vladislav.yasevich@hp.com>
--------------------------- ---------------------------
...@@ -314,3 +324,23 @@ Why: This option was introduced just to allow older lm-sensors userspace ...@@ -314,3 +324,23 @@ Why: This option was introduced just to allow older lm-sensors userspace
to keep working over the upgrade to 2.6.26. At the scheduled time of to keep working over the upgrade to 2.6.26. At the scheduled time of
removal fixed lm-sensors (2.x or 3.x) should be readily available. removal fixed lm-sensors (2.x or 3.x) should be readily available.
Who: Rene Herman <rene.herman@gmail.com> Who: Rene Herman <rene.herman@gmail.com>
---------------------------
What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS
(in net/core/net-sysfs.c)
When: After the only user (hal) has seen a release with the patches
for enough time, probably some time in 2010.
Why: Over 1K .text/.data size reduction, data is available in other
ways (ioctls)
Who: Johannes Berg <johannes@sipsolutions.net>
---------------------------
What: CONFIG_NF_CT_ACCT
When: 2.6.29
Why: Accounting can now be enabled/disabled without kernel recompilation.
Currently used only to set a default value for a feature that is also
controlled by a kernel/module/sysfs/sysctl parameter.
Who: Krzysztof Piotr Oledzki <ole@ans.pl>
...@@ -510,6 +510,7 @@ prototypes: ...@@ -510,6 +510,7 @@ prototypes:
void (*close)(struct vm_area_struct*); void (*close)(struct vm_area_struct*);
int (*fault)(struct vm_area_struct*, struct vm_fault *); int (*fault)(struct vm_area_struct*, struct vm_fault *);
int (*page_mkwrite)(struct vm_area_struct *, struct page *); int (*page_mkwrite)(struct vm_area_struct *, struct page *);
int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
locking rules: locking rules:
BKL mmap_sem PageLocked(page) BKL mmap_sem PageLocked(page)
...@@ -517,6 +518,7 @@ open: no yes ...@@ -517,6 +518,7 @@ open: no yes
close: no yes close: no yes
fault: no yes fault: no yes
page_mkwrite: no yes no page_mkwrite: no yes no
access: no yes
->page_mkwrite() is called when a previously read-only page is ->page_mkwrite() is called when a previously read-only page is
about to become writeable. The file system is responsible for about to become writeable. The file system is responsible for
...@@ -525,6 +527,11 @@ taking to lock out truncate, the page range should be verified to be ...@@ -525,6 +527,11 @@ taking to lock out truncate, the page range should be verified to be
within i_size. The page mapping should also be checked that it is not within i_size. The page mapping should also be checked that it is not
NULL. NULL.
->access() is called when get_user_pages() fails in
acces_process_vm(), typically used to debug a process through
/proc/pid/mem or ptrace. This function is needed only for
VM_IO | VM_PFNMAP VMAs.
================================================================================ ================================================================================
Dubious stuff Dubious stuff
......
...@@ -26,11 +26,11 @@ You can simplify mounting by just typing: ...@@ -26,11 +26,11 @@ You can simplify mounting by just typing:
this will allocate the first available loopback device (and load loop.o this will allocate the first available loopback device (and load loop.o
kernel module if necessary) automatically. If the loopback driver is not kernel module if necessary) automatically. If the loopback driver is not
loaded automatically, make sure that your kernel is compiled with kmod loaded automatically, make sure that you have compiled the module and
support (CONFIG_KMOD) enabled. Beware that umount will not that modprobe is functioning. Beware that umount will not deallocate
deallocate /dev/loopN device if /etc/mtab file on your system is a /dev/loopN device if /etc/mtab file on your system is a symbolic link to
symbolic link to /proc/mounts. You will need to do it manually using /proc/mounts. You will need to do it manually using "-d" switch of
"-d" switch of losetup(8). Read losetup(8) manpage for more info. losetup(8). Read losetup(8) manpage for more info.
To create the BFS image under UnixWare you need to find out first which To create the BFS image under UnixWare you need to find out first which
slice contains it. The command prtvtoc(1M) is your friend: slice contains it. The command prtvtoc(1M) is your friend:
......
...@@ -233,12 +233,10 @@ accomplished via the group operations specified on the group's ...@@ -233,12 +233,10 @@ accomplished via the group operations specified on the group's
config_item_type. config_item_type.
struct configfs_group_operations { struct configfs_group_operations {
int (*make_item)(struct config_group *group, struct config_item *(*make_item)(struct config_group *group,
const char *name, const char *name);
struct config_item **new_item); struct config_group *(*make_group)(struct config_group *group,
int (*make_group)(struct config_group *group, const char *name);
const char *name,
struct config_group **new_group);
int (*commit_item)(struct config_item *item); int (*commit_item)(struct config_item *item);
void (*disconnect_notify)(struct config_group *group, void (*disconnect_notify)(struct config_group *group,
struct config_item *item); struct config_item *item);
...@@ -313,9 +311,20 @@ the subsystem must be ready for it. ...@@ -313,9 +311,20 @@ the subsystem must be ready for it.
[An Example] [An Example]
The best example of these basic concepts is the simple_children The best example of these basic concepts is the simple_children
subsystem/group and the simple_child item in configfs_example.c It subsystem/group and the simple_child item in configfs_example_explicit.c
shows a trivial object displaying and storing an attribute, and a simple and configfs_example_macros.c. It shows a trivial object displaying and
group creating and destroying these children. storing an attribute, and a simple group creating and destroying these
children.
The only difference between configfs_example_explicit.c and
configfs_example_macros.c is how the attributes of the childless item
are defined. The childless item has extended attributes, each with
their own show()/store() operation. This follows a convention commonly
used in sysfs. configfs_example_explicit.c creates these attributes
by explicitly defining the structures involved. Conversely
configfs_example_macros.c uses some convenience macros from configfs.h
to define the attributes. These macros are similar to their sysfs
counterparts.
[Hierarchy Navigation and the Subsystem Mutex] [Hierarchy Navigation and the Subsystem Mutex]
......
/*
* vim: noexpandtab ts=8 sts=0 sw=8:
*
* configfs_example.c - This file is a demonstration module containing
* a number of configfs subsystems.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 021110-1307, USA.
*
* Based on sysfs:
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
*
* configfs Copyright (C) 2005 Oracle. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/configfs.h>
/*
* 01-childless
*
* This first example is a childless subsystem. It cannot create
* any config_items. It just has attributes.
*
* Note that we are enclosing the configfs_subsystem inside a container.
* This is not necessary if a subsystem has no attributes directly
* on the subsystem. See the next example, 02-simple-children, for
* such a subsystem.
*/
struct childless {
struct configfs_subsystem subsys;
int showme;
int storeme;
};
struct childless_attribute {
struct configfs_attribute attr;
ssize_t (*show)(struct childless *, char *);
ssize_t (*store)(struct childless *, const char *, size_t);
};
static inline struct childless *to_childless(struct config_item *item)
{
return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
}
static ssize_t childless_showme_read(struct childless *childless,
char *page)
{
ssize_t pos;
pos = sprintf(page, "%d\n", childless->showme);
childless->showme++;
return pos;
}
static ssize_t childless_storeme_read(struct childless *childless,
char *page)
{
return sprintf(page, "%d\n", childless->storeme);
}
static ssize_t childless_storeme_write(struct childless *childless,
const char *page,
size_t count)
{
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
childless->storeme = tmp;
return count;
}
static ssize_t childless_description_read(struct childless *childless,
char *page)
{
return sprintf(page,
"[01-childless]\n"
"\n"
"The childless subsystem is the simplest possible subsystem in\n"
"configfs. It does not support the creation of child config_items.\n"
"It only has a few attributes. In fact, it isn't much different\n"
"than a directory in /proc.\n");
}
static struct childless_attribute childless_attr_showme = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
.show = childless_showme_read,
};
static struct childless_attribute childless_attr_storeme = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
.show = childless_storeme_read,
.store = childless_storeme_write,
};
static struct childless_attribute childless_attr_description = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
.show = childless_description_read,
};
static struct configfs_attribute *childless_attrs[] = {
&childless_attr_showme.attr,
&childless_attr_storeme.attr,
&childless_attr_description.attr,
NULL,
};
static ssize_t childless_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
struct childless *childless = to_childless(item);
struct childless_attribute *childless_attr =
container_of(attr, struct childless_attribute, attr);
ssize_t ret = 0;
if (childless_attr->show)
ret = childless_attr->show(childless, page);
return ret;
}
static ssize_t childless_attr_store(struct config_item *item,
struct configfs_attribute *attr,
const char *page, size_t count)
{
struct childless *childless = to_childless(item);
struct childless_attribute *childless_attr =
container_of(attr, struct childless_attribute, attr);
ssize_t ret = -EINVAL;
if (childless_attr->store)
ret = childless_attr->store(childless, page, count);
return ret;
}
static struct configfs_item_operations childless_item_ops = {
.show_attribute = childless_attr_show,
.store_attribute = childless_attr_store,
};
static struct config_item_type childless_type = {
.ct_item_ops = &childless_item_ops,
.ct_attrs = childless_attrs,
.ct_owner = THIS_MODULE,
};
static struct childless childless_subsys = {
.subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "01-childless",
.ci_type = &childless_type,
},
},
},
};
/* ----------------------------------------------------------------- */
/*
* 02-simple-children
*
* This example merely has a simple one-attribute child. Note that
* there is no extra attribute structure, as the child's attribute is
* known from the get-go. Also, there is no container for the
* subsystem, as it has no attributes of its own.
*/
struct simple_child {
struct config_item item;
int storeme;
};
static inline struct simple_child *to_simple_child(struct config_item *item)
{
return item ? container_of(item, struct simple_child, item) : NULL;
}
static struct configfs_attribute simple_child_attr_storeme = {
.ca_owner = THIS_MODULE,
.ca_name = "storeme",
.ca_mode = S_IRUGO | S_IWUSR,
};
static struct configfs_attribute *simple_child_attrs[] = {
&simple_child_attr_storeme,
NULL,
};
static ssize_t simple_child_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
ssize_t count;
struct simple_child *simple_child = to_simple_child(item);
count = sprintf(page, "%d\n", simple_child->storeme);
return count;
}
static ssize_t simple_child_attr_store(struct config_item *item,
struct configfs_attribute *attr,
const char *page, size_t count)
{
struct simple_child *simple_child = to_simple_child(item);
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
simple_child->storeme = tmp;
return count;
}
static void simple_child_release(struct config_item *item)
{
kfree(to_simple_child(item));
}
static struct configfs_item_operations simple_child_item_ops = {
.release = simple_child_release,
.show_attribute = simple_child_attr_show,
.store_attribute = simple_child_attr_store,
};
static struct config_item_type simple_child_type = {
.ct_item_ops = &simple_child_item_ops,
.ct_attrs = simple_child_attrs,
.ct_owner = THIS_MODULE,
};
struct simple_children {
struct config_group group;
};
static inline struct simple_children *to_simple_children(struct config_item *item)
{
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
}
static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item)
{
struct simple_child *simple_child;
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
if (!simple_child)
return -ENOMEM;
config_item_init_type_name(&simple_child->item, name,
&simple_child_type);
simple_child->storeme = 0;
*new_item = &simple_child->item;
return 0;
}
static struct configfs_attribute simple_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *simple_children_attrs[] = {
&simple_children_attr_description,
NULL,
};
static ssize_t simple_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[02-simple-children]\n"
"\n"
"This subsystem allows the creation of child config_items. These\n"
"items have only one attribute that is readable and writeable.\n");
}
static void simple_children_release(struct config_item *item)
{
kfree(to_simple_children(item));
}
static struct configfs_item_operations simple_children_item_ops = {
.release = simple_children_release,
.show_attribute = simple_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations simple_children_group_ops = {
.make_item = simple_children_make_item,
};
static struct config_item_type simple_children_type = {
.ct_item_ops = &simple_children_item_ops,
.ct_group_ops = &simple_children_group_ops,
.ct_attrs = simple_children_attrs,
.ct_owner = THIS_MODULE,
};
static struct configfs_subsystem simple_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "02-simple-children",
.ci_type = &simple_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* 03-group-children
*
* This example reuses the simple_children group from above. However,
* the simple_children group is not the subsystem itself, it is a
* child of the subsystem. Creation of a group in the subsystem creates
* a new simple_children group. That group can then have simple_child
* children of its own.
*/
static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group)
{
struct simple_children *simple_children;
simple_children = kzalloc(sizeof(struct simple_children),
GFP_KERNEL);
if (!simple_children)
return -ENOMEM;
config_group_init_type_name(&simple_children->group, name,
&simple_children_type);
*new_group = &simple_children->group;
return 0;
}
static struct configfs_attribute group_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *group_children_attrs[] = {
&group_children_attr_description,
NULL,
};
static ssize_t group_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[03-group-children]\n"
"\n"
"This subsystem allows the creation of child config_groups. These\n"
"groups are like the subsystem simple-children.\n");
}
static struct configfs_item_operations group_children_item_ops = {
.show_attribute = group_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations group_children_group_ops = {
.make_group = group_children_make_group,
};
static struct config_item_type group_children_type = {
.ct_item_ops = &group_children_item_ops,
.ct_group_ops = &group_children_group_ops,
.ct_attrs = group_children_attrs,
.ct_owner = THIS_MODULE,
};
static struct configfs_subsystem group_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "03-group-children",
.ci_type = &group_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* We're now done with our subsystem definitions.
* For convenience in this module, here's a list of them all. It
* allows the init function to easily register them. Most modules
* will only have one subsystem, and will only call register_subsystem
* on it directly.
*/
static struct configfs_subsystem *example_subsys[] = {
&childless_subsys.subsys,
&simple_children_subsys,
&group_children_subsys,
NULL,
};
static int __init configfs_example_init(void)
{
int ret;
int i;
struct configfs_subsystem *subsys;
for (i = 0; example_subsys[i]; i++) {
subsys = example_subsys[i];
config_group_init(&subsys->su_group);
mutex_init(&subsys->su_mutex);
ret = configfs_register_subsystem(subsys);
if (ret) {
printk(KERN_ERR "Error %d while registering subsystem %s\n",
ret,
subsys->su_group.cg_item.ci_namebuf);
goto out_unregister;
}
}
return 0;
out_unregister:
for (; i >= 0; i--) {
configfs_unregister_subsystem(example_subsys[i]);
}
return ret;
}
static void __exit configfs_example_exit(void)
{
int i;
for (i = 0; example_subsys[i]; i++) {
configfs_unregister_subsystem(example_subsys[i]);
}
}
module_init(configfs_example_init);
module_exit(configfs_example_exit);
MODULE_LICENSE("GPL");
/*
* vim: noexpandtab ts=8 sts=0 sw=8:
*
* configfs_example_explicit.c - This file is a demonstration module
* containing a number of configfs subsystems. It explicitly defines
* each structure without using the helper macros defined in
* configfs.h.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 021110-1307, USA.
*
* Based on sysfs:
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
*
* configfs Copyright (C) 2005 Oracle. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/configfs.h>
/*
* 01-childless
*
* This first example is a childless subsystem. It cannot create
* any config_items. It just has attributes.
*
* Note that we are enclosing the configfs_subsystem inside a container.
* This is not necessary if a subsystem has no attributes directly
* on the subsystem. See the next example, 02-simple-children, for
* such a subsystem.
*/
struct childless {
struct configfs_subsystem subsys;
int showme;
int storeme;
};
struct childless_attribute {
struct configfs_attribute attr;
ssize_t (*show)(struct childless *, char *);
ssize_t (*store)(struct childless *, const char *, size_t);
};
static inline struct childless *to_childless(struct config_item *item)
{
return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
}
static ssize_t childless_showme_read(struct childless *childless,
char *page)
{
ssize_t pos;
pos = sprintf(page, "%d\n", childless->showme);
childless->showme++;
return pos;
}
static ssize_t childless_storeme_read(struct childless *childless,
char *page)
{
return sprintf(page, "%d\n", childless->storeme);
}
static ssize_t childless_storeme_write(struct childless *childless,
const char *page,
size_t count)
{
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
childless->storeme = tmp;
return count;
}
static ssize_t childless_description_read(struct childless *childless,
char *page)
{
return sprintf(page,
"[01-childless]\n"
"\n"
"The childless subsystem is the simplest possible subsystem in\n"
"configfs. It does not support the creation of child config_items.\n"
"It only has a few attributes. In fact, it isn't much different\n"
"than a directory in /proc.\n");
}
static struct childless_attribute childless_attr_showme = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
.show = childless_showme_read,
};
static struct childless_attribute childless_attr_storeme = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
.show = childless_storeme_read,
.store = childless_storeme_write,
};
static struct childless_attribute childless_attr_description = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
.show = childless_description_read,
};
static struct configfs_attribute *childless_attrs[] = {
&childless_attr_showme.attr,
&childless_attr_storeme.attr,
&childless_attr_description.attr,
NULL,
};
static ssize_t childless_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
struct childless *childless = to_childless(item);
struct childless_attribute *childless_attr =
container_of(attr, struct childless_attribute, attr);
ssize_t ret = 0;
if (childless_attr->show)
ret = childless_attr->show(childless, page);
return ret;
}
static ssize_t childless_attr_store(struct config_item *item,
struct configfs_attribute *attr,
const char *page, size_t count)
{
struct childless *childless = to_childless(item);
struct childless_attribute *childless_attr =
container_of(attr, struct childless_attribute, attr);
ssize_t ret = -EINVAL;
if (childless_attr->store)
ret = childless_attr->store(childless, page, count);
return ret;
}
static struct configfs_item_operations childless_item_ops = {
.show_attribute = childless_attr_show,
.store_attribute = childless_attr_store,
};
static struct config_item_type childless_type = {
.ct_item_ops = &childless_item_ops,
.ct_attrs = childless_attrs,
.ct_owner = THIS_MODULE,
};
static struct childless childless_subsys = {
.subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "01-childless",
.ci_type = &childless_type,
},
},
},
};
/* ----------------------------------------------------------------- */
/*
* 02-simple-children
*
* This example merely has a simple one-attribute child. Note that
* there is no extra attribute structure, as the child's attribute is
* known from the get-go. Also, there is no container for the
* subsystem, as it has no attributes of its own.
*/
struct simple_child {
struct config_item item;
int storeme;
};
static inline struct simple_child *to_simple_child(struct config_item *item)
{
return item ? container_of(item, struct simple_child, item) : NULL;
}
static struct configfs_attribute simple_child_attr_storeme = {
.ca_owner = THIS_MODULE,
.ca_name = "storeme",
.ca_mode = S_IRUGO | S_IWUSR,
};
static struct configfs_attribute *simple_child_attrs[] = {
&simple_child_attr_storeme,
NULL,
};
static ssize_t simple_child_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
ssize_t count;
struct simple_child *simple_child = to_simple_child(item);
count = sprintf(page, "%d\n", simple_child->storeme);
return count;
}
static ssize_t simple_child_attr_store(struct config_item *item,
struct configfs_attribute *attr,
const char *page, size_t count)
{
struct simple_child *simple_child = to_simple_child(item);
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
simple_child->storeme = tmp;
return count;
}
static void simple_child_release(struct config_item *item)
{
kfree(to_simple_child(item));
}
static struct configfs_item_operations simple_child_item_ops = {
.release = simple_child_release,
.show_attribute = simple_child_attr_show,
.store_attribute = simple_child_attr_store,
};
static struct config_item_type simple_child_type = {
.ct_item_ops = &simple_child_item_ops,
.ct_attrs = simple_child_attrs,
.ct_owner = THIS_MODULE,
};
struct simple_children {
struct config_group group;
};
static inline struct simple_children *to_simple_children(struct config_item *item)
{
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
}
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
{
struct simple_child *simple_child;
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
if (!simple_child)
return ERR_PTR(-ENOMEM);
config_item_init_type_name(&simple_child->item, name,
&simple_child_type);
simple_child->storeme = 0;
return &simple_child->item;
}
static struct configfs_attribute simple_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *simple_children_attrs[] = {
&simple_children_attr_description,
NULL,
};
static ssize_t simple_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[02-simple-children]\n"
"\n"
"This subsystem allows the creation of child config_items. These\n"
"items have only one attribute that is readable and writeable.\n");
}
static void simple_children_release(struct config_item *item)
{
kfree(to_simple_children(item));
}
static struct configfs_item_operations simple_children_item_ops = {
.release = simple_children_release,
.show_attribute = simple_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations simple_children_group_ops = {
.make_item = simple_children_make_item,
};
static struct config_item_type simple_children_type = {
.ct_item_ops = &simple_children_item_ops,
.ct_group_ops = &simple_children_group_ops,
.ct_attrs = simple_children_attrs,
.ct_owner = THIS_MODULE,
};
static struct configfs_subsystem simple_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "02-simple-children",
.ci_type = &simple_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* 03-group-children
*
* This example reuses the simple_children group from above. However,
* the simple_children group is not the subsystem itself, it is a
* child of the subsystem. Creation of a group in the subsystem creates
* a new simple_children group. That group can then have simple_child
* children of its own.
*/
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
{
struct simple_children *simple_children;
simple_children = kzalloc(sizeof(struct simple_children),
GFP_KERNEL);
if (!simple_children)
return ERR_PTR(-ENOMEM);
config_group_init_type_name(&simple_children->group, name,
&simple_children_type);
return &simple_children->group;
}
static struct configfs_attribute group_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *group_children_attrs[] = {
&group_children_attr_description,
NULL,
};
static ssize_t group_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[03-group-children]\n"
"\n"
"This subsystem allows the creation of child config_groups. These\n"
"groups are like the subsystem simple-children.\n");
}
static struct configfs_item_operations group_children_item_ops = {
.show_attribute = group_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations group_children_group_ops = {
.make_group = group_children_make_group,
};
static struct config_item_type group_children_type = {
.ct_item_ops = &group_children_item_ops,
.ct_group_ops = &group_children_group_ops,
.ct_attrs = group_children_attrs,
.ct_owner = THIS_MODULE,
};
static struct configfs_subsystem group_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "03-group-children",
.ci_type = &group_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* We're now done with our subsystem definitions.
* For convenience in this module, here's a list of them all. It
* allows the init function to easily register them. Most modules
* will only have one subsystem, and will only call register_subsystem
* on it directly.
*/
static struct configfs_subsystem *example_subsys[] = {
&childless_subsys.subsys,
&simple_children_subsys,
&group_children_subsys,
NULL,
};
static int __init configfs_example_init(void)
{
int ret;
int i;
struct configfs_subsystem *subsys;
for (i = 0; example_subsys[i]; i++) {
subsys = example_subsys[i];
config_group_init(&subsys->su_group);
mutex_init(&subsys->su_mutex);
ret = configfs_register_subsystem(subsys);
if (ret) {
printk(KERN_ERR "Error %d while registering subsystem %s\n",
ret,
subsys->su_group.cg_item.ci_namebuf);
goto out_unregister;
}
}
return 0;
out_unregister:
for (; i >= 0; i--) {
configfs_unregister_subsystem(example_subsys[i]);
}
return ret;
}
static void __exit configfs_example_exit(void)
{
int i;
for (i = 0; example_subsys[i]; i++) {
configfs_unregister_subsystem(example_subsys[i]);
}
}
module_init(configfs_example_init);
module_exit(configfs_example_exit);
MODULE_LICENSE("GPL");
/*
* vim: noexpandtab ts=8 sts=0 sw=8:
*
* configfs_example_macros.c - This file is a demonstration module
* containing a number of configfs subsystems. It uses the helper
* macros defined by configfs.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 021110-1307, USA.
*
* Based on sysfs:
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
*
* configfs Copyright (C) 2005 Oracle. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/configfs.h>
/*
* 01-childless
*
* This first example is a childless subsystem. It cannot create
* any config_items. It just has attributes.
*
* Note that we are enclosing the configfs_subsystem inside a container.
* This is not necessary if a subsystem has no attributes directly
* on the subsystem. See the next example, 02-simple-children, for
* such a subsystem.
*/
struct childless {
struct configfs_subsystem subsys;
int showme;
int storeme;
};
static inline struct childless *to_childless(struct config_item *item)
{
return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
}
CONFIGFS_ATTR_STRUCT(childless);
#define CHILDLESS_ATTR(_name, _mode, _show, _store) \
struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store)
#define CHILDLESS_ATTR_RO(_name, _show) \
struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show);
static ssize_t childless_showme_read(struct childless *childless,
char *page)
{
ssize_t pos;
pos = sprintf(page, "%d\n", childless->showme);
childless->showme++;
return pos;
}
static ssize_t childless_storeme_read(struct childless *childless,
char *page)
{
return sprintf(page, "%d\n", childless->storeme);
}
static ssize_t childless_storeme_write(struct childless *childless,
const char *page,
size_t count)
{
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
childless->storeme = tmp;
return count;
}
static ssize_t childless_description_read(struct childless *childless,
char *page)
{
return sprintf(page,
"[01-childless]\n"
"\n"
"The childless subsystem is the simplest possible subsystem in\n"
"configfs. It does not support the creation of child config_items.\n"
"It only has a few attributes. In fact, it isn't much different\n"
"than a directory in /proc.\n");
}
CHILDLESS_ATTR_RO(showme, childless_showme_read);
CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read,
childless_storeme_write);
CHILDLESS_ATTR_RO(description, childless_description_read);
static struct configfs_attribute *childless_attrs[] = {
&childless_attr_showme.attr,
&childless_attr_storeme.attr,
&childless_attr_description.attr,
NULL,
};
CONFIGFS_ATTR_OPS(childless);
static struct configfs_item_operations childless_item_ops = {
.show_attribute = childless_attr_show,
.store_attribute = childless_attr_store,
};
static struct config_item_type childless_type = {
.ct_item_ops = &childless_item_ops,
.ct_attrs = childless_attrs,
.ct_owner = THIS_MODULE,
};
static struct childless childless_subsys = {
.subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "01-childless",
.ci_type = &childless_type,
},
},
},
};
/* ----------------------------------------------------------------- */
/*
* 02-simple-children
*
* This example merely has a simple one-attribute child. Note that
* there is no extra attribute structure, as the child's attribute is
* known from the get-go. Also, there is no container for the
* subsystem, as it has no attributes of its own.
*/
struct simple_child {
struct config_item item;
int storeme;
};
static inline struct simple_child *to_simple_child(struct config_item *item)
{
return item ? container_of(item, struct simple_child, item) : NULL;
}
static struct configfs_attribute simple_child_attr_storeme = {
.ca_owner = THIS_MODULE,
.ca_name = "storeme",
.ca_mode = S_IRUGO | S_IWUSR,
};
static struct configfs_attribute *simple_child_attrs[] = {
&simple_child_attr_storeme,
NULL,
};
static ssize_t simple_child_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
ssize_t count;
struct simple_child *simple_child = to_simple_child(item);
count = sprintf(page, "%d\n", simple_child->storeme);
return count;
}
static ssize_t simple_child_attr_store(struct config_item *item,
struct configfs_attribute *attr,
const char *page, size_t count)
{
struct simple_child *simple_child = to_simple_child(item);
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
simple_child->storeme = tmp;
return count;
}
static void simple_child_release(struct config_item *item)
{
kfree(to_simple_child(item));
}
static struct configfs_item_operations simple_child_item_ops = {
.release = simple_child_release,
.show_attribute = simple_child_attr_show,
.store_attribute = simple_child_attr_store,
};
static struct config_item_type simple_child_type = {
.ct_item_ops = &simple_child_item_ops,
.ct_attrs = simple_child_attrs,
.ct_owner = THIS_MODULE,
};
struct simple_children {
struct config_group group;
};
static inline struct simple_children *to_simple_children(struct config_item *item)
{
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
}
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
{
struct simple_child *simple_child;
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
if (!simple_child)
return ERR_PTR(-ENOMEM);
config_item_init_type_name(&simple_child->item, name,
&simple_child_type);
simple_child->storeme = 0;
return &simple_child->item;
}
static struct configfs_attribute simple_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *simple_children_attrs[] = {
&simple_children_attr_description,
NULL,
};
static ssize_t simple_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[02-simple-children]\n"
"\n"
"This subsystem allows the creation of child config_items. These\n"
"items have only one attribute that is readable and writeable.\n");
}
static void simple_children_release(struct config_item *item)
{
kfree(to_simple_children(item));
}
static struct configfs_item_operations simple_children_item_ops = {
.release = simple_children_release,
.show_attribute = simple_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations simple_children_group_ops = {
.make_item = simple_children_make_item,
};
static struct config_item_type simple_children_type = {
.ct_item_ops = &simple_children_item_ops,
.ct_group_ops = &simple_children_group_ops,
.ct_attrs = simple_children_attrs,
.ct_owner = THIS_MODULE,
};
static struct configfs_subsystem simple_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "02-simple-children",
.ci_type = &simple_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* 03-group-children
*
* This example reuses the simple_children group from above. However,
* the simple_children group is not the subsystem itself, it is a
* child of the subsystem. Creation of a group in the subsystem creates
* a new simple_children group. That group can then have simple_child
* children of its own.
*/
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
{
struct simple_children *simple_children;
simple_children = kzalloc(sizeof(struct simple_children),
GFP_KERNEL);
if (!simple_children)
return ERR_PTR(-ENOMEM);
config_group_init_type_name(&simple_children->group, name,
&simple_children_type);
return &simple_children->group;
}
static struct configfs_attribute group_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *group_children_attrs[] = {
&group_children_attr_description,
NULL,
};
static ssize_t group_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[03-group-children]\n"
"\n"
"This subsystem allows the creation of child config_groups. These\n"
"groups are like the subsystem simple-children.\n");
}
static struct configfs_item_operations group_children_item_ops = {
.show_attribute = group_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations group_children_group_ops = {
.make_group = group_children_make_group,
};
static struct config_item_type group_children_type = {
.ct_item_ops = &group_children_item_ops,
.ct_group_ops = &group_children_group_ops,
.ct_attrs = group_children_attrs,
.ct_owner = THIS_MODULE,
};
static struct configfs_subsystem group_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "03-group-children",
.ci_type = &group_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* We're now done with our subsystem definitions.
* For convenience in this module, here's a list of them all. It
* allows the init function to easily register them. Most modules
* will only have one subsystem, and will only call register_subsystem
* on it directly.
*/
static struct configfs_subsystem *example_subsys[] = {
&childless_subsys.subsys,
&simple_children_subsys,
&group_children_subsys,
NULL,
};
static int __init configfs_example_init(void)
{
int ret;
int i;
struct configfs_subsystem *subsys;
for (i = 0; example_subsys[i]; i++) {
subsys = example_subsys[i];
config_group_init(&subsys->su_group);
mutex_init(&subsys->su_mutex);
ret = configfs_register_subsystem(subsys);
if (ret) {
printk(KERN_ERR "Error %d while registering subsystem %s\n",
ret,
subsys->su_group.cg_item.ci_namebuf);
goto out_unregister;
}
}
return 0;
out_unregister:
for (; i >= 0; i--) {
configfs_unregister_subsystem(example_subsys[i]);
}
return ret;
}
static void __exit configfs_example_exit(void)
{
int i;
for (i = 0; example_subsys[i]; i++) {
configfs_unregister_subsystem(example_subsys[i]);
}
}
module_init(configfs_example_init);
module_exit(configfs_example_exit);
MODULE_LICENSE("GPL");
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
################################################################################ ################################################################################
Author: NetApp and Open Grid Computing Author: NetApp and Open Grid Computing
Date: April 15, 2008 Date: May 29, 2008
Table of Contents Table of Contents
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
...@@ -60,16 +60,18 @@ Installation ...@@ -60,16 +60,18 @@ Installation
The procedures described in this document have been tested with The procedures described in this document have been tested with
distributions from Red Hat's Fedora Project (http://fedora.redhat.com/). distributions from Red Hat's Fedora Project (http://fedora.redhat.com/).
- Install nfs-utils-1.1.1 or greater on the client - Install nfs-utils-1.1.2 or greater on the client
An NFS/RDMA mount point can only be obtained by using the mount.nfs An NFS/RDMA mount point can be obtained by using the mount.nfs command in
command in nfs-utils-1.1.1 or greater. To see which version of mount.nfs nfs-utils-1.1.2 or greater (nfs-utils-1.1.1 was the first nfs-utils
you are using, type: version with support for NFS/RDMA mounts, but for various reasons we
recommend using nfs-utils-1.1.2 or greater). To see which version of
mount.nfs you are using, type:
> /sbin/mount.nfs -V $ /sbin/mount.nfs -V
If the version is less than 1.1.1 or the command does not exist, If the version is less than 1.1.2 or the command does not exist,
then you will need to install the latest version of nfs-utils. you should install the latest version of nfs-utils.
Download the latest package from: Download the latest package from:
...@@ -77,22 +79,33 @@ Installation ...@@ -77,22 +79,33 @@ Installation
Uncompress the package and follow the installation instructions. Uncompress the package and follow the installation instructions.
If you will not be using GSS and NFSv4, the installation process If you will not need the idmapper and gssd executables (you do not need
can be simplified by disabling these features when running configure: these to create an NFS/RDMA enabled mount command), the installation
process can be simplified by disabling these features when running
configure:
> ./configure --disable-gss --disable-nfsv4 $ ./configure --disable-gss --disable-nfsv4
For more information on this see the package's README and INSTALL files. To build nfs-utils you will need the tcp_wrappers package installed. For
more information on this see the package's README and INSTALL files.
After building the nfs-utils package, there will be a mount.nfs binary in After building the nfs-utils package, there will be a mount.nfs binary in
the utils/mount directory. This binary can be used to initiate NFS v2, v3, the utils/mount directory. This binary can be used to initiate NFS v2, v3,
or v4 mounts. To initiate a v4 mount, the binary must be called mount.nfs4. or v4 mounts. To initiate a v4 mount, the binary must be called
The standard technique is to create a symlink called mount.nfs4 to mount.nfs. mount.nfs4. The standard technique is to create a symlink called
mount.nfs4 to mount.nfs.
NOTE: mount.nfs and therefore nfs-utils-1.1.1 or greater is only needed This mount.nfs binary should be installed at /sbin/mount.nfs as follows:
$ sudo cp utils/mount/mount.nfs /sbin/mount.nfs
In this location, mount.nfs will be invoked automatically for NFS mounts
by the system mount commmand.
NOTE: mount.nfs and therefore nfs-utils-1.1.2 or greater is only needed
on the NFS client machine. You do not need this specific version of on the NFS client machine. You do not need this specific version of
nfs-utils on the server. Furthermore, only the mount.nfs command from nfs-utils on the server. Furthermore, only the mount.nfs command from
nfs-utils-1.1.1 is needed on the client. nfs-utils-1.1.2 is needed on the client.
- Install a Linux kernel with NFS/RDMA - Install a Linux kernel with NFS/RDMA
...@@ -156,8 +169,8 @@ Check RDMA and NFS Setup ...@@ -156,8 +169,8 @@ Check RDMA and NFS Setup
this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel
card: card:
> modprobe ib_mthca $ modprobe ib_mthca
> modprobe ib_ipoib $ modprobe ib_ipoib
If you are using InfiniBand, make sure there is a Subnet Manager (SM) If you are using InfiniBand, make sure there is a Subnet Manager (SM)
running on the network. If your IB switch has an embedded SM, you can running on the network. If your IB switch has an embedded SM, you can
...@@ -166,7 +179,7 @@ Check RDMA and NFS Setup ...@@ -166,7 +179,7 @@ Check RDMA and NFS Setup
If an SM is running on your network, you should see the following: If an SM is running on your network, you should see the following:
> cat /sys/class/infiniband/driverX/ports/1/state $ cat /sys/class/infiniband/driverX/ports/1/state
4: ACTIVE 4: ACTIVE
where driverX is mthca0, ipath5, ehca3, etc. where driverX is mthca0, ipath5, ehca3, etc.
...@@ -174,10 +187,10 @@ Check RDMA and NFS Setup ...@@ -174,10 +187,10 @@ Check RDMA and NFS Setup
To further test the InfiniBand software stack, use IPoIB (this To further test the InfiniBand software stack, use IPoIB (this
assumes you have two IB hosts named host1 and host2): assumes you have two IB hosts named host1 and host2):
host1> ifconfig ib0 a.b.c.x host1$ ifconfig ib0 a.b.c.x
host2> ifconfig ib0 a.b.c.y host2$ ifconfig ib0 a.b.c.y
host1> ping a.b.c.y host1$ ping a.b.c.y
host2> ping a.b.c.x host2$ ping a.b.c.x
For other device types, follow the appropriate procedures. For other device types, follow the appropriate procedures.
...@@ -202,11 +215,11 @@ NFS/RDMA Setup ...@@ -202,11 +215,11 @@ NFS/RDMA Setup
/vol0 192.168.0.47(fsid=0,rw,async,insecure,no_root_squash) /vol0 192.168.0.47(fsid=0,rw,async,insecure,no_root_squash)
/vol0 192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash) /vol0 192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash)
The IP address(es) is(are) the client's IPoIB address for an InfiniBand HCA or the The IP address(es) is(are) the client's IPoIB address for an InfiniBand
cleint's iWARP address(es) for an RNIC. HCA or the cleint's iWARP address(es) for an RNIC.
NOTE: The "insecure" option must be used because the NFS/RDMA client does not NOTE: The "insecure" option must be used because the NFS/RDMA client does
use a reserved port. not use a reserved port.
Each time a machine boots: Each time a machine boots:
...@@ -214,43 +227,45 @@ NFS/RDMA Setup ...@@ -214,43 +227,45 @@ NFS/RDMA Setup
For InfiniBand using a Mellanox adapter: For InfiniBand using a Mellanox adapter:
> modprobe ib_mthca $ modprobe ib_mthca
> modprobe ib_ipoib $ modprobe ib_ipoib
> ifconfig ib0 a.b.c.d $ ifconfig ib0 a.b.c.d
NOTE: use unique addresses for the client and server NOTE: use unique addresses for the client and server
- Start the NFS server - Start the NFS server
If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in kernel config), If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
load the RDMA transport module: kernel config), load the RDMA transport module:
> modprobe svcrdma $ modprobe svcrdma
Regardless of how the server was built (module or built-in), start the server: Regardless of how the server was built (module or built-in), start the
server:
> /etc/init.d/nfs start $ /etc/init.d/nfs start
or or
> service nfs start $ service nfs start
Instruct the server to listen on the RDMA transport: Instruct the server to listen on the RDMA transport:
> echo rdma 2050 > /proc/fs/nfsd/portlist $ echo rdma 2050 > /proc/fs/nfsd/portlist
- On the client system - On the client system
If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in kernel config), If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
load the RDMA client module: kernel config), load the RDMA client module:
> modprobe xprtrdma.ko $ modprobe xprtrdma.ko
Regardless of how the client was built (module or built-in), issue the mount.nfs command: Regardless of how the client was built (module or built-in), use this
command to mount the NFS/RDMA server:
> /path/to/your/mount.nfs <IPoIB-server-name-or-address>:/<export> /mnt -i -o rdma,port=2050 $ mount -o rdma,port=2050 <IPoIB-server-name-or-address>:/<export> /mnt
To verify that the mount is using RDMA, run "cat /proc/mounts" and check the To verify that the mount is using RDMA, run "cat /proc/mounts" and check
"proto" field for the given mount. the "proto" field for the given mount.
Congratulations! You're using NFS/RDMA! Congratulations! You're using NFS/RDMA!
Optimized MPEG Filesystem (OMFS)
Overview
========
OMFS is a filesystem created by SonicBlue for use in the ReplayTV DVR
and Rio Karma MP3 player. The filesystem is extent-based, utilizing
block sizes from 2k to 8k, with hash-based directories. This
filesystem driver may be used to read and write disks from these
devices.
Note, it is not recommended that this FS be used in place of a general
filesystem for your own streaming media device. Native Linux filesystems
will likely perform better.
More information is available at:
http://linux-karma.sf.net/
Various utilities, including mkomfs and omfsck, are included with
omfsprogs, available at:
http://bobcopeland.com/karma/
Instructions are included in its README.
Options
=======
OMFS supports the following mount-time options:
uid=n - make all files owned by specified user
gid=n - make all files owned by specified group
umask=xxx - set permission umask to xxx
fmask=xxx - set umask to xxx for files
dmask=xxx - set umask to xxx for directories
Disk format
===========
OMFS discriminates between "sysblocks" and normal data blocks. The sysblock
group consists of super block information, file metadata, directory structures,
and extents. Each sysblock has a header containing CRCs of the entire
sysblock, and may be mirrored in successive blocks on the disk. A sysblock may
have a smaller size than a data block, but since they are both addressed by the
same 64-bit block number, any remaining space in the smaller sysblock is
unused.
Sysblock header information:
struct omfs_header {
__be64 h_self; /* FS block where this is located */
__be32 h_body_size; /* size of useful data after header */
__be16 h_crc; /* crc-ccitt of body_size bytes */
char h_fill1[2];
u8 h_version; /* version, always 1 */
char h_type; /* OMFS_INODE_X */
u8 h_magic; /* OMFS_IMAGIC */
u8 h_check_xor; /* XOR of header bytes before this */
__be32 h_fill2;
};
Files and directories are both represented by omfs_inode:
struct omfs_inode {
struct omfs_header i_head; /* header */
__be64 i_parent; /* parent containing this inode */
__be64 i_sibling; /* next inode in hash bucket */
__be64 i_ctime; /* ctime, in milliseconds */
char i_fill1[35];
char i_type; /* OMFS_[DIR,FILE] */
__be32 i_fill2;
char i_fill3[64];
char i_name[OMFS_NAMELEN]; /* filename */
__be64 i_size; /* size of file, in bytes */
};
Directories in OMFS are implemented as a large hash table. Filenames are
hashed then prepended into the bucket list beginning at OMFS_DIR_START.
Lookup requires hashing the filename, then seeking across i_sibling pointers
until a match is found on i_name. Empty buckets are represented by block
pointers with all-1s (~0).
A file is an omfs_inode structure followed by an extent table beginning at
OMFS_EXTENT_START:
struct omfs_extent_entry {
__be64 e_cluster; /* start location of a set of blocks */
__be64 e_blocks; /* number of blocks after e_cluster */
};
struct omfs_extent {
__be64 e_next; /* next extent table location */
__be32 e_extent_count; /* total # extents in this table */
__be32 e_fill;
struct omfs_extent_entry e_entry; /* start of extent entries */
};
Each extent holds the block offset followed by number of blocks allocated to
the extent. The final extent in each table is a terminator with e_cluster
being ~0 and e_blocks being ones'-complement of the total number of blocks
in the table.
If this table overflows, a continuation inode is written and pointed to by
e_next. These have a header but lack the rest of the inode structure.
...@@ -296,6 +296,7 @@ Table 1-4: Kernel info in /proc ...@@ -296,6 +296,7 @@ Table 1-4: Kernel info in /proc
uptime System uptime uptime System uptime
version Kernel version version Kernel version
video bttv info of video resources (2.4) video bttv info of video resources (2.4)
vmallocinfo Show vmalloced areas
.............................................................................. ..............................................................................
You can, for example, check which interrupts are currently in use and what You can, for example, check which interrupts are currently in use and what
...@@ -557,6 +558,49 @@ VmallocTotal: total size of vmalloc memory area ...@@ -557,6 +558,49 @@ VmallocTotal: total size of vmalloc memory area
VmallocUsed: amount of vmalloc area which is used VmallocUsed: amount of vmalloc area which is used
VmallocChunk: largest contigious block of vmalloc area which is free VmallocChunk: largest contigious block of vmalloc area which is free
..............................................................................
vmallocinfo:
Provides information about vmalloced/vmaped areas. One line per area,
containing the virtual address range of the area, size in bytes,
caller information of the creator, and optional information depending
on the kind of area :
pages=nr number of pages
phys=addr if a physical address was specified
ioremap I/O mapping (ioremap() and friends)
vmalloc vmalloc() area
vmap vmap()ed pages
user VM_USERMAP area
vpages buffer for pages pointers was vmalloced (huge area)
N<node>=nr (Only on NUMA kernels)
Number of pages allocated on memory node <node>
> cat /proc/vmallocinfo
0xffffc20000000000-0xffffc20000201000 2101248 alloc_large_system_hash+0x204 ...
/0x2c0 pages=512 vmalloc N0=128 N1=128 N2=128 N3=128
0xffffc20000201000-0xffffc20000302000 1052672 alloc_large_system_hash+0x204 ...
/0x2c0 pages=256 vmalloc N0=64 N1=64 N2=64 N3=64
0xffffc20000302000-0xffffc20000304000 8192 acpi_tb_verify_table+0x21/0x4f...
phys=7fee8000 ioremap
0xffffc20000304000-0xffffc20000307000 12288 acpi_tb_verify_table+0x21/0x4f...
phys=7fee7000 ioremap
0xffffc2000031d000-0xffffc2000031f000 8192 init_vdso_vars+0x112/0x210
0xffffc2000031f000-0xffffc2000032b000 49152 cramfs_uncompress_init+0x2e ...
/0x80 pages=11 vmalloc N0=3 N1=3 N2=2 N3=3
0xffffc2000033a000-0xffffc2000033d000 12288 sys_swapon+0x640/0xac0 ...
pages=2 vmalloc N1=2
0xffffc20000347000-0xffffc2000034c000 20480 xt_alloc_table_info+0xfe ...
/0x130 [x_tables] pages=4 vmalloc N0=4
0xffffffffa0000000-0xffffffffa000f000 61440 sys_init_module+0xc27/0x1d00 ...
pages=14 vmalloc N2=14
0xffffffffa000f000-0xffffffffa0014000 20480 sys_init_module+0xc27/0x1d00 ...
pages=4 vmalloc N1=4
0xffffffffa0014000-0xffffffffa0017000 12288 sys_init_module+0xc27/0x1d00 ...
pages=2 vmalloc N1=2
0xffffffffa0017000-0xffffffffa0022000 45056 sys_init_module+0xc27/0x1d00 ...
pages=10 vmalloc N0=10
1.3 IDE devices in /proc/ide 1.3 IDE devices in /proc/ide
---------------------------- ----------------------------
...@@ -887,7 +931,7 @@ group_prealloc max_to_scan mb_groups mb_history min_to_scan order2_req ...@@ -887,7 +931,7 @@ group_prealloc max_to_scan mb_groups mb_history min_to_scan order2_req
stats stream_req stats stream_req
mb_groups: mb_groups:
This file gives the details of mutiblock allocator buddy cache of free blocks This file gives the details of multiblock allocator buddy cache of free blocks
mb_history: mb_history:
Multiblock allocation history. Multiblock allocation history.
...@@ -1430,7 +1474,7 @@ used because pages_free(1355) is smaller than watermark + protection[2] ...@@ -1430,7 +1474,7 @@ used because pages_free(1355) is smaller than watermark + protection[2]
normal page requirement. If requirement is DMA zone(index=0), protection[0] normal page requirement. If requirement is DMA zone(index=0), protection[0]
(=0) is used. (=0) is used.
zone[i]'s protection[j] is calculated by following exprssion. zone[i]'s protection[j] is calculated by following expression.
(i < j): (i < j):
zone[i]->protection[j] zone[i]->protection[j]
......
...@@ -294,6 +294,16 @@ user-defined data with a channel, and is immediately available ...@@ -294,6 +294,16 @@ user-defined data with a channel, and is immediately available
(including in create_buf_file()) via chan->private_data or (including in create_buf_file()) via chan->private_data or
buf->chan->private_data. buf->chan->private_data.
Buffer-only channels
--------------------
These channels have no files associated and can be created with
relay_open(NULL, NULL, ...). Such channels are useful in scenarios such
as when doing early tracing in the kernel, before the VFS is up. In these
cases, one may open a buffer-only channel and then call
relay_late_setup_files() when the kernel is ready to handle files,
to expose the buffered data to the userspace.
Channel 'modes' Channel 'modes'
--------------- ---------------
......
...@@ -248,6 +248,7 @@ The top level sysfs directory looks like: ...@@ -248,6 +248,7 @@ The top level sysfs directory looks like:
block/ block/
bus/ bus/
class/ class/
dev/
devices/ devices/
firmware/ firmware/
net/ net/
...@@ -274,6 +275,11 @@ fs/ contains a directory for some filesystems. Currently each ...@@ -274,6 +275,11 @@ fs/ contains a directory for some filesystems. Currently each
filesystem wanting to export attributes must create its own hierarchy filesystem wanting to export attributes must create its own hierarchy
below fs/ (see ./fuse.txt for an example). below fs/ (see ./fuse.txt for an example).
dev/ contains two directories char/ and block/. Inside these two
directories there are symlinks named <major>:<minor>. These symlinks
point to the sysfs directory for the given device. /sys/dev provides a
quick way to lookup the sysfs interface for a device from the result of
a stat(2) operation.
More information can driver-model specific features can be found in More information can driver-model specific features can be found in
Documentation/driver-model/. Documentation/driver-model/.
......
...@@ -96,6 +96,14 @@ shortname=lower|win95|winnt|mixed ...@@ -96,6 +96,14 @@ shortname=lower|win95|winnt|mixed
emulate the Windows 95 rule for create. emulate the Windows 95 rule for create.
Default setting is `lower'. Default setting is `lower'.
tz=UTC -- Interpret timestamps as UTC rather than local time.
This option disables the conversion of timestamps
between local time (as used by Windows on FAT) and UTC
(which Linux uses internally). This is particuluarly
useful when mounting devices (like digital cameras)
that are set to UTC in order to avoid the pitfalls of
local time.
<bool>: 0,1,yes,no,true,false <bool>: 0,1,yes,no,true,false
TODO TODO
......
...@@ -143,7 +143,7 @@ struct file_system_type { ...@@ -143,7 +143,7 @@ struct file_system_type {
The get_sb() method has the following arguments: The get_sb() method has the following arguments:
struct file_system_type *fs_type: decribes the filesystem, partly initialized struct file_system_type *fs_type: describes the filesystem, partly initialized
by the specific filesystem code by the specific filesystem code
int flags: mount flags int flags: mount flags
...@@ -895,9 +895,9 @@ struct dentry_operations { ...@@ -895,9 +895,9 @@ struct dentry_operations {
iput() yourself iput() yourself
d_dname: called when the pathname of a dentry should be generated. d_dname: called when the pathname of a dentry should be generated.
Usefull for some pseudo filesystems (sockfs, pipefs, ...) to delay Useful for some pseudo filesystems (sockfs, pipefs, ...) to delay
pathname generation. (Instead of doing it when dentry is created, pathname generation. (Instead of doing it when dentry is created,
its done only when the path is needed.). Real filesystems probably it's done only when the path is needed.). Real filesystems probably
dont want to use it, because their dentries are present in global dont want to use it, because their dentries are present in global
dcache hash, so their hash should be an invariant. As no lock is dcache hash, so their hash should be an invariant. As no lock is
held, d_dname() should not try to modify the dentry itself, unless held, d_dname() should not try to modify the dentry itself, unless
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
Copyright 2008 Red Hat Inc. Copyright 2008 Red Hat Inc.
Author: Steven Rostedt <srostedt@redhat.com> Author: Steven Rostedt <srostedt@redhat.com>
License: The GNU Free Documentation License, Version 1.2 License: The GNU Free Documentation License, Version 1.2
(dual licensed under the GPL v2)
Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton, Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton,
John Kacur, and David Teigland. John Kacur, and David Teigland.
......
...@@ -347,15 +347,12 @@ necessarily be nonportable. ...@@ -347,15 +347,12 @@ necessarily be nonportable.
Dynamic definition of GPIOs is not currently standard; for example, as Dynamic definition of GPIOs is not currently standard; for example, as
a side effect of configuring an add-on board with some GPIO expanders. a side effect of configuring an add-on board with some GPIO expanders.
These calls are purely for kernel space, but a userspace API could be built
on top of them.
GPIO implementor's framework (OPTIONAL) GPIO implementor's framework (OPTIONAL)
======================================= =======================================
As noted earlier, there is an optional implementation framework making it As noted earlier, there is an optional implementation framework making it
easier for platforms to support different kinds of GPIO controller using easier for platforms to support different kinds of GPIO controller using
the same programming interface. the same programming interface. This framework is called "gpiolib".
As a debugging aid, if debugfs is available a /sys/kernel/debug/gpio file As a debugging aid, if debugfs is available a /sys/kernel/debug/gpio file
will be found there. That will list all the controllers registered through will be found there. That will list all the controllers registered through
...@@ -392,11 +389,21 @@ either NULL or the label associated with that GPIO when it was requested. ...@@ -392,11 +389,21 @@ either NULL or the label associated with that GPIO when it was requested.
Platform Support Platform Support
---------------- ----------------
To support this framework, a platform's Kconfig will "select HAVE_GPIO_LIB" To support this framework, a platform's Kconfig will "select" either
ARCH_REQUIRE_GPIOLIB or ARCH_WANT_OPTIONAL_GPIOLIB
and arrange that its <asm/gpio.h> includes <asm-generic/gpio.h> and defines and arrange that its <asm/gpio.h> includes <asm-generic/gpio.h> and defines
three functions: gpio_get_value(), gpio_set_value(), and gpio_cansleep(). three functions: gpio_get_value(), gpio_set_value(), and gpio_cansleep().
They may also want to provide a custom value for ARCH_NR_GPIOS. They may also want to provide a custom value for ARCH_NR_GPIOS.
ARCH_REQUIRE_GPIOLIB means that the gpio-lib code will always get compiled
into the kernel on that architecture.
ARCH_WANT_OPTIONAL_GPIOLIB means the gpio-lib code defaults to off and the user
can enable it and build it into the kernel optionally.
If neither of these options are selected, the platform does not support
GPIOs through GPIO-lib and the code cannot be enabled by the user.
Trivial implementations of those functions can directly use framework Trivial implementations of those functions can directly use framework
code, which always dispatches through the gpio_chip: code, which always dispatches through the gpio_chip:
...@@ -439,4 +446,120 @@ becomes available. That may mean the device should not be registered until ...@@ -439,4 +446,120 @@ becomes available. That may mean the device should not be registered until
calls for that GPIO can work. One way to address such dependencies is for calls for that GPIO can work. One way to address such dependencies is for
such gpio_chip controllers to provide setup() and teardown() callbacks to such gpio_chip controllers to provide setup() and teardown() callbacks to
board specific code; those board specific callbacks would register devices board specific code; those board specific callbacks would register devices
once all the necessary resources are available. once all the necessary resources are available, and remove them later when
the GPIO controller device becomes unavailable.
Sysfs Interface for Userspace (OPTIONAL)
========================================
Platforms which use the "gpiolib" implementors framework may choose to
configure a sysfs user interface to GPIOs. This is different from the
debugfs interface, since it provides control over GPIO direction and
value instead of just showing a gpio state summary. Plus, it could be
present on production systems without debugging support.
Given approprate hardware documentation for the system, userspace could
know for example that GPIO #23 controls the write protect line used to
protect boot loader segments in flash memory. System upgrade procedures
may need to temporarily remove that protection, first importing a GPIO,
then changing its output state, then updating the code before re-enabling
the write protection. In normal use, GPIO #23 would never be touched,
and the kernel would have no need to know about it.
Again depending on appropriate hardware documentation, on some systems
userspace GPIO can be used to determine system configuration data that
standard kernels won't know about. And for some tasks, simple userspace
GPIO drivers could be all that the system really needs.
Note that standard kernel drivers exist for common "LEDs and Buttons"
GPIO tasks: "leds-gpio" and "gpio_keys", respectively. Use those
instead of talking directly to the GPIOs; they integrate with kernel
frameworks better than your userspace code could.
Paths in Sysfs
--------------
There are three kinds of entry in /sys/class/gpio:
- Control interfaces used to get userspace control over GPIOs;
- GPIOs themselves; and
- GPIO controllers ("gpio_chip" instances).
That's in addition to standard files including the "device" symlink.
The control interfaces are write-only:
/sys/class/gpio/
"export" ... Userspace may ask the kernel to export control of
a GPIO to userspace by writing its number to this file.
Example: "echo 19 > export" will create a "gpio19" node
for GPIO #19, if that's not requested by kernel code.
"unexport" ... Reverses the effect of exporting to userspace.
Example: "echo 19 > unexport" will remove a "gpio19"
node exported using the "export" file.
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
and have the following read/write attributes:
/sys/class/gpio/gpioN/
"direction" ... reads as either "in" or "out". This value may
normally be written. Writing as "out" defaults to
initializing the value as low. To ensure glitch free
operation, values "low" and "high" may be written to
configure the GPIO as an output with that initial value.
Note that this attribute *will not exist* if the kernel
doesn't support changing the direction of a GPIO, or
it was exported by kernel code that didn't explicitly
allow userspace to reconfigure this GPIO's direction.
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
GPIO controllers have paths like /sys/class/gpio/chipchip42/ (for the
controller implementing GPIOs starting at #42) and have the following
read-only attributes:
/sys/class/gpio/gpiochipN/
"base" ... same as N, the first GPIO managed by this chip
"label" ... provided for diagnostics (not always unique)
"ngpio" ... how many GPIOs this manges (N to N + ngpio - 1)
Board documentation should in most cases cover what GPIOs are used for
what purposes. However, those numbers are not always stable; GPIOs on
a daughtercard might be different depending on the base board being used,
or other cards in the stack. In such cases, you may need to use the
gpiochip nodes (possibly in conjunction with schematics) to determine
the correct GPIO number to use for a given signal.
Exporting from Kernel code
--------------------------
Kernel code can explicitly manage exports of GPIOs which have already been
requested using gpio_request():
/* export the GPIO to userspace */
int gpio_export(unsigned gpio, bool direction_may_change);
/* reverse gpio_export() */
void gpio_unexport();
After a kernel driver requests a GPIO, it may only be made available in
the sysfs interface by gpio_export(). The driver can control whether the
signal direction may change. This helps drivers prevent userspace code
from accidentally clobbering important system state.
This explicit exporting can help with debugging (by making some kinds
of experiments easier), or can provide an always-there interface that's
suitable for documenting as part of a board support package.
...@@ -10,6 +10,10 @@ Supported chips: ...@@ -10,6 +10,10 @@ Supported chips:
Prefix: 'sch311x' Prefix: 'sch311x'
Addresses scanned: none, address read from Super-I/O config space Addresses scanned: none, address read from Super-I/O config space
Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf
* SMSC SCH5027
Prefix: 'sch5027'
Addresses scanned: I2C 0x2c, 0x2d, 0x2e
Datasheet: Provided by SMSC upon request and under NDA
Authors: Authors:
Juerg Haefliger <juergh@gmail.com> Juerg Haefliger <juergh@gmail.com>
...@@ -22,34 +26,36 @@ Module Parameters ...@@ -22,34 +26,36 @@ Module Parameters
and PWM output control functions. Using this parameter and PWM output control functions. Using this parameter
shouldn't be required since the BIOS usually takes care shouldn't be required since the BIOS usually takes care
of this. of this.
* probe_all_addr: bool Include non-standard LPC addresses 0x162e and 0x164e
Note that there is no need to use this parameter if the driver loads without when probing for ISA devices. This is required for the
complaining. The driver will say so if it is necessary. following boards:
- VIA EPIA SN18000
Description Description
----------- -----------
This driver implements support for the hardware monitoring capabilities of the This driver implements support for the hardware monitoring capabilities of the
SMSC DME1737 and Asus A8000 (which are the same) and SMSC SCH311x Super-I/O SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, and SMSC
chips. These chips feature monitoring of 3 temp sensors temp[1-3] (2 remote SCH311x Super-I/O chips. These chips feature monitoring of 3 temp sensors
diodes and 1 internal), 7 voltages in[0-6] (6 external and 1 internal) and up temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and
to 6 fan speeds fan[1-6]. Additionally, the chips implement up to 5 PWM 1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement
outputs pwm[1-3,5-6] for controlling fan speeds both manually and up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and
automatically. automatically.
For the DME1737 and A8000, fan[1-2] and pwm[1-2] are always present. Fan[3-6] For the DME1737, A8000 and SCH5027, fan[1-2] and pwm[1-2] are always present.
and pwm[3,5-6] are optional features and their availability depends on the Fan[3-6] and pwm[3,5-6] are optional features and their availability depends on
configuration of the chip. The driver will detect which features are present the configuration of the chip. The driver will detect which features are
during initialization and create the sysfs attributes accordingly. present during initialization and create the sysfs attributes accordingly.
For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and
pwm[5-6] don't exist. pwm[5-6] don't exist.
The hardware monitoring features of the DME1737 and A8000 are only accessible The hardware monitoring features of the DME1737, A8000, and SCH5027 are only
via SMBus, while the SCH311x only provides access via the ISA bus. The driver accessible via SMBus, while the SCH311x only provides access via the ISA bus.
will therefore register itself as an I2C client driver if it detects a DME1737 The driver will therefore register itself as an I2C client driver if it detects
or A8000 and as a platform driver if it detects a SCH311x chip. a DME1737, A8000, or SCH5027 and as a platform driver if it detects a SCH311x
chip.
Voltage Monitoring Voltage Monitoring
...@@ -60,6 +66,7 @@ scaling resistors. The values returned by the driver therefore reflect true ...@@ -60,6 +66,7 @@ scaling resistors. The values returned by the driver therefore reflect true
millivolts and don't need scaling. The voltage inputs are mapped as follows millivolts and don't need scaling. The voltage inputs are mapped as follows
(the last column indicates the input ranges): (the last column indicates the input ranges):
DME1737, A8000:
in0: +5VTR (+5V standby) 0V - 6.64V in0: +5VTR (+5V standby) 0V - 6.64V
in1: Vccp (processor core) 0V - 3V in1: Vccp (processor core) 0V - 3V
in2: VCC (internal +3.3V) 0V - 4.38V in2: VCC (internal +3.3V) 0V - 4.38V
...@@ -68,6 +75,24 @@ millivolts and don't need scaling. The voltage inputs are mapped as follows ...@@ -68,6 +75,24 @@ millivolts and don't need scaling. The voltage inputs are mapped as follows
in5: VTR (+3.3V standby) 0V - 4.38V in5: VTR (+3.3V standby) 0V - 4.38V
in6: Vbat (+3.0V) 0V - 4.38V in6: Vbat (+3.0V) 0V - 4.38V
SCH311x:
in0: +2.5V 0V - 6.64V
in1: Vccp (processor core) 0V - 2V
in2: VCC (internal +3.3V) 0V - 4.38V
in3: +5V 0V - 6.64V
in4: +12V 0V - 16V
in5: VTR (+3.3V standby) 0V - 4.38V
in6: Vbat (+3.0V) 0V - 4.38V
SCH5027:
in0: +5VTR (+5V standby) 0V - 6.64V
in1: Vccp (processor core) 0V - 3V
in2: VCC (internal +3.3V) 0V - 4.38V
in3: V2_IN 0V - 1.5V
in4: V1_IN 0V - 1.5V
in5: VTR (+3.3V standby) 0V - 4.38V
in6: Vbat (+3.0V) 0V - 4.38V
Each voltage input has associated min and max limits which trigger an alarm Each voltage input has associated min and max limits which trigger an alarm
when crossed. when crossed.
......
...@@ -6,12 +6,14 @@ Supported chips: ...@@ -6,12 +6,14 @@ Supported chips:
Prefix: 'it87' Prefix: 'it87'
Addresses scanned: from Super I/O config space (8 I/O ports) Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Publicly available at the ITE website Datasheet: Publicly available at the ITE website
http://www.ite.com.tw/ http://www.ite.com.tw/product_info/file/pc/IT8705F_V.0.4.1.pdf
* IT8712F * IT8712F
Prefix: 'it8712' Prefix: 'it8712'
Addresses scanned: from Super I/O config space (8 I/O ports) Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Publicly available at the ITE website Datasheet: Publicly available at the ITE website
http://www.ite.com.tw/ http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.1.pdf
http://www.ite.com.tw/product_info/file/pc/Errata%20V0.1%20for%20IT8712F%20V0.9.1.pdf
http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.3.pdf
* IT8716F/IT8726F * IT8716F/IT8726F
Prefix: 'it8716' Prefix: 'it8716'
Addresses scanned: from Super I/O config space (8 I/O ports) Addresses scanned: from Super I/O config space (8 I/O ports)
...@@ -90,14 +92,13 @@ upper VID bits share their pins with voltage inputs (in5 and in6) so you ...@@ -90,14 +92,13 @@ upper VID bits share their pins with voltage inputs (in5 and in6) so you
can't have both on a given board. can't have both on a given board.
The IT8716F, IT8718F and later IT8712F revisions have support for The IT8716F, IT8718F and later IT8712F revisions have support for
2 additional fans. They are supported by the driver for the IT8716F and 2 additional fans. The additional fans are supported by the driver.
IT8718F but not for the IT8712F
The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional
16-bit tachometer counters for fans 1 to 3. This is better (no more fan 16-bit tachometer counters for fans 1 to 3. This is better (no more fan
clock divider mess) but not compatible with the older chips and clock divider mess) but not compatible with the older chips and
revisions. For now, the driver only uses the 16-bit mode on the revisions. The 16-bit tachometer mode is enabled by the driver when one
IT8716F and IT8718F. of the above chips is detected.
The IT8726F is just bit enhanced IT8716F with additional hardware The IT8726F is just bit enhanced IT8716F with additional hardware
for AMD power sequencing. Therefore the chip will appear as IT8716F for AMD power sequencing. Therefore the chip will appear as IT8716F
......
...@@ -96,11 +96,6 @@ initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has ...@@ -96,11 +96,6 @@ initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has
confirmed this "bug". The ADT7463 is reported to work as described in the confirmed this "bug". The ADT7463 is reported to work as described in the
documentation. The current lm85 driver does not show the offset register. documentation. The current lm85 driver does not show the offset register.
The ADT7463 has a THERM asserted counter. This counter has a 22.76ms
resolution and a range of 5.8 seconds. The driver implements a 32-bit
accumulator of the counter value to extend the range to over a year. The
counter will stay at it's max value until read.
See the vendor datasheets for more information. There is application note See the vendor datasheets for more information. There is application note
from National (AN-1260) with some additional information about the LM85. from National (AN-1260) with some additional information about the LM85.
The Analog Devices datasheet is very detailed and describes a procedure for The Analog Devices datasheet is very detailed and describes a procedure for
...@@ -206,13 +201,15 @@ Configuration choices: ...@@ -206,13 +201,15 @@ Configuration choices:
The National LM85's have two vendor specific configuration The National LM85's have two vendor specific configuration
features. Tach. mode and Spinup Control. For more details on these, features. Tach. mode and Spinup Control. For more details on these,
see the LM85 datasheet or Application Note AN-1260. see the LM85 datasheet or Application Note AN-1260. These features
are not currently supported by the lm85 driver.
The Analog Devices ADM1027 has several vendor specific enhancements. The Analog Devices ADM1027 has several vendor specific enhancements.
The number of pulses-per-rev of the fans can be set, Tach monitoring The number of pulses-per-rev of the fans can be set, Tach monitoring
can be optimized for PWM operation, and an offset can be applied to can be optimized for PWM operation, and an offset can be applied to
the temperatures to compensate for systemic errors in the the temperatures to compensate for systemic errors in the
measurements. measurements. These features are not currently supported by the lm85
driver.
In addition to the ADM1027 features, the ADT7463 also has Tmin control In addition to the ADM1027 features, the ADT7463 also has Tmin control
and THERM asserted counts. Automatic Tmin control acts to adjust the and THERM asserted counts. Automatic Tmin control acts to adjust the
......
...@@ -40,10 +40,6 @@ Module Parameters ...@@ -40,10 +40,6 @@ Module Parameters
(default is 1) (default is 1)
Use 'init=0' to bypass initializing the chip. Use 'init=0' to bypass initializing the chip.
Try this if your computer crashes when you load the module. Try this if your computer crashes when you load the module.
* reset: int
(default is 0)
The driver used to reset the chip on load, but does no more. Use
'reset=1' to restore the old behavior. Report if you need to do this.
Description Description
----------- -----------
......
...@@ -22,6 +22,7 @@ Credits: ...@@ -22,6 +22,7 @@ Credits:
Additional contributors: Additional contributors:
Sven Anders <anders@anduras.de> Sven Anders <anders@anduras.de>
Marc Hulsman <m.hulsman@tudelft.nl>
Module Parameters Module Parameters
----------------- -----------------
...@@ -67,9 +68,8 @@ on until the temperature falls below the Hysteresis value. ...@@ -67,9 +68,8 @@ on until the temperature falls below the Hysteresis value.
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
triggered if the rotation speed has dropped below a programmable limit. Fan triggered if the rotation speed has dropped below a programmable limit. Fan
readings can be divided by a programmable divider (1, 2, 4, 8 for fan 1/2/3 readings can be divided by a programmable divider (1, 2, 4, 8, 16,
and 1, 2, 4, 8, 16, 32, 64 or 128 for fan 4/5) to give the readings more 32, 64 or 128 for all fans) to give the readings more range or accuracy.
range or accuracy.
Voltage sensors (also known as IN sensors) report their values in millivolts. Voltage sensors (also known as IN sensors) report their values in millivolts.
An alarm is triggered if the voltage has crossed a programmable minimum An alarm is triggered if the voltage has crossed a programmable minimum
......
Upgrading I2C Drivers to the new 2.6 Driver Model
=================================================
Ben Dooks <ben-linux@fluff.org>
Introduction
------------
This guide outlines how to alter existing Linux 2.6 client drivers from
the old to the new new binding methods.
Example old-style driver
------------------------
struct example_state {
struct i2c_client client;
....
};
static struct i2c_driver example_driver;
static unsigned short ignore[] = { I2C_CLIENT_END };
static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
static int example_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct example_state *state;
struct device *dev = &adap->dev; /* to use for dev_ reports */
int ret;
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
if (state == NULL) {
dev_err(dev, "failed to create our state\n");
return -ENOMEM;
}
example->client.addr = addr;
example->client.flags = 0;
example->client.adapter = adap;
i2c_set_clientdata(&state->i2c_client, state);
strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
ret = i2c_attach_client(&state->i2c_client);
if (ret < 0) {
dev_err(dev, "failed to attach client\n");
kfree(state);
return ret;
}
dev = &state->i2c_client.dev;
/* rest of the initialisation goes here. */
dev_info(dev, "example client created\n");
return 0;
}
static int __devexit example_detach(struct i2c_client *client)
{
struct example_state *state = i2c_get_clientdata(client);
i2c_detach_client(client);
kfree(state);
return 0;
}
static int example_attach_adapter(struct i2c_adapter *adap)
{
return i2c_probe(adap, &addr_data, example_attach);
}
static struct i2c_driver example_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "example",
},
.attach_adapter = example_attach_adapter,
.detach_client = __devexit_p(example_detach),
.suspend = example_suspend,
.resume = example_resume,
};
Updating the client
-------------------
The new style binding model will check against a list of supported
devices and their associated address supplied by the code registering
the busses. This means that the driver .attach_adapter and
.detach_adapter methods can be removed, along with the addr_data,
as follows:
- static struct i2c_driver example_driver;
- static unsigned short ignore[] = { I2C_CLIENT_END };
- static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
- I2C_CLIENT_INSMOD;
- static int example_attach_adapter(struct i2c_adapter *adap)
- {
- return i2c_probe(adap, &addr_data, example_attach);
- }
static struct i2c_driver example_driver = {
- .attach_adapter = example_attach_adapter,
- .detach_client = __devexit_p(example_detach),
}
Add the probe and remove methods to the i2c_driver, as so:
static struct i2c_driver example_driver = {
+ .probe = example_probe,
+ .remove = __devexit_p(example_remove),
}
Change the example_attach method to accept the new parameters
which include the i2c_client that it will be working with:
- static int example_attach(struct i2c_adapter *adap, int addr, int kind)
+ static int example_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
Change the name of example_attach to example_probe to align it with the
i2c_driver entry names. The rest of the probe routine will now need to be
changed as the i2c_client has already been setup for use.
The necessary client fields have already been setup before
the probe function is called, so the following client setup
can be removed:
- example->client.addr = addr;
- example->client.flags = 0;
- example->client.adapter = adap;
-
- strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
The i2c_set_clientdata is now:
- i2c_set_clientdata(&state->client, state);
+ i2c_set_clientdata(client, state);
The call to i2c_attach_client is no longer needed, if the probe
routine exits successfully, then the driver will be automatically
attached by the core. Change the probe routine as so:
- ret = i2c_attach_client(&state->i2c_client);
- if (ret < 0) {
- dev_err(dev, "failed to attach client\n");
- kfree(state);
- return ret;
- }
Remove the storage of 'struct i2c_client' from the 'struct example_state'
as we are provided with the i2c_client in our example_probe. Instead we
store a pointer to it for when it is needed.
struct example_state {
- struct i2c_client client;
+ struct i2c_client *client;
the new i2c client as so:
- struct device *dev = &adap->dev; /* to use for dev_ reports */
+ struct device *dev = &i2c_client->dev; /* to use for dev_ reports */
And remove the change after our client is attached, as the driver no
longer needs to register a new client structure with the core:
- dev = &state->i2c_client.dev;
In the probe routine, ensure that the new state has the client stored
in it:
static int example_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
struct example_state *state;
struct device *dev = &i2c_client->dev;
int ret;
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
if (state == NULL) {
dev_err(dev, "failed to create our state\n");
return -ENOMEM;
}
+ state->client = i2c_client;
Update the detach method, by changing the name to _remove and
to delete the i2c_detach_client call. It is possible that you
can also remove the ret variable as it is not not needed for
any of the core functions.
- static int __devexit example_detach(struct i2c_client *client)
+ static int __devexit example_remove(struct i2c_client *client)
{
struct example_state *state = i2c_get_clientdata(client);
- i2c_detach_client(client);
And finally ensure that we have the correct ID table for the i2c-core
and other utilities:
+ struct i2c_device_id example_idtable[] = {
+ { "example", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, example_idtable);
static struct i2c_driver example_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "example",
},
+ .id_table = example_ids,
Our driver should now look like this:
struct example_state {
struct i2c_client *client;
....
};
static int example_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct example_state *state;
struct device *dev = &client->dev;
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
if (state == NULL) {
dev_err(dev, "failed to create our state\n");
return -ENOMEM;
}
state->client = client;
i2c_set_clientdata(client, state);
/* rest of the initialisation goes here. */
dev_info(dev, "example client created\n");
return 0;
}
static int __devexit example_remove(struct i2c_client *client)
{
struct example_state *state = i2c_get_clientdata(client);
kfree(state);
return 0;
}
static struct i2c_device_id example_idtable[] = {
{ "example", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, example_idtable);
static struct i2c_driver example_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "example",
},
.id_table = example_idtable,
.probe = example_probe,
.remove = __devexit_p(example_remove),
.suspend = example_suspend,
.resume = example_resume,
};
...@@ -50,9 +50,9 @@ Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qe ...@@ -50,9 +50,9 @@ Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qe
/usr/local/bin/qemu-system-ia64 -smp xx -m 512 -hda $your_image /usr/local/bin/qemu-system-ia64 -smp xx -m 512 -hda $your_image
(xx is the number of virtual processors for the guest, now the maximum value is 4) (xx is the number of virtual processors for the guest, now the maximum value is 4)
5. Known possibile issue on some platforms with old Firmware. 5. Known possible issue on some platforms with old Firmware.
If meet strange host crashe issues, try to solve it through either of the following ways: In the event of strange host crash issues, try to solve it through either of the following ways:
(1): Upgrade your Firmware to the latest one. (1): Upgrade your Firmware to the latest one.
...@@ -65,8 +65,8 @@ index 0b53344..f02b0f7 100644 ...@@ -65,8 +65,8 @@ index 0b53344..f02b0f7 100644
mov ar.pfs = loc1 mov ar.pfs = loc1
mov rp = loc0 mov rp = loc0
;; ;;
- srlz.d // seralize restoration of psr.l - srlz.d // serialize restoration of psr.l
+ srlz.i // seralize restoration of psr.l + srlz.i // serialize restoration of psr.l
+ ;; + ;;
br.ret.sptk.many b0 br.ret.sptk.many b0
END(ia64_pal_call_static) END(ia64_pal_call_static)
......
Paravirt_ops on IA64
====================
21 May 2008, Isaku Yamahata <yamahata@valinux.co.jp>
Introduction
------------
The aim of this documentation is to help with maintainability and/or to
encourage people to use paravirt_ops/IA64.
paravirt_ops (pv_ops in short) is a way for virtualization support of
Linux kernel on x86. Several ways for virtualization support were
proposed, paravirt_ops is the winner.
On the other hand, now there are also several IA64 virtualization
technologies like kvm/IA64, xen/IA64 and many other academic IA64
hypervisors so that it is good to add generic virtualization
infrastructure on Linux/IA64.
What is paravirt_ops?
---------------------
It has been developed on x86 as virtualization support via API, not ABI.
It allows each hypervisor to override operations which are important for
hypervisors at API level. And it allows a single kernel binary to run on
all supported execution environments including native machine.
Essentially paravirt_ops is a set of function pointers which represent
operations corresponding to low level sensitive instructions and high
level functionalities in various area. But one significant difference
from usual function pointer table is that it allows optimization with
binary patch. It is because some of these operations are very
performance sensitive and indirect call overhead is not negligible.
With binary patch, indirect C function call can be transformed into
direct C function call or in-place execution to eliminate the overhead.
Thus, operations of paravirt_ops are classified into three categories.
- simple indirect call
These operations correspond to high level functionality so that the
overhead of indirect call isn't very important.
- indirect call which allows optimization with binary patch
Usually these operations correspond to low level instructions. They
are called frequently and performance critical. So the overhead is
very important.
- a set of macros for hand written assembly code
Hand written assembly codes (.S files) also need paravirtualization
because they include sensitive instructions or some of code paths in
them are very performance critical.
The relation to the IA64 machine vector
---------------------------------------
Linux/IA64 has the IA64 machine vector functionality which allows the
kernel to switch implementations (e.g. initialization, ipi, dma api...)
depending on executing platform.
We can replace some implementations very easily defining a new machine
vector. Thus another approach for virtualization support would be
enhancing the machine vector functionality.
But paravirt_ops approach was taken because
- virtualization support needs wider support than machine vector does.
e.g. low level instruction paravirtualization. It must be
initialized very early before platform detection.
- virtualization support needs more functionality like binary patch.
Probably the calling overhead might not be very large compared to the
emulation overhead of virtualization. However in the native case, the
overhead should be eliminated completely.
A single kernel binary should run on each environment including native,
and the overhead of paravirt_ops on native environment should be as
small as possible.
- for full virtualization technology, e.g. KVM/IA64 or
Xen/IA64 HVM domain, the result would be
(the emulated platform machine vector. probably dig) + (pv_ops).
This means that the virtualization support layer should be under
the machine vector layer.
Possibly it might be better to move some function pointers from
paravirt_ops to machine vector. In fact, Xen domU case utilizes both
pv_ops and machine vector.
IA64 paravirt_ops
-----------------
In this section, the concrete paravirt_ops will be discussed.
Because of the architecture difference between ia64 and x86, the
resulting set of functions is very different from x86 pv_ops.
- C function pointer tables
They are not very performance critical so that simple C indirect
function call is acceptable. The following structures are defined at
this moment. For details see linux/include/asm-ia64/paravirt.h
- struct pv_info
This structure describes the execution environment.
- struct pv_init_ops
This structure describes the various initialization hooks.
- struct pv_iosapic_ops
This structure describes hooks to iosapic operations.
- struct pv_irq_ops
This structure describes hooks to irq related operations
- struct pv_time_op
This structure describes hooks to steal time accounting.
- a set of indirect calls which need optimization
Currently this class of functions correspond to a subset of IA64
intrinsics. At this moment the optimization with binary patch isn't
implemented yet.
struct pv_cpu_op is defined. For details see
linux/include/asm-ia64/paravirt_privop.h
Mostly they correspond to ia64 intrinsics 1-to-1.
Caveat: Now they are defined as C indirect function pointers, but in
order to support binary patch optimization, they will be changed
using GCC extended inline assembly code.
- a set of macros for hand written assembly code (.S files)
For maintenance purpose, the taken approach for .S files is single
source code and compile multiple times with different macros definitions.
Each pv_ops instance must define those macros to compile.
The important thing here is that sensitive, but non-privileged
instructions must be paravirtualized and that some privileged
instructions also need paravirtualization for reasonable performance.
Developers who modify .S files must be aware of that. At this moment
an easy checker is implemented to detect paravirtualization breakage.
But it doesn't cover all the cases.
Sometimes this set of macros is called pv_cpu_asm_op. But there is no
corresponding structure in the source code.
Those macros mostly 1:1 correspond to a subset of privileged
instructions. See linux/include/asm-ia64/native/inst.h.
And some functions written in assembly also need to be overrided so
that each pv_ops instance have to define some macros. Again see
linux/include/asm-ia64/native/inst.h.
Those structures must be initialized very early before start_kernel.
Probably initialized in head.S using multi entry point or some other trick.
For native case implementation see linux/arch/ia64/kernel/paravirt.c.
...@@ -31,7 +31,7 @@ The driver works with ALSA drivers simultaneously. For example, the xracer ...@@ -31,7 +31,7 @@ The driver works with ALSA drivers simultaneously. For example, the xracer
uses joystick as input device and PCM device as sound output in one time. uses joystick as input device and PCM device as sound output in one time.
There are no sound or input collisions detected. The source code have There are no sound or input collisions detected. The source code have
comments about them; but I've found the joystick can be initialized comments about them; but I've found the joystick can be initialized
separately of ALSA modules. So, you canm use only one joystick driver separately of ALSA modules. So, you can use only one joystick driver
without ALSA drivers. The ALSA drivers are not needed to compile or without ALSA drivers. The ALSA drivers are not needed to compile or
run this driver. run this driver.
......
$Id: gameport-programming.txt,v 1.3 2001/04/24 13:51:37 vojtech Exp $
Programming gameport drivers Programming gameport drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
Linux Input drivers v1.0 Linux Input drivers v1.0
(c) 1999-2001 Vojtech Pavlik <vojtech@ucw.cz> (c) 1999-2001 Vojtech Pavlik <vojtech@ucw.cz>
Sponsored by SuSE Sponsored by SuSE
$Id: input.txt,v 1.8 2002/05/29 03:15:01 bradleym Exp $
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
0. Disclaimer 0. Disclaimer
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
7 Aug 1998 7 Aug 1998
$Id: joystick-api.txt,v 1.2 2001/05/08 21:21:23 vojtech Exp $
1. Initialization 1. Initialization
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
(c) 1998-2000 Vojtech Pavlik <vojtech@ucw.cz> (c) 1998-2000 Vojtech Pavlik <vojtech@ucw.cz>
(c) 1998 Andree Borrmann <a.borrmann@tu-bs.de> (c) 1998 Andree Borrmann <a.borrmann@tu-bs.de>
Sponsored by SuSE Sponsored by SuSE
$Id: joystick-parport.txt,v 1.6 2001/09/25 09:31:32 vojtech Exp $
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
0. Disclaimer 0. Disclaimer
......
Linux Joystick driver v2.0.0 Linux Joystick driver v2.0.0
(c) 1996-2000 Vojtech Pavlik <vojtech@ucw.cz> (c) 1996-2000 Vojtech Pavlik <vojtech@ucw.cz>
Sponsored by SuSE Sponsored by SuSE
$Id: joystick.txt,v 1.12 2002/03/03 12:13:07 jdeneux Exp $
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
0. Disclaimer 0. Disclaimer
......
To decode a hex IOCTL code: To decode a hex IOCTL code:
Most architecures use this generic format, but check Most architectures use this generic format, but check
include/ARCH/ioctl.h for specifics, e.g. powerpc include/ARCH/ioctl.h for specifics, e.g. powerpc
uses 3 bits to encode read/write and 13 bits for size. uses 3 bits to encode read/write and 13 bits for size.
...@@ -18,7 +18,7 @@ uses 3 bits to encode read/write and 13 bits for size. ...@@ -18,7 +18,7 @@ uses 3 bits to encode read/write and 13 bits for size.
7-0 function # 7-0 function #
So for example 0x82187201 is a read with arg length of 0x218, So for example 0x82187201 is a read with arg length of 0x218,
character 'r' function 1. Grepping the source reveals this is: character 'r' function 1. Grepping the source reveals this is:
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
...@@ -143,7 +143,7 @@ disk and partition statistics are consistent again. Since we still don't ...@@ -143,7 +143,7 @@ disk and partition statistics are consistent again. Since we still don't
keep record of the partition-relative address, an operation is attributed to keep record of the partition-relative address, an operation is attributed to
the partition which contains the first sector of the request after the the partition which contains the first sector of the request after the
eventual merges. As requests can be merged across partition, this could lead eventual merges. As requests can be merged across partition, this could lead
to some (probably insignificant) innacuracy. to some (probably insignificant) inaccuracy.
Additional notes Additional notes
---------------- ----------------
......
mISDN is a new modular ISDN driver, in the long term it should replace
the old I4L driver architecture for passiv ISDN cards.
It was designed to allow a broad range of applications and interfaces
but only have the basic function in kernel, the interface to the user
space is based on sockets with a own address family AF_ISDN.
...@@ -65,26 +65,26 @@ Install kexec-tools ...@@ -65,26 +65,26 @@ Install kexec-tools
2) Download the kexec-tools user-space package from the following URL: 2) Download the kexec-tools user-space package from the following URL:
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools-testing.tar.gz http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools.tar.gz
This is a symlink to the latest version, which at the time of writing is This is a symlink to the latest version.
20061214, the only release of kexec-tools-testing so far. As other versions
are released, the older ones will remain available at
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
Note: Latest kexec-tools-testing git tree is available at The latest kexec-tools git tree is available at:
git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools-testing.git git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools.git
or or
http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools-testing.git;a=summary http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools.git
More information about kexec-tools can be found at
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/README.html
3) Unpack the tarball with the tar command, as follows: 3) Unpack the tarball with the tar command, as follows:
tar xvpzf kexec-tools-testing.tar.gz tar xvpzf kexec-tools.tar.gz
4) Change to the kexec-tools directory, as follows: 4) Change to the kexec-tools directory, as follows:
cd kexec-tools-testing-VERSION cd kexec-tools-VERSION
5) Configure the package, as follows: 5) Configure the package, as follows:
......
...@@ -87,7 +87,8 @@ parameter is applicable: ...@@ -87,7 +87,8 @@ parameter is applicable:
SH SuperH architecture is enabled. SH SuperH architecture is enabled.
SMP The kernel is an SMP kernel. SMP The kernel is an SMP kernel.
SPARC Sparc architecture is enabled. SPARC Sparc architecture is enabled.
SWSUSP Software suspend is enabled. SWSUSP Software suspend (hibernation) is enabled.
SUSPEND System suspend states are enabled.
TS Appropriate touchscreen support is enabled. TS Appropriate touchscreen support is enabled.
USB USB support is enabled. USB USB support is enabled.
USBHID USB Human Interface Device support is enabled. USBHID USB Human Interface Device support is enabled.
...@@ -147,10 +148,12 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -147,10 +148,12 @@ and is between 256 and 4096 characters. It is defined in the file
default: 0 default: 0
acpi_sleep= [HW,ACPI] Sleep options acpi_sleep= [HW,ACPI] Sleep options
Format: { s3_bios, s3_mode, s3_beep, old_ordering } Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, old_ordering }
See Documentation/power/video.txt for s3_bios and s3_mode. See Documentation/power/video.txt for s3_bios and s3_mode.
s3_beep is for debugging; it makes the PC's speaker beep s3_beep is for debugging; it makes the PC's speaker beep
as soon as the kernel's real-mode entry point is called. as soon as the kernel's real-mode entry point is called.
s4_nohwsig prevents ACPI hardware signature from being
used during resume from hibernation.
old_ordering causes the ACPI 1.0 ordering of the _PTS old_ordering causes the ACPI 1.0 ordering of the _PTS
control method, wrt putting devices into low power control method, wrt putting devices into low power
states, to be enforced (the ACPI 2.0 ordering of _PTS is states, to be enforced (the ACPI 2.0 ordering of _PTS is
...@@ -774,8 +777,22 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -774,8 +777,22 @@ and is between 256 and 4096 characters. It is defined in the file
hisax= [HW,ISDN] hisax= [HW,ISDN]
See Documentation/isdn/README.HiSax. See Documentation/isdn/README.HiSax.
hugepages= [HW,X86-32,IA-64] Maximal number of HugeTLB pages. hugepages= [HW,X86-32,IA-64] HugeTLB pages to allocate at boot.
hugepagesz= [HW,IA-64,PPC] The size of the HugeTLB pages. hugepagesz= [HW,IA-64,PPC,X86-64] The size of the HugeTLB pages.
On x86-64 and powerpc, this option can be specified
multiple times interleaved with hugepages= to reserve
huge pages of different sizes. Valid pages sizes on
x86-64 are 2M (when the CPU supports "pse") and 1G
(when the CPU supports the "pdpe1gb" cpuinfo flag)
Note that 1GB pages can only be allocated at boot time
using hugepages= and not freed afterwards.
default_hugepagesz=
[same as hugepagesz=] The size of the default
HugeTLB page size. This is the size represented by
the legacy /proc/ hugepages APIs, used for SHM, and
default size when mounting hugetlbfs filesystems.
Defaults to the default architecture's huge page size
if not specified.
i8042.direct [HW] Put keyboard port into non-translated mode i8042.direct [HW] Put keyboard port into non-translated mode
i8042.dumbkbd [HW] Pretend that controller can only read data from i8042.dumbkbd [HW] Pretend that controller can only read data from
...@@ -1206,7 +1223,7 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1206,7 +1223,7 @@ and is between 256 and 4096 characters. It is defined in the file
or or
memmap=0x10000$0x18690000 memmap=0x10000$0x18690000
memtest= [KNL,X86_64] Enable memtest memtest= [KNL,X86] Enable memtest
Format: <integer> Format: <integer>
range: 0,4 : pattern number range: 0,4 : pattern number
default : 0 <disable> default : 0 <disable>
...@@ -1225,6 +1242,14 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1225,6 +1242,14 @@ and is between 256 and 4096 characters. It is defined in the file
mga= [HW,DRM] mga= [HW,DRM]
mminit_loglevel=
[KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
parameter allows control of the logging verbosity for
the additional memory initialisation checks. A value
of 0 disables mminit logging and a level of 4 will
log everything. Information is printed at KERN_DEBUG
so loglevel=8 may also need to be specified.
mousedev.tap_time= mousedev.tap_time=
[MOUSE] Maximum time between finger touching and [MOUSE] Maximum time between finger touching and
leaving touchpad surface for touch to be considered leaving touchpad surface for touch to be considered
...@@ -1279,6 +1304,13 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1279,6 +1304,13 @@ and is between 256 and 4096 characters. It is defined in the file
This usage is only documented in each driver source This usage is only documented in each driver source
file if at all. file if at all.
nf_conntrack.acct=
[NETFILTER] Enable connection tracking flow accounting
0 to disable accounting
1 to enable accounting
Default value depends on CONFIG_NF_CT_ACCT that is
going to be removed in 2.6.29.
nfsaddrs= [NFS] nfsaddrs= [NFS]
See Documentation/filesystems/nfsroot.txt. See Documentation/filesystems/nfsroot.txt.
...@@ -2027,6 +2059,9 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -2027,6 +2059,9 @@ and is between 256 and 4096 characters. It is defined in the file
snd-ymfpci= [HW,ALSA] snd-ymfpci= [HW,ALSA]
softlockup_panic=
[KNL] Should the soft-lockup detector generate panics.
sonypi.*= [HW] Sony Programmable I/O Control Device driver sonypi.*= [HW] Sony Programmable I/O Control Device driver
See Documentation/sonypi.txt See Documentation/sonypi.txt
...@@ -2091,6 +2126,12 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -2091,6 +2126,12 @@ and is between 256 and 4096 characters. It is defined in the file
tdfx= [HW,DRM] tdfx= [HW,DRM]
test_suspend= [SUSPEND]
Specify "mem" (for Suspend-to-RAM) or "standby" (for
standby suspend) as the system sleep state to briefly
enter during system startup. The system is woken from
this state using a wakeup-capable RTC alarm.
thash_entries= [KNL,NET] thash_entries= [KNL,NET]
Set number of hash buckets for TCP connection Set number of hash buckets for TCP connection
...@@ -2118,13 +2159,6 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -2118,13 +2159,6 @@ and is between 256 and 4096 characters. It is defined in the file
<deci-seconds>: poll all this frequency <deci-seconds>: poll all this frequency
0: no polling (default) 0: no polling (default)
tipar.timeout= [HW,PPT]
Set communications timeout in tenths of a second
(default 15).
tipar.delay= [HW,PPT]
Set inter-bit delay in microseconds (default 10).
tmscsim= [HW,SCSI] tmscsim= [HW,SCSI]
See comment before function dc390_setup() in See comment before function dc390_setup() in
drivers/scsi/tmscsim.c. drivers/scsi/tmscsim.c.
...@@ -2158,6 +2192,10 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -2158,6 +2192,10 @@ and is between 256 and 4096 characters. It is defined in the file
Note that genuine overcurrent events won't be Note that genuine overcurrent events won't be
reported either. reported either.
unknown_nmi_panic
[X86-32,X86-64]
Set unknown_nmi_panic=1 early on boot.
usbcore.autosuspend= usbcore.autosuspend=
[USB] The autosuspend time delay (in seconds) used [USB] The autosuspend time delay (in seconds) used
for newly-detected USB devices (default 2). This for newly-detected USB devices (default 2). This
......
...@@ -864,7 +864,7 @@ payload contents" for more information. ...@@ -864,7 +864,7 @@ payload contents" for more information.
request_key_with_auxdata() respectively. request_key_with_auxdata() respectively.
These two functions return with the key potentially still under These two functions return with the key potentially still under
construction. To wait for contruction completion, the following should be construction. To wait for construction completion, the following should be
called: called:
int wait_for_key_construction(struct key *key, bool intr); int wait_for_key_construction(struct key *key, bool intr);
......
...@@ -59,7 +59,7 @@ Hardware accelerated blink of LEDs ...@@ -59,7 +59,7 @@ Hardware accelerated blink of LEDs
Some LEDs can be programmed to blink without any CPU interaction. To Some LEDs can be programmed to blink without any CPU interaction. To
support this feature, a LED driver can optionally implement the support this feature, a LED driver can optionally implement the
blink_set() function (see <linux/leds.h>). If implemeted, triggers can blink_set() function (see <linux/leds.h>). If implemented, triggers can
attempt to use it before falling back to software timers. The blink_set() attempt to use it before falling back to software timers. The blink_set()
function should return 0 if the blink setting is supported, or -EINVAL function should return 0 if the blink setting is supported, or -EINVAL
otherwise, which means that LED blinking will be handled by software. otherwise, which means that LED blinking will be handled by software.
......
此差异已折叠。
...@@ -36,7 +36,7 @@ It can be done by slightly modifying the standard atomic operations : only ...@@ -36,7 +36,7 @@ It can be done by slightly modifying the standard atomic operations : only
their UP variant must be kept. It typically means removing LOCK prefix (on their UP variant must be kept. It typically means removing LOCK prefix (on
i386 and x86_64) and any SMP sychronization barrier. If the architecture does i386 and x86_64) and any SMP sychronization barrier. If the architecture does
not have a different behavior between SMP and UP, including asm-generic/local.h not have a different behavior between SMP and UP, including asm-generic/local.h
in your archtecture's local.h is sufficient. in your architecture's local.h is sufficient.
The local_t type is defined as an opaque signed long by embedding an The local_t type is defined as an opaque signed long by embedding an
atomic_long_t inside a structure. This is made so a cast from this type to a atomic_long_t inside a structure. This is made so a cast from this type to a
......
此差异已折叠。
此差异已折叠。
...@@ -186,7 +186,7 @@ solution for a couple of reasons: ...@@ -186,7 +186,7 @@ solution for a couple of reasons:
The Linux network devices (by default) just can handle the The Linux network devices (by default) just can handle the
transmission and reception of media dependent frames. Due to the transmission and reception of media dependent frames. Due to the
arbritration on the CAN bus the transmission of a low prio CAN-ID arbitration on the CAN bus the transmission of a low prio CAN-ID
may be delayed by the reception of a high prio CAN frame. To may be delayed by the reception of a high prio CAN frame. To
reflect the correct* traffic on the node the loopback of the sent reflect the correct* traffic on the node the loopback of the sent
data has to be performed right after a successful transmission. If data has to be performed right after a successful transmission. If
...@@ -481,7 +481,7 @@ solution for a couple of reasons: ...@@ -481,7 +481,7 @@ solution for a couple of reasons:
- stats_timer: To calculate the Socket CAN core statistics - stats_timer: To calculate the Socket CAN core statistics
(e.g. current/maximum frames per second) this 1 second timer is (e.g. current/maximum frames per second) this 1 second timer is
invoked at can.ko module start time by default. This timer can be invoked at can.ko module start time by default. This timer can be
disabled by using stattimer=0 on the module comandline. disabled by using stattimer=0 on the module commandline.
- debug: (removed since SocketCAN SVN r546) - debug: (removed since SocketCAN SVN r546)
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
interface=wlan0
driver=nl80211
hw_mode=g
channel=1
ssid=mac80211 test
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
wpa_passphrase=12345678
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册