Merge branch 'master' into for-2.6.35
Conflicts: fs/ext3/fsync.c Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
@@ -250,6 +250,8 @@ numastat.txt
|
|||||||
- info on how to read Numa policy hit/miss statistics in sysfs.
|
- info on how to read Numa policy hit/miss statistics in sysfs.
|
||||||
oops-tracing.txt
|
oops-tracing.txt
|
||||||
- how to decode those nasty internal kernel error dump messages.
|
- how to decode those nasty internal kernel error dump messages.
|
||||||
|
padata.txt
|
||||||
|
- An introduction to the "padata" parallel execution API
|
||||||
parisc/
|
parisc/
|
||||||
- directory with info on using Linux on PA-RISC architecture.
|
- directory with info on using Linux on PA-RISC architecture.
|
||||||
parport.txt
|
parport.txt
|
||||||
|
|||||||
31
Documentation/ABI/obsolete/sysfs-bus-usb
Normal file
31
Documentation/ABI/obsolete/sysfs-bus-usb
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
What: /sys/bus/usb/devices/.../power/level
|
||||||
|
Date: March 2007
|
||||||
|
KernelVersion: 2.6.21
|
||||||
|
Contact: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Description:
|
||||||
|
Each USB device directory will contain a file named
|
||||||
|
power/level. This file holds a power-level setting for
|
||||||
|
the device, either "on" or "auto".
|
||||||
|
|
||||||
|
"on" means that the device is not allowed to autosuspend,
|
||||||
|
although normal suspends for system sleep will still
|
||||||
|
be honored. "auto" means the device will autosuspend
|
||||||
|
and autoresume in the usual manner, according to the
|
||||||
|
capabilities of its driver.
|
||||||
|
|
||||||
|
During normal use, devices should be left in the "auto"
|
||||||
|
level. The "on" level is meant for administrative uses.
|
||||||
|
If you want to suspend a device immediately but leave it
|
||||||
|
free to wake up in response to I/O requests, you should
|
||||||
|
write "0" to power/autosuspend.
|
||||||
|
|
||||||
|
Device not capable of proper suspend and resume should be
|
||||||
|
left in the "on" level. Although the USB spec requires
|
||||||
|
devices to support suspend/resume, many of them do not.
|
||||||
|
In fact so many don't that by default, the USB core
|
||||||
|
initializes all non-hub devices in the "on" level. Some
|
||||||
|
drivers may change this setting when they are bound.
|
||||||
|
|
||||||
|
This file is deprecated and will be removed after 2010.
|
||||||
|
Use the power/control file instead; it does exactly the
|
||||||
|
same thing.
|
||||||
29
Documentation/ABI/obsolete/sysfs-class-rfkill
Normal file
29
Documentation/ABI/obsolete/sysfs-class-rfkill
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
rfkill - radio frequency (RF) connector kill switch support
|
||||||
|
|
||||||
|
For details to this subsystem look at Documentation/rfkill.txt.
|
||||||
|
|
||||||
|
What: /sys/class/rfkill/rfkill[0-9]+/state
|
||||||
|
Date: 09-Jul-2007
|
||||||
|
KernelVersion v2.6.22
|
||||||
|
Contact: linux-wireless@vger.kernel.org
|
||||||
|
Description: Current state of the transmitter.
|
||||||
|
This file is deprecated and sheduled to be removed in 2014,
|
||||||
|
because its not possible to express the 'soft and hard block'
|
||||||
|
state of the rfkill driver.
|
||||||
|
Values: A numeric value.
|
||||||
|
0: RFKILL_STATE_SOFT_BLOCKED
|
||||||
|
transmitter is turned off by software
|
||||||
|
1: RFKILL_STATE_UNBLOCKED
|
||||||
|
transmitter is (potentially) active
|
||||||
|
2: RFKILL_STATE_HARD_BLOCKED
|
||||||
|
transmitter is forced off by something outside of
|
||||||
|
the driver's control.
|
||||||
|
|
||||||
|
What: /sys/class/rfkill/rfkill[0-9]+/claim
|
||||||
|
Date: 09-Jul-2007
|
||||||
|
KernelVersion v2.6.22
|
||||||
|
Contact: linux-wireless@vger.kernel.org
|
||||||
|
Description: This file is deprecated because there no longer is a way to
|
||||||
|
claim just control over a single rfkill instance.
|
||||||
|
This file is scheduled to be removed in 2012.
|
||||||
|
Values: 0: Kernel handles events
|
||||||
67
Documentation/ABI/stable/sysfs-class-rfkill
Normal file
67
Documentation/ABI/stable/sysfs-class-rfkill
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
rfkill - radio frequency (RF) connector kill switch support
|
||||||
|
|
||||||
|
For details to this subsystem look at Documentation/rfkill.txt.
|
||||||
|
|
||||||
|
For the deprecated /sys/class/rfkill/*/state and
|
||||||
|
/sys/class/rfkill/*/claim knobs of this interface look in
|
||||||
|
Documentation/ABI/obsolete/sysfs-class-rfkill.
|
||||||
|
|
||||||
|
What: /sys/class/rfkill
|
||||||
|
Date: 09-Jul-2007
|
||||||
|
KernelVersion: v2.6.22
|
||||||
|
Contact: linux-wireless@vger.kernel.org,
|
||||||
|
Description: The rfkill class subsystem folder.
|
||||||
|
Each registered rfkill driver is represented by an rfkillX
|
||||||
|
subfolder (X being an integer > 0).
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/rfkill/rfkill[0-9]+/name
|
||||||
|
Date: 09-Jul-2007
|
||||||
|
KernelVersion v2.6.22
|
||||||
|
Contact: linux-wireless@vger.kernel.org
|
||||||
|
Description: Name assigned by driver to this key (interface or driver name).
|
||||||
|
Values: arbitrary string.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/rfkill/rfkill[0-9]+/type
|
||||||
|
Date: 09-Jul-2007
|
||||||
|
KernelVersion v2.6.22
|
||||||
|
Contact: linux-wireless@vger.kernel.org
|
||||||
|
Description: Driver type string ("wlan", "bluetooth", etc).
|
||||||
|
Values: See include/linux/rfkill.h.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/rfkill/rfkill[0-9]+/persistent
|
||||||
|
Date: 09-Jul-2007
|
||||||
|
KernelVersion v2.6.22
|
||||||
|
Contact: linux-wireless@vger.kernel.org
|
||||||
|
Description: Whether the soft blocked state is initialised from non-volatile
|
||||||
|
storage at startup.
|
||||||
|
Values: A numeric value.
|
||||||
|
0: false
|
||||||
|
1: true
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/rfkill/rfkill[0-9]+/hard
|
||||||
|
Date: 12-March-2010
|
||||||
|
KernelVersion v2.6.34
|
||||||
|
Contact: linux-wireless@vger.kernel.org
|
||||||
|
Description: Current hardblock state. This file is read only.
|
||||||
|
Values: A numeric value.
|
||||||
|
0: inactive
|
||||||
|
The transmitter is (potentially) active.
|
||||||
|
1: active
|
||||||
|
The transmitter is forced off by something outside of
|
||||||
|
the driver's control.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/class/rfkill/rfkill[0-9]+/soft
|
||||||
|
Date: 12-March-2010
|
||||||
|
KernelVersion v2.6.34
|
||||||
|
Contact: linux-wireless@vger.kernel.org
|
||||||
|
Description: Current softblock state. This file is read and write.
|
||||||
|
Values: A numeric value.
|
||||||
|
0: inactive
|
||||||
|
The transmitter is (potentially) active.
|
||||||
|
1: active
|
||||||
|
The transmitter is turned off by software.
|
||||||
@@ -14,34 +14,6 @@ Description:
|
|||||||
The autosuspend delay for newly-created devices is set to
|
The autosuspend delay for newly-created devices is set to
|
||||||
the value of the usbcore.autosuspend module parameter.
|
the value of the usbcore.autosuspend module parameter.
|
||||||
|
|
||||||
What: /sys/bus/usb/devices/.../power/level
|
|
||||||
Date: March 2007
|
|
||||||
KernelVersion: 2.6.21
|
|
||||||
Contact: Alan Stern <stern@rowland.harvard.edu>
|
|
||||||
Description:
|
|
||||||
Each USB device directory will contain a file named
|
|
||||||
power/level. This file holds a power-level setting for
|
|
||||||
the device, either "on" or "auto".
|
|
||||||
|
|
||||||
"on" means that the device is not allowed to autosuspend,
|
|
||||||
although normal suspends for system sleep will still
|
|
||||||
be honored. "auto" means the device will autosuspend
|
|
||||||
and autoresume in the usual manner, according to the
|
|
||||||
capabilities of its driver.
|
|
||||||
|
|
||||||
During normal use, devices should be left in the "auto"
|
|
||||||
level. The "on" level is meant for administrative uses.
|
|
||||||
If you want to suspend a device immediately but leave it
|
|
||||||
free to wake up in response to I/O requests, you should
|
|
||||||
write "0" to power/autosuspend.
|
|
||||||
|
|
||||||
Device not capable of proper suspend and resume should be
|
|
||||||
left in the "on" level. Although the USB spec requires
|
|
||||||
devices to support suspend/resume, many of them do not.
|
|
||||||
In fact so many don't that by default, the USB core
|
|
||||||
initializes all non-hub devices in the "on" level. Some
|
|
||||||
drivers may change this setting when they are bound.
|
|
||||||
|
|
||||||
What: /sys/bus/usb/devices/.../power/persist
|
What: /sys/bus/usb/devices/.../power/persist
|
||||||
Date: May 2007
|
Date: May 2007
|
||||||
KernelVersion: 2.6.23
|
KernelVersion: 2.6.23
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Date: September 2008
|
|||||||
Contact: Badari Pulavarty <pbadari@us.ibm.com>
|
Contact: Badari Pulavarty <pbadari@us.ibm.com>
|
||||||
Description:
|
Description:
|
||||||
The file /sys/devices/system/memory/memoryX/state
|
The file /sys/devices/system/memory/memoryX/state
|
||||||
is read-write. When read, it's contents show the
|
is read-write. When read, its contents show the
|
||||||
online/offline state of the memory section. When written,
|
online/offline state of the memory section. When written,
|
||||||
root can toggle the the online/offline state of a removable
|
root can toggle the the online/offline state of a removable
|
||||||
memory section (see removable file description above)
|
memory section (see removable file description above)
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
What: /sys/devices/platform/_UDC_/gadget/suspended
|
||||||
|
Date: April 2010
|
||||||
|
Contact: Fabien Chouteau <fabien.chouteau@barco.com>
|
||||||
|
Description:
|
||||||
|
Show the suspend state of an USB composite gadget.
|
||||||
|
1 -> suspended
|
||||||
|
0 -> resumed
|
||||||
|
|
||||||
|
(_UDC_ is the name of the USB Device Controller driver)
|
||||||
43
Documentation/ABI/testing/sysfs-driver-hid-picolcd
Normal file
43
Documentation/ABI/testing/sysfs-driver-hid-picolcd
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/operation_mode
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Bruno Prémont <bonbons@linux-vserver.org>
|
||||||
|
Description: Make it possible to switch the PicoLCD device between LCD
|
||||||
|
(firmware) and bootloader (flasher) operation modes.
|
||||||
|
|
||||||
|
Reading: returns list of available modes, the active mode being
|
||||||
|
enclosed in brackets ('[' and ']')
|
||||||
|
|
||||||
|
Writing: causes operation mode switch. Permitted values are
|
||||||
|
the non-active mode names listed when read.
|
||||||
|
|
||||||
|
Note: when switching mode the current PicoLCD HID device gets
|
||||||
|
disconnected and reconnects after above delay (see attribute
|
||||||
|
operation_mode_delay for its value).
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/operation_mode_delay
|
||||||
|
Date: April 2010
|
||||||
|
Contact: Bruno Prémont <bonbons@linux-vserver.org>
|
||||||
|
Description: Delay PicoLCD waits before restarting in new mode when
|
||||||
|
operation_mode has changed.
|
||||||
|
|
||||||
|
Reading/Writing: It is expressed in ms and permitted range is
|
||||||
|
0..30000ms.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/fb_update_rate
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Bruno Prémont <bonbons@linux-vserver.org>
|
||||||
|
Description: Make it possible to adjust defio refresh rate.
|
||||||
|
|
||||||
|
Reading: returns list of available refresh rates (expressed in Hz),
|
||||||
|
the active refresh rate being enclosed in brackets ('[' and ']')
|
||||||
|
|
||||||
|
Writing: accepts new refresh rate expressed in integer Hz
|
||||||
|
within permitted rates.
|
||||||
|
|
||||||
|
Note: As device can barely do 2 complete refreshes a second
|
||||||
|
it only makes sense to adjust this value if only one or two
|
||||||
|
tiles get changed and it's not appropriate to expect the application
|
||||||
|
to flush it's tiny changes explicitely at higher than default rate.
|
||||||
|
|
||||||
29
Documentation/ABI/testing/sysfs-driver-hid-prodikeys
Normal file
29
Documentation/ABI/testing/sysfs-driver-hid-prodikeys
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
What: /sys/bus/hid/drivers/prodikeys/.../channel
|
||||||
|
Date: April 2010
|
||||||
|
KernelVersion: 2.6.34
|
||||||
|
Contact: Don Prince <dhprince.devel@yahoo.co.uk>
|
||||||
|
Description:
|
||||||
|
Allows control (via software) the midi channel to which
|
||||||
|
that the pc-midi keyboard will output.midi data.
|
||||||
|
Range: 0..15
|
||||||
|
Type: Read/write
|
||||||
|
What: /sys/bus/hid/drivers/prodikeys/.../sustain
|
||||||
|
Date: April 2010
|
||||||
|
KernelVersion: 2.6.34
|
||||||
|
Contact: Don Prince <dhprince.devel@yahoo.co.uk>
|
||||||
|
Description:
|
||||||
|
Allows control (via software) the sustain duration of a
|
||||||
|
note held by the pc-midi driver.
|
||||||
|
0 means sustain mode is disabled.
|
||||||
|
Range: 0..5000 (milliseconds)
|
||||||
|
Type: Read/write
|
||||||
|
What: /sys/bus/hid/drivers/prodikeys/.../octave
|
||||||
|
Date: April 2010
|
||||||
|
KernelVersion: 2.6.34
|
||||||
|
Contact: Don Prince <dhprince.devel@yahoo.co.uk>
|
||||||
|
Description:
|
||||||
|
Controls the octave shift modifier in the pc-midi driver.
|
||||||
|
The octave can be shifted via software up/down 2 octaves.
|
||||||
|
0 means the no ocatve shift.
|
||||||
|
Range: -2..2 (minus 2 to plus 2)
|
||||||
|
Type: Read/Write
|
||||||
111
Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
Normal file
111
Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_dpi
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: It is possible to switch the dpi setting of the mouse with the
|
||||||
|
press of a button.
|
||||||
|
When read, this file returns the raw number of the actual dpi
|
||||||
|
setting reported by the mouse. This number has to be further
|
||||||
|
processed to receive the real dpi value.
|
||||||
|
|
||||||
|
VALUE DPI
|
||||||
|
1 800
|
||||||
|
2 1200
|
||||||
|
3 1600
|
||||||
|
4 2000
|
||||||
|
5 2400
|
||||||
|
6 3200
|
||||||
|
|
||||||
|
This file is readonly.
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_profile
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: When read, this file returns the number of the actual profile.
|
||||||
|
This file is readonly.
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/firmware_version
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: When read, this file returns the raw integer version number of the
|
||||||
|
firmware reported by the mouse. Using the integer value eases
|
||||||
|
further usage in other programs. To receive the real version
|
||||||
|
number the decimal point has to be shifted 2 positions to the
|
||||||
|
left. E.g. a returned value of 138 means 1.38
|
||||||
|
This file is readonly.
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/kone_driver_version
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: When read, this file returns the driver version.
|
||||||
|
The format of the string is "v<major>.<minor>.<patchlevel>".
|
||||||
|
This attribute is used by the userland tools to find the sysfs-
|
||||||
|
paths of installed kone-mice and determine the capabilites of
|
||||||
|
the driver. Versions of this driver for old kernels replace
|
||||||
|
usbhid instead of generic-usb. The way to scan for this file
|
||||||
|
has been chosen to provide a consistent way for all supported
|
||||||
|
kernel versions.
|
||||||
|
This file is readonly.
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: The mouse can store 5 profiles which can be switched by the
|
||||||
|
press of a button. A profile holds informations like button
|
||||||
|
mappings, sensitivity, the colors of the 5 leds and light
|
||||||
|
effects.
|
||||||
|
When read, these files return the respective profile. The
|
||||||
|
returned data is 975 bytes in size.
|
||||||
|
When written, this file lets one write the respective profile
|
||||||
|
data back to the mouse. The data has to be 975 bytes long.
|
||||||
|
The mouse will reject invalid data, whereas the profile number
|
||||||
|
stored in the profile doesn't need to fit the number of the
|
||||||
|
store.
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/settings
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: When read, this file returns the settings stored in the mouse.
|
||||||
|
The size of the data is 36 bytes and holds information like the
|
||||||
|
startup_profile, tcu state and calibration_data.
|
||||||
|
When written, this file lets write settings back to the mouse.
|
||||||
|
The data has to be 36 bytes long. The mouse will reject invalid
|
||||||
|
data.
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/startup_profile
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: The integer value of this attribute ranges from 1 to 5.
|
||||||
|
When read, this attribute returns the number of the profile
|
||||||
|
that's active when the mouse is powered on.
|
||||||
|
When written, this file sets the number of the startup profile
|
||||||
|
and the mouse activates this profile immediately.
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/tcu
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: The mouse has a "Tracking Control Unit" which lets the user
|
||||||
|
calibrate the laser power to fit the mousepad surface.
|
||||||
|
When read, this file returns the current state of the TCU,
|
||||||
|
where 0 means off and 1 means on.
|
||||||
|
Writing 0 in this file will switch the TCU off.
|
||||||
|
Writing 1 in this file will start the calibration which takes
|
||||||
|
around 6 seconds to complete and activates the TCU.
|
||||||
|
|
||||||
|
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/weight
|
||||||
|
Date: March 2010
|
||||||
|
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||||
|
Description: The mouse can be equipped with one of four supplied weights
|
||||||
|
ranging from 5 to 20 grams which are recognized by the mouse
|
||||||
|
and its value can be read out. When read, this file returns the
|
||||||
|
raw value returned by the mouse which eases further processing
|
||||||
|
in other software.
|
||||||
|
The values map to the weights as follows:
|
||||||
|
|
||||||
|
VALUE WEIGHT
|
||||||
|
0 none
|
||||||
|
1 5g
|
||||||
|
2 10g
|
||||||
|
3 15g
|
||||||
|
4 20g
|
||||||
|
|
||||||
|
This file is readonly.
|
||||||
10
Documentation/ABI/testing/sysfs-wacom
Normal file
10
Documentation/ABI/testing/sysfs-wacom
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
What: /sys/class/hidraw/hidraw*/device/speed
|
||||||
|
Date: April 2010
|
||||||
|
Kernel Version: 2.6.35
|
||||||
|
Contact: linux-bluetooth@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
The /sys/class/hidraw/hidraw*/device/speed file controls
|
||||||
|
reporting speed of wacom bluetooth tablet. Reading from
|
||||||
|
this file returns 1 if tablet reports in high speed mode
|
||||||
|
or 0 otherwise. Writing to this file one of these values
|
||||||
|
switches reporting speed.
|
||||||
@@ -49,7 +49,7 @@ o oprofile 0.9 # oprofiled --version
|
|||||||
o udev 081 # udevinfo -V
|
o udev 081 # udevinfo -V
|
||||||
o grub 0.93 # grub --version
|
o grub 0.93 # grub --version
|
||||||
o mcelog 0.6
|
o mcelog 0.6
|
||||||
o iptables 1.4.1 # iptables -V
|
o iptables 1.4.2 # iptables -V
|
||||||
|
|
||||||
|
|
||||||
Kernel compilation
|
Kernel compilation
|
||||||
|
|||||||
@@ -742,7 +742,7 @@ failure can be determined by:
|
|||||||
|
|
||||||
Closing
|
Closing
|
||||||
|
|
||||||
This document, and the API itself, would not be in it's current
|
This document, and the API itself, would not be in its current
|
||||||
form without the feedback and suggestions from numerous individuals.
|
form without the feedback and suggestions from numerous individuals.
|
||||||
We would like to specifically mention, in no particular order, the
|
We would like to specifically mention, in no particular order, the
|
||||||
following people:
|
following people:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.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 sh.xml regulator.xml \
|
mac80211.xml debugobjects.xml sh.xml regulator.xml \
|
||||||
alsa-driver-api.xml writing-an-alsa-driver.xml \
|
alsa-driver-api.xml writing-an-alsa-driver.xml \
|
||||||
tracepoint.xml media.xml
|
tracepoint.xml media.xml drm.xml
|
||||||
|
|
||||||
###
|
###
|
||||||
# The build process is as follows (targets):
|
# The build process is as follows (targets):
|
||||||
|
|||||||
839
Documentation/DocBook/drm.tmpl
Normal file
839
Documentation/DocBook/drm.tmpl
Normal file
@@ -0,0 +1,839 @@
|
|||||||
|
<?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="drmDevelopersGuide">
|
||||||
|
<bookinfo>
|
||||||
|
<title>Linux DRM Developer's Guide</title>
|
||||||
|
|
||||||
|
<copyright>
|
||||||
|
<year>2008-2009</year>
|
||||||
|
<holder>
|
||||||
|
Intel Corporation (Jesse Barnes <jesse.barnes@intel.com>)
|
||||||
|
</holder>
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<legalnotice>
|
||||||
|
<para>
|
||||||
|
The contents of this file may be used under the terms of the GNU
|
||||||
|
General Public License version 2 (the "GPL") as distributed in
|
||||||
|
the kernel source COPYING file.
|
||||||
|
</para>
|
||||||
|
</legalnotice>
|
||||||
|
</bookinfo>
|
||||||
|
|
||||||
|
<toc></toc>
|
||||||
|
|
||||||
|
<!-- Introduction -->
|
||||||
|
|
||||||
|
<chapter id="drmIntroduction">
|
||||||
|
<title>Introduction</title>
|
||||||
|
<para>
|
||||||
|
The Linux DRM layer contains code intended to support the needs
|
||||||
|
of complex graphics devices, usually containing programmable
|
||||||
|
pipelines well suited to 3D graphics acceleration. Graphics
|
||||||
|
drivers in the kernel can make use of DRM functions to make
|
||||||
|
tasks like memory management, interrupt handling and DMA easier,
|
||||||
|
and provide a uniform interface to applications.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A note on versions: this guide covers features found in the DRM
|
||||||
|
tree, including the TTM memory manager, output configuration and
|
||||||
|
mode setting, and the new vblank internals, in addition to all
|
||||||
|
the regular features found in current kernels.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
[Insert diagram of typical DRM stack here]
|
||||||
|
</para>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<!-- Internals -->
|
||||||
|
|
||||||
|
<chapter id="drmInternals">
|
||||||
|
<title>DRM Internals</title>
|
||||||
|
<para>
|
||||||
|
This chapter documents DRM internals relevant to driver authors
|
||||||
|
and developers working to add support for the latest features to
|
||||||
|
existing drivers.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
First, we'll go over some typical driver initialization
|
||||||
|
requirements, like setting up command buffers, creating an
|
||||||
|
initial output configuration, and initializing core services.
|
||||||
|
Subsequent sections will cover core internals in more detail,
|
||||||
|
providing implementation notes and examples.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The DRM layer provides several services to graphics drivers,
|
||||||
|
many of them driven by the application interfaces it provides
|
||||||
|
through libdrm, the library that wraps most of the DRM ioctls.
|
||||||
|
These include vblank event handling, memory
|
||||||
|
management, output management, framebuffer management, command
|
||||||
|
submission & fencing, suspend/resume support, and DMA
|
||||||
|
services.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The core of every DRM driver is struct drm_device. Drivers
|
||||||
|
will typically statically initialize a drm_device structure,
|
||||||
|
then pass it to drm_init() at load time.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<!-- Internals: driver init -->
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Driver initialization</title>
|
||||||
|
<para>
|
||||||
|
Before calling the DRM initialization routines, the driver must
|
||||||
|
first create and fill out a struct drm_device structure.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
static struct drm_driver driver = {
|
||||||
|
/* don't use mtrr's here, the Xserver or user space app should
|
||||||
|
* deal with them for intel hardware.
|
||||||
|
*/
|
||||||
|
.driver_features =
|
||||||
|
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
|
||||||
|
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_MODESET,
|
||||||
|
.load = i915_driver_load,
|
||||||
|
.unload = i915_driver_unload,
|
||||||
|
.firstopen = i915_driver_firstopen,
|
||||||
|
.lastclose = i915_driver_lastclose,
|
||||||
|
.preclose = i915_driver_preclose,
|
||||||
|
.save = i915_save,
|
||||||
|
.restore = i915_restore,
|
||||||
|
.device_is_agp = i915_driver_device_is_agp,
|
||||||
|
.get_vblank_counter = i915_get_vblank_counter,
|
||||||
|
.enable_vblank = i915_enable_vblank,
|
||||||
|
.disable_vblank = i915_disable_vblank,
|
||||||
|
.irq_preinstall = i915_driver_irq_preinstall,
|
||||||
|
.irq_postinstall = i915_driver_irq_postinstall,
|
||||||
|
.irq_uninstall = i915_driver_irq_uninstall,
|
||||||
|
.irq_handler = i915_driver_irq_handler,
|
||||||
|
.reclaim_buffers = drm_core_reclaim_buffers,
|
||||||
|
.get_map_ofs = drm_core_get_map_ofs,
|
||||||
|
.get_reg_ofs = drm_core_get_reg_ofs,
|
||||||
|
.fb_probe = intelfb_probe,
|
||||||
|
.fb_remove = intelfb_remove,
|
||||||
|
.fb_resize = intelfb_resize,
|
||||||
|
.master_create = i915_master_create,
|
||||||
|
.master_destroy = i915_master_destroy,
|
||||||
|
#if defined(CONFIG_DEBUG_FS)
|
||||||
|
.debugfs_init = i915_debugfs_init,
|
||||||
|
.debugfs_cleanup = i915_debugfs_cleanup,
|
||||||
|
#endif
|
||||||
|
.gem_init_object = i915_gem_init_object,
|
||||||
|
.gem_free_object = i915_gem_free_object,
|
||||||
|
.gem_vm_ops = &i915_gem_vm_ops,
|
||||||
|
.ioctls = i915_ioctls,
|
||||||
|
.fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = drm_open,
|
||||||
|
.release = drm_release,
|
||||||
|
.ioctl = drm_ioctl,
|
||||||
|
.mmap = drm_mmap,
|
||||||
|
.poll = drm_poll,
|
||||||
|
.fasync = drm_fasync,
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
.compat_ioctl = i915_compat_ioctl,
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
.pci_driver = {
|
||||||
|
.name = DRIVER_NAME,
|
||||||
|
.id_table = pciidlist,
|
||||||
|
.probe = probe,
|
||||||
|
.remove = __devexit_p(drm_cleanup_pci),
|
||||||
|
},
|
||||||
|
.name = DRIVER_NAME,
|
||||||
|
.desc = DRIVER_DESC,
|
||||||
|
.date = DRIVER_DATE,
|
||||||
|
.major = DRIVER_MAJOR,
|
||||||
|
.minor = DRIVER_MINOR,
|
||||||
|
.patchlevel = DRIVER_PATCHLEVEL,
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
In the example above, taken from the i915 DRM driver, the driver
|
||||||
|
sets several flags indicating what core features it supports.
|
||||||
|
We'll go over the individual callbacks in later sections. Since
|
||||||
|
flags indicate which features your driver supports to the DRM
|
||||||
|
core, you need to set most of them prior to calling drm_init(). Some,
|
||||||
|
like DRIVER_MODESET can be set later based on user supplied parameters,
|
||||||
|
but that's the exception rather than the rule.
|
||||||
|
</para>
|
||||||
|
<variablelist>
|
||||||
|
<title>Driver flags</title>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_USE_AGP</term>
|
||||||
|
<listitem><para>
|
||||||
|
Driver uses AGP interface
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_REQUIRE_AGP</term>
|
||||||
|
<listitem><para>
|
||||||
|
Driver needs AGP interface to function.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_USE_MTRR</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Driver uses MTRR interface for mapping memory. Deprecated.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_PCI_DMA</term>
|
||||||
|
<listitem><para>
|
||||||
|
Driver is capable of PCI DMA. Deprecated.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_SG</term>
|
||||||
|
<listitem><para>
|
||||||
|
Driver can perform scatter/gather DMA. Deprecated.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_HAVE_DMA</term>
|
||||||
|
<listitem><para>Driver supports DMA. Deprecated.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_HAVE_IRQ</term><term>DRIVER_IRQ_SHARED</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
DRIVER_HAVE_IRQ indicates whether the driver has a IRQ
|
||||||
|
handler, DRIVER_IRQ_SHARED indicates whether the device &
|
||||||
|
handler support shared IRQs (note that this is required of
|
||||||
|
PCI drivers).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_DMA_QUEUE</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
If the driver queues DMA requests and completes them
|
||||||
|
asynchronously, this flag should be set. Deprecated.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_FB_DMA</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Driver supports DMA to/from the framebuffer. Deprecated.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>DRIVER_MODESET</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Driver supports mode setting interfaces.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
<para>
|
||||||
|
In this specific case, the driver requires AGP and supports
|
||||||
|
IRQs. DMA, as we'll see, is handled by device specific ioctls
|
||||||
|
in this case. It also supports the kernel mode setting APIs, though
|
||||||
|
unlike in the actual i915 driver source, this example unconditionally
|
||||||
|
exports KMS capability.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<!-- Internals: driver load -->
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Driver load</title>
|
||||||
|
<para>
|
||||||
|
In the previous section, we saw what a typical drm_driver
|
||||||
|
structure might look like. One of the more important fields in
|
||||||
|
the structure is the hook for the load function.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
static struct drm_driver driver = {
|
||||||
|
...
|
||||||
|
.load = i915_driver_load,
|
||||||
|
...
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
The load function has many responsibilities: allocating a driver
|
||||||
|
private structure, specifying supported performance counters,
|
||||||
|
configuring the device (e.g. mapping registers & command
|
||||||
|
buffers), initializing the memory manager, and setting up the
|
||||||
|
initial output configuration.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Note that the tasks performed at driver load time must not
|
||||||
|
conflict with DRM client requirements. For instance, if user
|
||||||
|
level mode setting drivers are in use, it would be problematic
|
||||||
|
to perform output discovery & configuration at load time.
|
||||||
|
Likewise, if pre-memory management aware user level drivers are
|
||||||
|
in use, memory management and command buffer setup may need to
|
||||||
|
be omitted. These requirements are driver specific, and care
|
||||||
|
needs to be taken to keep both old and new applications and
|
||||||
|
libraries working. The i915 driver supports the "modeset"
|
||||||
|
module parameter to control whether advanced features are
|
||||||
|
enabled at load time or in legacy fashion. If compatibility is
|
||||||
|
a concern (e.g. with drivers converted over to the new interfaces
|
||||||
|
from the old ones), care must be taken to prevent incompatible
|
||||||
|
device initialization and control with the currently active
|
||||||
|
userspace drivers.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>Driver private & performance counters</title>
|
||||||
|
<para>
|
||||||
|
The driver private hangs off the main drm_device structure and
|
||||||
|
can be used for tracking various device specific bits of
|
||||||
|
information, like register offsets, command buffer status,
|
||||||
|
register state for suspend/resume, etc. At load time, a
|
||||||
|
driver can simply allocate one and set drm_device.dev_priv
|
||||||
|
appropriately; at unload the driver can free it and set
|
||||||
|
drm_device.dev_priv to NULL.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The DRM supports several counters which can be used for rough
|
||||||
|
performance characterization. Note that the DRM stat counter
|
||||||
|
system is not often used by applications, and supporting
|
||||||
|
additional counters is completely optional.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
These interfaces are deprecated and should not be used. If performance
|
||||||
|
monitoring is desired, the developer should investigate and
|
||||||
|
potentially enhance the kernel perf and tracing infrastructure to export
|
||||||
|
GPU related performance information to performance monitoring
|
||||||
|
tools and applications.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>Configuring the device</title>
|
||||||
|
<para>
|
||||||
|
Obviously, device configuration will be device specific.
|
||||||
|
However, there are several common operations: finding a
|
||||||
|
device's PCI resources, mapping them, and potentially setting
|
||||||
|
up an IRQ handler.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Finding & mapping resources is fairly straightforward. The
|
||||||
|
DRM wrapper functions, drm_get_resource_start() and
|
||||||
|
drm_get_resource_len() can be used to find BARs on the given
|
||||||
|
drm_device struct. Once those values have been retrieved, the
|
||||||
|
driver load function can call drm_addmap() to create a new
|
||||||
|
mapping for the BAR in question. Note you'll probably want a
|
||||||
|
drm_local_map_t in your driver private structure to track any
|
||||||
|
mappings you create.
|
||||||
|
<!-- !Fdrivers/gpu/drm/drm_bufs.c drm_get_resource_* -->
|
||||||
|
<!-- !Finclude/drm/drmP.h drm_local_map_t -->
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
if compatibility with other operating systems isn't a concern
|
||||||
|
(DRM drivers can run under various BSD variants and OpenSolaris),
|
||||||
|
native Linux calls can be used for the above, e.g. pci_resource_*
|
||||||
|
and iomap*/iounmap. See the Linux device driver book for more
|
||||||
|
info.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Once you have a register map, you can use the DRM_READn() and
|
||||||
|
DRM_WRITEn() macros to access the registers on your device, or
|
||||||
|
use driver specific versions to offset into your MMIO space
|
||||||
|
relative to a driver specific base pointer (see I915_READ for
|
||||||
|
example).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If your device supports interrupt generation, you may want to
|
||||||
|
setup an interrupt handler at driver load time as well. This
|
||||||
|
is done using the drm_irq_install() function. If your device
|
||||||
|
supports vertical blank interrupts, it should call
|
||||||
|
drm_vblank_init() to initialize the core vblank handling code before
|
||||||
|
enabling interrupts on your device. This ensures the vblank related
|
||||||
|
structures are allocated and allows the core to handle vblank events.
|
||||||
|
</para>
|
||||||
|
<!--!Fdrivers/char/drm/drm_irq.c drm_irq_install-->
|
||||||
|
<para>
|
||||||
|
Once your interrupt handler is registered (it'll use your
|
||||||
|
drm_driver.irq_handler as the actual interrupt handling
|
||||||
|
function), you can safely enable interrupts on your device,
|
||||||
|
assuming any other state your interrupt handler uses is also
|
||||||
|
initialized.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Another task that may be necessary during configuration is
|
||||||
|
mapping the video BIOS. On many devices, the VBIOS describes
|
||||||
|
device configuration, LCD panel timings (if any), and contains
|
||||||
|
flags indicating device state. Mapping the BIOS can be done
|
||||||
|
using the pci_map_rom() call, a convenience function that
|
||||||
|
takes care of mapping the actual ROM, whether it has been
|
||||||
|
shadowed into memory (typically at address 0xc0000) or exists
|
||||||
|
on the PCI device in the ROM BAR. Note that once you've
|
||||||
|
mapped the ROM and extracted any necessary information, be
|
||||||
|
sure to unmap it; on many devices the ROM address decoder is
|
||||||
|
shared with other BARs, so leaving it mapped can cause
|
||||||
|
undesired behavior like hangs or memory corruption.
|
||||||
|
<!--!Fdrivers/pci/rom.c pci_map_rom-->
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>Memory manager initialization</title>
|
||||||
|
<para>
|
||||||
|
In order to allocate command buffers, cursor memory, scanout
|
||||||
|
buffers, etc., as well as support the latest features provided
|
||||||
|
by packages like Mesa and the X.Org X server, your driver
|
||||||
|
should support a memory manager.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If your driver supports memory management (it should!), you'll
|
||||||
|
need to set that up at load time as well. How you intialize
|
||||||
|
it depends on which memory manager you're using, TTM or GEM.
|
||||||
|
</para>
|
||||||
|
<sect3>
|
||||||
|
<title>TTM initialization</title>
|
||||||
|
<para>
|
||||||
|
TTM (for Translation Table Manager) manages video memory and
|
||||||
|
aperture space for graphics devices. TTM supports both UMA devices
|
||||||
|
and devices with dedicated video RAM (VRAM), i.e. most discrete
|
||||||
|
graphics devices. If your device has dedicated RAM, supporting
|
||||||
|
TTM is desireable. TTM also integrates tightly with your
|
||||||
|
driver specific buffer execution function. See the radeon
|
||||||
|
driver for examples.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The core TTM structure is the ttm_bo_driver struct. It contains
|
||||||
|
several fields with function pointers for initializing the TTM,
|
||||||
|
allocating and freeing memory, waiting for command completion
|
||||||
|
and fence synchronization, and memory migration. See the
|
||||||
|
radeon_ttm.c file for an example of usage.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The ttm_global_reference structure is made up of several fields:
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
struct ttm_global_reference {
|
||||||
|
enum ttm_global_types global_type;
|
||||||
|
size_t size;
|
||||||
|
void *object;
|
||||||
|
int (*init) (struct ttm_global_reference *);
|
||||||
|
void (*release) (struct ttm_global_reference *);
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
There should be one global reference structure for your memory
|
||||||
|
manager as a whole, and there will be others for each object
|
||||||
|
created by the memory manager at runtime. Your global TTM should
|
||||||
|
have a type of TTM_GLOBAL_TTM_MEM. The size field for the global
|
||||||
|
object should be sizeof(struct ttm_mem_global), and the init and
|
||||||
|
release hooks should point at your driver specific init and
|
||||||
|
release routines, which will probably eventually call
|
||||||
|
ttm_mem_global_init and ttm_mem_global_release respectively.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Once your global TTM accounting structure is set up and initialized
|
||||||
|
(done by calling ttm_global_item_ref on the global object you
|
||||||
|
just created), you'll need to create a buffer object TTM to
|
||||||
|
provide a pool for buffer object allocation by clients and the
|
||||||
|
kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO,
|
||||||
|
and its size should be sizeof(struct ttm_bo_global). Again,
|
||||||
|
driver specific init and release functions can be provided,
|
||||||
|
likely eventually calling ttm_bo_global_init and
|
||||||
|
ttm_bo_global_release, respectively. Also like the previous
|
||||||
|
object, ttm_global_item_ref is used to create an initial reference
|
||||||
|
count for the TTM, which will call your initalization function.
|
||||||
|
</para>
|
||||||
|
</sect3>
|
||||||
|
<sect3>
|
||||||
|
<title>GEM initialization</title>
|
||||||
|
<para>
|
||||||
|
GEM is an alternative to TTM, designed specifically for UMA
|
||||||
|
devices. It has simpler initialization and execution requirements
|
||||||
|
than TTM, but has no VRAM management capability. Core GEM
|
||||||
|
initialization is comprised of a basic drm_mm_init call to create
|
||||||
|
a GTT DRM MM object, which provides an address space pool for
|
||||||
|
object allocation. In a KMS configuration, the driver will
|
||||||
|
need to allocate and initialize a command ring buffer following
|
||||||
|
basic GEM initialization. Most UMA devices have a so-called
|
||||||
|
"stolen" memory region, which provides space for the initial
|
||||||
|
framebuffer and large, contiguous memory regions required by the
|
||||||
|
device. This space is not typically managed by GEM, and must
|
||||||
|
be initialized separately into its own DRM MM object.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Initialization will be driver specific, and will depend on
|
||||||
|
the architecture of the device. In the case of Intel
|
||||||
|
integrated graphics chips like 965GM, GEM initialization can
|
||||||
|
be done by calling the internal GEM init function,
|
||||||
|
i915_gem_do_init(). Since the 965GM is a UMA device
|
||||||
|
(i.e. it doesn't have dedicated VRAM), GEM will manage
|
||||||
|
making regular RAM available for GPU operations. Memory set
|
||||||
|
aside by the BIOS (called "stolen" memory by the i915
|
||||||
|
driver) will be managed by the DRM memrange allocator; the
|
||||||
|
rest of the aperture will be managed by GEM.
|
||||||
|
<programlisting>
|
||||||
|
/* Basic memrange allocator for stolen space (aka vram) */
|
||||||
|
drm_memrange_init(&dev_priv->vram, 0, prealloc_size);
|
||||||
|
/* Let GEM Manage from end of prealloc space to end of aperture */
|
||||||
|
i915_gem_do_init(dev, prealloc_size, agp_size);
|
||||||
|
</programlisting>
|
||||||
|
<!--!Edrivers/char/drm/drm_memrange.c-->
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Once the memory manager has been set up, we can allocate the
|
||||||
|
command buffer. In the i915 case, this is also done with a
|
||||||
|
GEM function, i915_gem_init_ringbuffer().
|
||||||
|
</para>
|
||||||
|
</sect3>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>Output configuration</title>
|
||||||
|
<para>
|
||||||
|
The final initialization task is output configuration. This involves
|
||||||
|
finding and initializing the CRTCs, encoders and connectors
|
||||||
|
for your device, creating an initial configuration and
|
||||||
|
registering a framebuffer console driver.
|
||||||
|
</para>
|
||||||
|
<sect3>
|
||||||
|
<title>Output discovery and initialization</title>
|
||||||
|
<para>
|
||||||
|
Several core functions exist to create CRTCs, encoders and
|
||||||
|
connectors, namely drm_crtc_init(), drm_connector_init() and
|
||||||
|
drm_encoder_init(), along with several "helper" functions to
|
||||||
|
perform common tasks.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Connectors should be registered with sysfs once they've been
|
||||||
|
detected and initialized, using the
|
||||||
|
drm_sysfs_connector_add() function. Likewise, when they're
|
||||||
|
removed from the system, they should be destroyed with
|
||||||
|
drm_sysfs_connector_remove().
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
void intel_crt_init(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_connector *connector;
|
||||||
|
struct intel_output *intel_output;
|
||||||
|
|
||||||
|
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
|
||||||
|
if (!intel_output)
|
||||||
|
return;
|
||||||
|
|
||||||
|
connector = &intel_output->base;
|
||||||
|
drm_connector_init(dev, &intel_output->base,
|
||||||
|
&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
|
||||||
|
|
||||||
|
drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
|
||||||
|
DRM_MODE_ENCODER_DAC);
|
||||||
|
|
||||||
|
drm_mode_connector_attach_encoder(&intel_output->base,
|
||||||
|
&intel_output->enc);
|
||||||
|
|
||||||
|
/* Set up the DDC bus. */
|
||||||
|
intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
|
||||||
|
if (!intel_output->ddc_bus) {
|
||||||
|
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
|
||||||
|
"failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
intel_output->type = INTEL_OUTPUT_ANALOG;
|
||||||
|
connector->interlace_allowed = 0;
|
||||||
|
connector->doublescan_allowed = 0;
|
||||||
|
|
||||||
|
drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
|
||||||
|
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
|
||||||
|
|
||||||
|
drm_sysfs_connector_add(connector);
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
In the example above (again, taken from the i915 driver), a
|
||||||
|
CRT connector and encoder combination is created. A device
|
||||||
|
specific i2c bus is also created, for fetching EDID data and
|
||||||
|
performing monitor detection. Once the process is complete,
|
||||||
|
the new connector is regsitered with sysfs, to make its
|
||||||
|
properties available to applications.
|
||||||
|
</para>
|
||||||
|
<sect4>
|
||||||
|
<title>Helper functions and core functions</title>
|
||||||
|
<para>
|
||||||
|
Since many PC-class graphics devices have similar display output
|
||||||
|
designs, the DRM provides a set of helper functions to make
|
||||||
|
output management easier. The core helper routines handle
|
||||||
|
encoder re-routing and disabling of unused functions following
|
||||||
|
mode set. Using the helpers is optional, but recommended for
|
||||||
|
devices with PC-style architectures (i.e. a set of display planes
|
||||||
|
for feeding pixels to encoders which are in turn routed to
|
||||||
|
connectors). Devices with more complex requirements needing
|
||||||
|
finer grained management can opt to use the core callbacks
|
||||||
|
directly.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
[Insert typical diagram here.] [Insert OMAP style config here.]
|
||||||
|
</para>
|
||||||
|
</sect4>
|
||||||
|
<para>
|
||||||
|
For each encoder, CRTC and connector, several functions must
|
||||||
|
be provided, depending on the object type. Encoder objects
|
||||||
|
need should provide a DPMS (basically on/off) function, mode fixup
|
||||||
|
(for converting requested modes into native hardware timings),
|
||||||
|
and prepare, set and commit functions for use by the core DRM
|
||||||
|
helper functions. Connector helpers need to provide mode fetch and
|
||||||
|
validity functions as well as an encoder matching function for
|
||||||
|
returing an ideal encoder for a given connector. The core
|
||||||
|
connector functions include a DPMS callback, (deprecated)
|
||||||
|
save/restore routines, detection, mode probing, property handling,
|
||||||
|
and cleanup functions.
|
||||||
|
</para>
|
||||||
|
<!--!Edrivers/char/drm/drm_crtc.h-->
|
||||||
|
<!--!Edrivers/char/drm/drm_crtc.c-->
|
||||||
|
<!--!Edrivers/char/drm/drm_crtc_helper.c-->
|
||||||
|
</sect3>
|
||||||
|
</sect2>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<!-- Internals: vblank handling -->
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>VBlank event handling</title>
|
||||||
|
<para>
|
||||||
|
The DRM core exposes two vertical blank related ioctls:
|
||||||
|
DRM_IOCTL_WAIT_VBLANK and DRM_IOCTL_MODESET_CTL.
|
||||||
|
<!--!Edrivers/char/drm/drm_irq.c-->
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
DRM_IOCTL_WAIT_VBLANK takes a struct drm_wait_vblank structure
|
||||||
|
as its argument, and is used to block or request a signal when a
|
||||||
|
specified vblank event occurs.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
DRM_IOCTL_MODESET_CTL should be called by application level
|
||||||
|
drivers before and after mode setting, since on many devices the
|
||||||
|
vertical blank counter will be reset at that time. Internally,
|
||||||
|
the DRM snapshots the last vblank count when the ioctl is called
|
||||||
|
with the _DRM_PRE_MODESET command so that the counter won't go
|
||||||
|
backwards (which is dealt with when _DRM_POST_MODESET is used).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
To support the functions above, the DRM core provides several
|
||||||
|
helper functions for tracking vertical blank counters, and
|
||||||
|
requires drivers to provide several callbacks:
|
||||||
|
get_vblank_counter(), enable_vblank() and disable_vblank(). The
|
||||||
|
core uses get_vblank_counter() to keep the counter accurate
|
||||||
|
across interrupt disable periods. It should return the current
|
||||||
|
vertical blank event count, which is often tracked in a device
|
||||||
|
register. The enable and disable vblank callbacks should enable
|
||||||
|
and disable vertical blank interrupts, respectively. In the
|
||||||
|
absence of DRM clients waiting on vblank events, the core DRM
|
||||||
|
code will use the disable_vblank() function to disable
|
||||||
|
interrupts, which saves power. They'll be re-enabled again when
|
||||||
|
a client calls the vblank wait ioctl above.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Devices that don't provide a count register can simply use an
|
||||||
|
internal atomic counter incremented on every vertical blank
|
||||||
|
interrupt, and can make their enable and disable vblank
|
||||||
|
functions into no-ops.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Memory management</title>
|
||||||
|
<para>
|
||||||
|
The memory manager lies at the heart of many DRM operations, and
|
||||||
|
is also required to support advanced client features like OpenGL
|
||||||
|
pbuffers. The DRM currently contains two memory managers, TTM
|
||||||
|
and GEM.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>The Translation Table Manager (TTM)</title>
|
||||||
|
<para>
|
||||||
|
TTM was developed by Tungsten Graphics, primarily by Thomas
|
||||||
|
Hellström, and is intended to be a flexible, high performance
|
||||||
|
graphics memory manager.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Drivers wishing to support TTM must fill out a drm_bo_driver
|
||||||
|
structure.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
TTM design background and information belongs here.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>The Graphics Execution Manager (GEM)</title>
|
||||||
|
<para>
|
||||||
|
GEM is an Intel project, authored by Eric Anholt and Keith
|
||||||
|
Packard. It provides simpler interfaces than TTM, and is well
|
||||||
|
suited for UMA devices.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
GEM-enabled drivers must provide gem_init_object() and
|
||||||
|
gem_free_object() callbacks to support the core memory
|
||||||
|
allocation routines. They should also provide several driver
|
||||||
|
specific ioctls to support command execution, pinning, buffer
|
||||||
|
read & write, mapping, and domain ownership transfers.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
On a fundamental level, GEM involves several operations: memory
|
||||||
|
allocation and freeing, command execution, and aperture management
|
||||||
|
at command execution time. Buffer object allocation is relatively
|
||||||
|
straightforward and largely provided by Linux's shmem layer, which
|
||||||
|
provides memory to back each object. When mapped into the GTT
|
||||||
|
or used in a command buffer, the backing pages for an object are
|
||||||
|
flushed to memory and marked write combined so as to be coherent
|
||||||
|
with the GPU. Likewise, when the GPU finishes rendering to an object,
|
||||||
|
if the CPU accesses it, it must be made coherent with the CPU's view
|
||||||
|
of memory, usually involving GPU cache flushing of various kinds.
|
||||||
|
This core CPU<->GPU coherency management is provided by the GEM
|
||||||
|
set domain function, which evaluates an object's current domain and
|
||||||
|
performs any necessary flushing or synchronization to put the object
|
||||||
|
into the desired coherency domain (note that the object may be busy,
|
||||||
|
i.e. an active render target; in that case the set domain function
|
||||||
|
will block the client and wait for rendering to complete before
|
||||||
|
performing any necessary flushing operations).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Perhaps the most important GEM function is providing a command
|
||||||
|
execution interface to clients. Client programs construct command
|
||||||
|
buffers containing references to previously allocated memory objects
|
||||||
|
and submit them to GEM. At that point, GEM will take care to bind
|
||||||
|
all the objects into the GTT, execute the buffer, and provide
|
||||||
|
necessary synchronization between clients accessing the same buffers.
|
||||||
|
This often involves evicting some objects from the GTT and re-binding
|
||||||
|
others (a fairly expensive operation), and providing relocation
|
||||||
|
support which hides fixed GTT offsets from clients. Clients must
|
||||||
|
take care not to submit command buffers that reference more objects
|
||||||
|
than can fit in the GTT or GEM will reject them and no rendering
|
||||||
|
will occur. Similarly, if several objects in the buffer require
|
||||||
|
fence registers to be allocated for correct rendering (e.g. 2D blits
|
||||||
|
on pre-965 chips), care must be taken not to require more fence
|
||||||
|
registers than are available to the client. Such resource management
|
||||||
|
should be abstracted from the client in libdrm.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<!-- Output management -->
|
||||||
|
<sect1>
|
||||||
|
<title>Output management</title>
|
||||||
|
<para>
|
||||||
|
At the core of the DRM output management code is a set of
|
||||||
|
structures representing CRTCs, encoders and connectors.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A CRTC is an abstraction representing a part of the chip that
|
||||||
|
contains a pointer to a scanout buffer. Therefore, the number
|
||||||
|
of CRTCs available determines how many independent scanout
|
||||||
|
buffers can be active at any given time. The CRTC structure
|
||||||
|
contains several fields to support this: a pointer to some video
|
||||||
|
memory, a display mode, and an (x, y) offset into the video
|
||||||
|
memory to support panning or configurations where one piece of
|
||||||
|
video memory spans multiple CRTCs.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
An encoder takes pixel data from a CRTC and converts it to a
|
||||||
|
format suitable for any attached connectors. On some devices,
|
||||||
|
it may be possible to have a CRTC send data to more than one
|
||||||
|
encoder. In that case, both encoders would receive data from
|
||||||
|
the same scanout buffer, resulting in a "cloned" display
|
||||||
|
configuration across the connectors attached to each encoder.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A connector is the final destination for pixel data on a device,
|
||||||
|
and usually connects directly to an external display device like
|
||||||
|
a monitor or laptop panel. A connector can only be attached to
|
||||||
|
one encoder at a time. The connector is also the structure
|
||||||
|
where information about the attached display is kept, so it
|
||||||
|
contains fields for display data, EDID data, DPMS &
|
||||||
|
connection status, and information about modes supported on the
|
||||||
|
attached displays.
|
||||||
|
</para>
|
||||||
|
<!--!Edrivers/char/drm/drm_crtc.c-->
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Framebuffer management</title>
|
||||||
|
<para>
|
||||||
|
In order to set a mode on a given CRTC, encoder and connector
|
||||||
|
configuration, clients need to provide a framebuffer object which
|
||||||
|
will provide a source of pixels for the CRTC to deliver to the encoder(s)
|
||||||
|
and ultimately the connector(s) in the configuration. A framebuffer
|
||||||
|
is fundamentally a driver specific memory object, made into an opaque
|
||||||
|
handle by the DRM addfb function. Once an fb has been created this
|
||||||
|
way it can be passed to the KMS mode setting routines for use in
|
||||||
|
a configuration.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Command submission & fencing</title>
|
||||||
|
<para>
|
||||||
|
This should cover a few device specific command submission
|
||||||
|
implementations.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Suspend/resume</title>
|
||||||
|
<para>
|
||||||
|
The DRM core provides some suspend/resume code, but drivers
|
||||||
|
wanting full suspend/resume support should provide save() and
|
||||||
|
restore() functions. These will be called at suspend,
|
||||||
|
hibernate, or resume time, and should perform any state save or
|
||||||
|
restore required by your device across suspend or hibernate
|
||||||
|
states.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>DMA services</title>
|
||||||
|
<para>
|
||||||
|
This should cover how DMA mapping etc. is supported by the core.
|
||||||
|
These functions are deprecated and should not be used.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<!-- External interfaces -->
|
||||||
|
|
||||||
|
<chapter id="drmExternals">
|
||||||
|
<title>Userland interfaces</title>
|
||||||
|
<para>
|
||||||
|
The DRM core exports several interfaces to applications,
|
||||||
|
generally intended to be used through corresponding libdrm
|
||||||
|
wrapper functions. In addition, drivers export device specific
|
||||||
|
interfaces for use by userspace drivers & device aware
|
||||||
|
applications through ioctls and sysfs files.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
External interfaces include: memory mapping, context management,
|
||||||
|
DMA operations, AGP management, vblank control, fence
|
||||||
|
management, memory management, and output management.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Cover generic ioctls and sysfs layout here. Only need high
|
||||||
|
level info, since man pages will cover the rest.
|
||||||
|
</para>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<!-- API reference -->
|
||||||
|
|
||||||
|
<appendix id="drmDriverApi">
|
||||||
|
<title>DRM Driver API</title>
|
||||||
|
<para>
|
||||||
|
Include auto-generated API reference here (need to reference it
|
||||||
|
from paragraphs above too).
|
||||||
|
</para>
|
||||||
|
</appendix>
|
||||||
|
|
||||||
|
</book>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<book id="kgdbOnLinux">
|
<book id="kgdbOnLinux">
|
||||||
<bookinfo>
|
<bookinfo>
|
||||||
<title>Using kgdb and the kgdb Internals</title>
|
<title>Using kgdb, kdb and the kernel debugger internals</title>
|
||||||
|
|
||||||
<authorgroup>
|
<authorgroup>
|
||||||
<author>
|
<author>
|
||||||
@@ -17,33 +17,8 @@
|
|||||||
</affiliation>
|
</affiliation>
|
||||||
</author>
|
</author>
|
||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Tom</firstname>
|
|
||||||
<surname>Rini</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>trini@kernel.crashing.org</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Amit S.</firstname>
|
|
||||||
<surname>Kale</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>amitkale@linsyssoft.com</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2008</year>
|
<year>2008,2010</year>
|
||||||
<holder>Wind River Systems, Inc.</holder>
|
<holder>Wind River Systems, Inc.</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
<copyright>
|
<copyright>
|
||||||
@@ -69,41 +44,76 @@
|
|||||||
<chapter id="Introduction">
|
<chapter id="Introduction">
|
||||||
<title>Introduction</title>
|
<title>Introduction</title>
|
||||||
<para>
|
<para>
|
||||||
kgdb is a source level debugger for linux kernel. It is used along
|
The kernel has two different debugger front ends (kdb and kgdb)
|
||||||
with gdb to debug a linux kernel. The expectation is that gdb can
|
which interface to the debug core. It is possible to use either
|
||||||
be used to "break in" to the kernel to inspect memory, variables
|
of the debugger front ends and dynamically transition between them
|
||||||
and look through call stack information similar to what an
|
if you configure the kernel properly at compile and runtime.
|
||||||
application developer would use gdb for. It is possible to place
|
|
||||||
breakpoints in kernel code and perform some limited execution
|
|
||||||
stepping.
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Two machines are required for using kgdb. One of these machines is a
|
Kdb is simplistic shell-style interface which you can use on a
|
||||||
development machine and the other is a test machine. The kernel
|
system console with a keyboard or serial console. You can use it
|
||||||
to be debugged runs on the test machine. The development machine
|
to inspect memory, registers, process lists, dmesg, and even set
|
||||||
runs an instance of gdb against the vmlinux file which contains
|
breakpoints to stop in a certain location. Kdb is not a source
|
||||||
the symbols (not boot image such as bzImage, zImage, uImage...).
|
level debugger, although you can set breakpoints and execute some
|
||||||
In gdb the developer specifies the connection parameters and
|
basic kernel run control. Kdb is mainly aimed at doing some
|
||||||
connects to kgdb. The type of connection a developer makes with
|
analysis to aid in development or diagnosing kernel problems. You
|
||||||
gdb depends on the availability of kgdb I/O modules compiled as
|
can access some symbols by name in kernel built-ins or in kernel
|
||||||
builtin's or kernel modules in the test machine's kernel.
|
modules if the code was built
|
||||||
|
with <symbol>CONFIG_KALLSYMS</symbol>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Kgdb is intended to be used as a source level debugger for the
|
||||||
|
Linux kernel. It is used along with gdb to debug a Linux kernel.
|
||||||
|
The expectation is that gdb can be used to "break in" to the
|
||||||
|
kernel to inspect memory, variables and look through call stack
|
||||||
|
information similar to the way an application developer would use
|
||||||
|
gdb to debug an application. It is possible to place breakpoints
|
||||||
|
in kernel code and perform some limited execution stepping.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Two machines are required for using kgdb. One of these machines is
|
||||||
|
a development machine and the other is the target machine. The
|
||||||
|
kernel to be debugged runs on the target machine. The development
|
||||||
|
machine runs an instance of gdb against the vmlinux file which
|
||||||
|
contains the symbols (not boot image such as bzImage, zImage,
|
||||||
|
uImage...). In gdb the developer specifies the connection
|
||||||
|
parameters and connects to kgdb. The type of connection a
|
||||||
|
developer makes with gdb depends on the availability of kgdb I/O
|
||||||
|
modules compiled as built-ins or loadable kernel modules in the test
|
||||||
|
machine's kernel.
|
||||||
</para>
|
</para>
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="CompilingAKernel">
|
<chapter id="CompilingAKernel">
|
||||||
<title>Compiling a kernel</title>
|
<title>Compiling a kernel</title>
|
||||||
<para>
|
<para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>In order to enable compilation of kdb, you must first enable kgdb.</para></listitem>
|
||||||
|
<listitem><para>The kgdb test compile options are described in the kgdb test suite chapter.</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
<sect1 id="CompileKGDB">
|
||||||
|
<title>Kernel config options for kgdb</title>
|
||||||
|
<para>
|
||||||
To enable <symbol>CONFIG_KGDB</symbol> you should first turn on
|
To enable <symbol>CONFIG_KGDB</symbol> you should first turn on
|
||||||
"Prompt for development and/or incomplete code/drivers"
|
"Prompt for development and/or incomplete code/drivers"
|
||||||
(CONFIG_EXPERIMENTAL) in "General setup", then under the
|
(CONFIG_EXPERIMENTAL) in "General setup", then under the
|
||||||
"Kernel debugging" select "KGDB: kernel debugging with remote gdb".
|
"Kernel debugging" select "KGDB: kernel debugger".
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
While it is not a hard requirement that you have symbols in your
|
||||||
|
vmlinux file, gdb tends not to be very useful without the symbolic
|
||||||
|
data, so you will want to turn
|
||||||
|
on <symbol>CONFIG_DEBUG_INFO</symbol> which is called "Compile the
|
||||||
|
kernel with debug info" in the config menu.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
It is advised, but not required that you turn on the
|
It is advised, but not required that you turn on the
|
||||||
CONFIG_FRAME_POINTER kernel option. This option inserts code to
|
<symbol>CONFIG_FRAME_POINTER</symbol> kernel option which is called "Compile the
|
||||||
into the compiled executable which saves the frame information in
|
kernel with frame pointers" in the config menu. This option
|
||||||
registers or on the stack at different points which will allow a
|
inserts code to into the compiled executable which saves the frame
|
||||||
debugger such as gdb to more accurately construct stack back traces
|
information in registers or on the stack at different points which
|
||||||
while debugging the kernel.
|
allows a debugger such as gdb to more accurately construct
|
||||||
|
stack back traces while debugging the kernel.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
If the architecture that you are using supports the kernel option
|
If the architecture that you are using supports the kernel option
|
||||||
@@ -116,38 +126,160 @@
|
|||||||
this option.
|
this option.
|
||||||
</para>
|
</para>
|
||||||
<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
|
||||||
host and debugged target. Early boot debugging requires a KGDB
|
debugging host and debugged target. Early boot debugging requires
|
||||||
I/O driver that supports early debugging and the driver must be
|
a KGDB I/O driver that supports early debugging and the driver
|
||||||
built into the kernel directly. Kgdb I/O driver configuration
|
must be built into the kernel directly. Kgdb I/O driver
|
||||||
takes place via kernel or module parameters, see following
|
configuration takes place via kernel or module parameters which
|
||||||
chapter.
|
you can learn more about in the in the section that describes the
|
||||||
|
parameter "kgdboc".
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>Here is an example set of .config symbols to enable or
|
||||||
The kgdb test compile options are described in the kgdb test suite chapter.
|
disable for kgdb:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para># CONFIG_DEBUG_RODATA is not set</para></listitem>
|
||||||
|
<listitem><para>CONFIG_FRAME_POINTER=y</para></listitem>
|
||||||
|
<listitem><para>CONFIG_KGDB=y</para></listitem>
|
||||||
|
<listitem><para>CONFIG_KGDB_SERIAL_CONSOLE=y</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
</sect1>
|
||||||
|
<sect1 id="CompileKDB">
|
||||||
|
<title>Kernel config options for kdb</title>
|
||||||
|
<para>Kdb is quite a bit more complex than the simple gdbstub
|
||||||
|
sitting on top of the kernel's debug core. Kdb must implement a
|
||||||
|
shell, and also adds some helper functions in other parts of the
|
||||||
|
kernel, responsible for printing out interesting data such as what
|
||||||
|
you would see if you ran "lsmod", or "ps". In order to build kdb
|
||||||
|
into the kernel you follow the same steps as you would for kgdb.
|
||||||
|
</para>
|
||||||
|
<para>The main config option for kdb
|
||||||
|
is <symbol>CONFIG_KGDB_KDB</symbol> which is called "KGDB_KDB:
|
||||||
|
include kdb frontend for kgdb" in the config menu. In theory you
|
||||||
|
would have already also selected an I/O driver such as the
|
||||||
|
CONFIG_KGDB_SERIAL_CONSOLE interface if you plan on using kdb on a
|
||||||
|
serial port, when you were configuring kgdb.
|
||||||
|
</para>
|
||||||
|
<para>If you want to use a PS/2-style keyboard with kdb, you would
|
||||||
|
select CONFIG_KDB_KEYBOARD which is called "KGDB_KDB: keyboard as
|
||||||
|
input device" in the config menu. The CONFIG_KDB_KEYBOARD option
|
||||||
|
is not used for anything in the gdb interface to kgdb. The
|
||||||
|
CONFIG_KDB_KEYBOARD option only works with kdb.
|
||||||
|
</para>
|
||||||
|
<para>Here is an example set of .config symbols to enable/disable kdb:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para># CONFIG_DEBUG_RODATA is not set</para></listitem>
|
||||||
|
<listitem><para>CONFIG_FRAME_POINTER=y</para></listitem>
|
||||||
|
<listitem><para>CONFIG_KGDB=y</para></listitem>
|
||||||
|
<listitem><para>CONFIG_KGDB_SERIAL_CONSOLE=y</para></listitem>
|
||||||
|
<listitem><para>CONFIG_KGDB_KDB=y</para></listitem>
|
||||||
|
<listitem><para>CONFIG_KDB_KEYBOARD=y</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="EnableKGDB">
|
<chapter id="kgdbKernelArgs">
|
||||||
<title>Enable kgdb for debugging</title>
|
<title>Kernel Debugger Boot Arguments</title>
|
||||||
<para>
|
<para>This section describes the various runtime kernel
|
||||||
In order to use kgdb you must activate it by passing configuration
|
parameters that affect the configuration of the kernel debugger.
|
||||||
information to one of the kgdb I/O drivers. If you do not pass any
|
The following chapter covers using kdb and kgdb as well as
|
||||||
configuration information kgdb will not do anything at all. Kgdb
|
provides some examples of the configuration parameters.</para>
|
||||||
will only actively hook up to the kernel trap hooks if a kgdb I/O
|
<sect1 id="kgdboc">
|
||||||
driver is loaded and configured. If you unconfigure a kgdb I/O
|
<title>Kernel parameter: kgdboc</title>
|
||||||
driver, kgdb will unregister all the kernel hook points.
|
<para>The kgdboc driver was originally an abbreviation meant to
|
||||||
|
stand for "kgdb over console". Today it is the primary mechanism
|
||||||
|
to configure how to communicate from gdb to kgdb as well as the
|
||||||
|
devices you want to use to interact with the kdb shell.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>For kgdb/gdb, kgdboc is designed to work with a single serial
|
||||||
All drivers can be reconfigured at run time, if
|
port. It is intended to cover the circumstance where you want to
|
||||||
<symbol>CONFIG_SYSFS</symbol> and <symbol>CONFIG_MODULES</symbol>
|
use a serial console as your primary console as well as using it to
|
||||||
are enabled, by echo'ing a new config string to
|
perform kernel debugging. It is also possible to use kgdb on a
|
||||||
<constant>/sys/module/<driver>/parameter/<option></constant>.
|
serial port which is not designated as a system console. Kgdboc
|
||||||
The driver can be unconfigured by passing an empty string. You cannot
|
may be configured as a kernel built-in or a kernel loadable module.
|
||||||
change the configuration while the debugger is attached. Make sure
|
You can only make use of <constant>kgdbwait</constant> and early
|
||||||
to detach the debugger with the <constant>detach</constant> command
|
debugging if you build kgdboc into the kernel as a built-in.
|
||||||
prior to trying unconfigure a kgdb I/O driver.
|
|
||||||
</para>
|
</para>
|
||||||
|
<sect2 id="kgdbocArgs">
|
||||||
|
<title>kgdboc arguments</title>
|
||||||
|
<para>Usage: <constant>kgdboc=[kbd][[,]serial_device][,baud]</constant></para>
|
||||||
|
<sect3 id="kgdbocArgs1">
|
||||||
|
<title>Using loadable module or built-in</title>
|
||||||
|
<para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>As a kernel built-in:</para>
|
||||||
|
<para>Use the kernel boot argument: <constant>kgdboc=<tty-device>,[baud]</constant></para></listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>As a kernel loadable module:</para>
|
||||||
|
<para>Use the command: <constant>modprobe kgdboc kgdboc=<tty-device>,[baud]</constant></para>
|
||||||
|
<para>Here are two examples of how you might formate the kgdboc
|
||||||
|
string. The first is for an x86 target using the first serial port.
|
||||||
|
The second example is for the ARM Versatile AB using the second
|
||||||
|
serial port.
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para><constant>kgdboc=ttyS0,115200</constant></para></listitem>
|
||||||
|
<listitem><para><constant>kgdboc=ttyAMA1,115200</constant></para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist></para>
|
||||||
|
</sect3>
|
||||||
|
<sect3 id="kgdbocArgs2">
|
||||||
|
<title>Configure kgdboc at runtime with sysfs</title>
|
||||||
|
<para>At run time you can enable or disable kgdboc by echoing a
|
||||||
|
parameters into the sysfs. Here are two examples:</para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>Enable kgdboc on ttyS0</para>
|
||||||
|
<para><constant>echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
||||||
|
<listitem><para>Disable kgdboc</para>
|
||||||
|
<para><constant>echo "" > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
<para>NOTE: You do not need to specify the baud if you are
|
||||||
|
configuring the console on tty which is already configured or
|
||||||
|
open.</para>
|
||||||
|
</sect3>
|
||||||
|
<sect3 id="kgdbocArgs3">
|
||||||
|
<title>More examples</title>
|
||||||
|
<para>You can configure kgdboc to use the keyboard, and or a serial device
|
||||||
|
depending on if you are using kdb and or kgdb, in one of the
|
||||||
|
following scenarios.
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>kdb and kgdb over only a serial port</para>
|
||||||
|
<para><constant>kgdboc=<serial_device>[,baud]</constant></para>
|
||||||
|
<para>Example: <constant>kgdboc=ttyS0,115200</constant></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>kdb and kgdb with keyboard and a serial port</para>
|
||||||
|
<para><constant>kgdboc=kbd,<serial_device>[,baud]</constant></para>
|
||||||
|
<para>Example: <constant>kgdboc=kbd,ttyS0,115200</constant></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>kdb with a keyboard</para>
|
||||||
|
<para><constant>kgdboc=kbd</constant></para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</para>
|
||||||
|
</sect3>
|
||||||
|
<para>NOTE: Kgdboc does not support interrupting the target via the
|
||||||
|
gdb remote protocol. You must manually send a sysrq-g unless you
|
||||||
|
have a proxy that splits console output to a terminal program.
|
||||||
|
A console proxy has a separate TCP port for the debugger and a separate
|
||||||
|
TCP port for the "human" console. The proxy can take care of sending
|
||||||
|
the sysrq-g for you.
|
||||||
|
</para>
|
||||||
|
<para>When using kgdboc with no debugger proxy, you can end up
|
||||||
|
connecting the debugger at one of two entry points. If an
|
||||||
|
exception occurs after you have loaded kgdboc, a message should
|
||||||
|
print on the console stating it is waiting for the debugger. In
|
||||||
|
this case you disconnect your terminal program and then connect the
|
||||||
|
debugger in its place. If you want to interrupt the target system
|
||||||
|
and forcibly enter a debug session you have to issue a Sysrq
|
||||||
|
sequence and then type the letter <constant>g</constant>. Then
|
||||||
|
you disconnect the terminal session and connect gdb. Your options
|
||||||
|
if you don't like this are to hack gdb to send the sysrq-g for you
|
||||||
|
as well as on the initial connect, or to use a debugger proxy that
|
||||||
|
allows an unmodified gdb to do the debugging.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
</sect1>
|
||||||
<sect1 id="kgdbwait">
|
<sect1 id="kgdbwait">
|
||||||
<title>Kernel parameter: kgdbwait</title>
|
<title>Kernel parameter: kgdbwait</title>
|
||||||
<para>
|
<para>
|
||||||
@@ -162,71 +294,25 @@
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The kernel will stop and wait as early as the I/O driver and
|
The kernel will stop and wait as early as the I/O driver and
|
||||||
architecture will allow when you use this option. If you build the
|
architecture allows when you use this option. If you build the
|
||||||
kgdb I/O driver as a kernel module kgdbwait will not do anything.
|
kgdb I/O driver as a loadable kernel module kgdbwait will not do
|
||||||
|
anything.
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1 id="kgdboc">
|
|
||||||
<title>Kernel parameter: kgdboc</title>
|
|
||||||
<para>
|
|
||||||
The kgdboc driver was originally an abbreviation meant to stand for
|
|
||||||
"kgdb over console". Kgdboc is designed to work with a single
|
|
||||||
serial port. It was meant to cover the circumstance
|
|
||||||
where you wanted to use a serial console as your primary console as
|
|
||||||
well as using it to perform kernel debugging. Of course you can
|
|
||||||
also use kgdboc without assigning a console to the same port.
|
|
||||||
</para>
|
|
||||||
<sect2 id="UsingKgdboc">
|
|
||||||
<title>Using kgdboc</title>
|
|
||||||
<para>
|
|
||||||
You can configure kgdboc via sysfs or a module or kernel boot line
|
|
||||||
parameter depending on if you build with CONFIG_KGDBOC as a module
|
|
||||||
or built-in.
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>From the module load or build-in</para>
|
|
||||||
<para><constant>kgdboc=<tty-device>,[baud]</constant></para>
|
|
||||||
<para>
|
|
||||||
The example here would be if your console port was typically ttyS0, you would use something like <constant>kgdboc=ttyS0,115200</constant> or on the ARM Versatile AB you would likely use <constant>kgdboc=ttyAMA0,115200</constant>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>From sysfs</para>
|
|
||||||
<para><constant>echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc</constant></para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
NOTE: Kgdboc does not support interrupting the target via the
|
|
||||||
gdb remote protocol. You must manually send a sysrq-g unless you
|
|
||||||
have a proxy that splits console output to a terminal problem and
|
|
||||||
has a separate port for the debugger to connect to that sends the
|
|
||||||
sysrq-g for you.
|
|
||||||
</para>
|
|
||||||
<para>When using kgdboc with no debugger proxy, you can end up
|
|
||||||
connecting the debugger for one of two entry points. If an
|
|
||||||
exception occurs after you have loaded kgdboc a message should print
|
|
||||||
on the console stating it is waiting for the debugger. In case you
|
|
||||||
disconnect your terminal program and then connect the debugger in
|
|
||||||
its place. If you want to interrupt the target system and forcibly
|
|
||||||
enter a debug session you have to issue a Sysrq sequence and then
|
|
||||||
type the letter <constant>g</constant>. Then you disconnect the
|
|
||||||
terminal session and connect gdb. Your options if you don't like
|
|
||||||
this are to hack gdb to send the sysrq-g for you as well as on the
|
|
||||||
initial connect, or to use a debugger proxy that allows an
|
|
||||||
unmodified gdb to do the debugging.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="kgdbcon">
|
<sect1 id="kgdbcon">
|
||||||
<title>Kernel parameter: kgdbcon</title>
|
<title>Kernel parameter: kgdbcon</title>
|
||||||
<para>
|
<para> The kgdbcon feature allows you to see printk() messages
|
||||||
Kgdb supports using the gdb serial protocol to send console messages
|
inside gdb while gdb is connected to the kernel. Kdb does not make
|
||||||
to the debugger when the debugger is connected and running. There
|
use of the kgdbcon feature.
|
||||||
are two ways to activate this feature.
|
</para>
|
||||||
|
<para>Kgdb supports using the gdb serial protocol to send console
|
||||||
|
messages to the debugger when the debugger is connected and running.
|
||||||
|
There are two ways to activate this feature.
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
<listitem><para>Activate with the kernel command line option:</para>
|
<listitem><para>Activate with the kernel command line option:</para>
|
||||||
<para><constant>kgdbcon</constant></para>
|
<para><constant>kgdbcon</constant></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>Use sysfs before configuring an io driver</para>
|
<listitem><para>Use sysfs before configuring an I/O driver</para>
|
||||||
<para>
|
<para>
|
||||||
<constant>echo 1 > /sys/module/kgdb/parameters/kgdb_use_con</constant>
|
<constant>echo 1 > /sys/module/kgdb/parameters/kgdb_use_con</constant>
|
||||||
</para>
|
</para>
|
||||||
@@ -237,28 +323,175 @@
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
|
<para>IMPORTANT NOTE: You cannot use kgdboc + kgdbcon on a tty that is an
|
||||||
|
active system console. An example incorrect usage is <constant>console=ttyS0,115200 kgdboc=ttyS0 kgdbcon</constant>
|
||||||
|
</para>
|
||||||
|
<para>It is possible to use this option with kgdboc on a tty that is not a system console.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
IMPORTANT NOTE: Using this option with kgdb over the console
|
|
||||||
(kgdboc) is not supported.
|
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="ConnectingGDB">
|
<chapter id="usingKDB">
|
||||||
<title>Connecting gdb</title>
|
<title>Using kdb</title>
|
||||||
<para>
|
<para>
|
||||||
If you are using kgdboc, you need to have used kgdbwait as a boot
|
|
||||||
argument, issued a sysrq-g, or the system you are going to debug
|
|
||||||
has already taken an exception and is waiting for the debugger to
|
|
||||||
attach before you can connect gdb.
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<sect1 id="quickKDBserial">
|
||||||
If you are not using different kgdb I/O driver other than kgdboc,
|
<title>Quick start for kdb on a serial port</title>
|
||||||
you should be able to connect and the target will automatically
|
<para>This is a quick example of how to use kdb.</para>
|
||||||
respond.
|
<para><orderedlist>
|
||||||
|
<listitem><para>Boot kernel with arguments:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para><constant>console=ttyS0,115200 kgdboc=ttyS0,115200</constant></para></listitem>
|
||||||
|
</itemizedlist></para>
|
||||||
|
<para>OR</para>
|
||||||
|
<para>Configure kgdboc after the kernel booted; assuming you are using a serial port console:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para><constant>echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>Enter the kernel debugger manually or by waiting for an oops or fault. There are several ways you can enter the kernel debugger manually; all involve using the sysrq-g, which means you must have enabled CONFIG_MAGIC_SYSRQ=y in your kernel config.</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>When logged in as root or with a super user session you can run:</para>
|
||||||
|
<para><constant>echo g > /proc/sysrq-trigger</constant></para></listitem>
|
||||||
|
<listitem><para>Example using minicom 2.2</para>
|
||||||
|
<para>Press: <constant>Control-a</constant></para>
|
||||||
|
<para>Press: <constant>f</constant></para>
|
||||||
|
<para>Press: <constant>g</constant></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>When you have telneted to a terminal server that supports sending a remote break</para>
|
||||||
|
<para>Press: <constant>Control-]</constant></para>
|
||||||
|
<para>Type in:<constant>send break</constant></para>
|
||||||
|
<para>Press: <constant>Enter</constant></para>
|
||||||
|
<para>Press: <constant>g</constant></para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>From the kdb prompt you can run the "help" command to see a complete list of the commands that are available.</para>
|
||||||
|
<para>Some useful commands in kdb include:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>lsmod -- Shows where kernel modules are loaded</para></listitem>
|
||||||
|
<listitem><para>ps -- Displays only the active processes</para></listitem>
|
||||||
|
<listitem><para>ps A -- Shows all the processes</para></listitem>
|
||||||
|
<listitem><para>summary -- Shows kernel version info and memory usage</para></listitem>
|
||||||
|
<listitem><para>bt -- Get a backtrace of the current process using dump_stack()</para></listitem>
|
||||||
|
<listitem><para>dmesg -- View the kernel syslog buffer</para></listitem>
|
||||||
|
<listitem><para>go -- Continue the system</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>When you are done using kdb you need to consider rebooting the
|
||||||
|
system or using the "go" command to resuming normal kernel
|
||||||
|
execution. If you have paused the kernel for a lengthy period of
|
||||||
|
time, applications that rely on timely networking or anything to do
|
||||||
|
with real wall clock time could be adversely affected, so you
|
||||||
|
should take this into consideration when using the kernel
|
||||||
|
debugger.</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist></para>
|
||||||
|
</sect1>
|
||||||
|
<sect1 id="quickKDBkeyboard">
|
||||||
|
<title>Quick start for kdb using a keyboard connected console</title>
|
||||||
|
<para>This is a quick example of how to use kdb with a keyboard.</para>
|
||||||
|
<para><orderedlist>
|
||||||
|
<listitem><para>Boot kernel with arguments:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para><constant>kgdboc=kbd</constant></para></listitem>
|
||||||
|
</itemizedlist></para>
|
||||||
|
<para>OR</para>
|
||||||
|
<para>Configure kgdboc after the kernel booted:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para><constant>echo kbd > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>Enter the kernel debugger manually or by waiting for an oops or fault. There are several ways you can enter the kernel debugger manually; all involve using the sysrq-g, which means you must have enabled CONFIG_MAGIC_SYSRQ=y in your kernel config.</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>When logged in as root or with a super user session you can run:</para>
|
||||||
|
<para><constant>echo g > /proc/sysrq-trigger</constant></para></listitem>
|
||||||
|
<listitem><para>Example using a laptop keyboard</para>
|
||||||
|
<para>Press and hold down: <constant>Alt</constant></para>
|
||||||
|
<para>Press and hold down: <constant>Fn</constant></para>
|
||||||
|
<para>Press and release the key with the label: <constant>SysRq</constant></para>
|
||||||
|
<para>Release: <constant>Fn</constant></para>
|
||||||
|
<para>Press and release: <constant>g</constant></para>
|
||||||
|
<para>Release: <constant>Alt</constant></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>Example using a PS/2 101-key keyboard</para>
|
||||||
|
<para>Press and hold down: <constant>Alt</constant></para>
|
||||||
|
<para>Press and release the key with the label: <constant>SysRq</constant></para>
|
||||||
|
<para>Press and release: <constant>g</constant></para>
|
||||||
|
<para>Release: <constant>Alt</constant></para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Now type in a kdb command such as "help", "dmesg", "bt" or "go" to continue kernel execution.</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist></para>
|
||||||
|
</sect1>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="EnableKGDB">
|
||||||
|
<title>Using kgdb / gdb</title>
|
||||||
|
<para>In order to use kgdb you must activate it by passing
|
||||||
|
configuration information to one of the kgdb I/O drivers. If you
|
||||||
|
do not pass any configuration information kgdb will not do anything
|
||||||
|
at all. Kgdb will only actively hook up to the kernel trap hooks
|
||||||
|
if a kgdb I/O driver is loaded and configured. If you unconfigure
|
||||||
|
a kgdb I/O driver, kgdb will unregister all the kernel hook points.
|
||||||
|
</para>
|
||||||
|
<para> All kgdb I/O drivers can be reconfigured at run time, if
|
||||||
|
<symbol>CONFIG_SYSFS</symbol> and <symbol>CONFIG_MODULES</symbol>
|
||||||
|
are enabled, by echo'ing a new config string to
|
||||||
|
<constant>/sys/module/<driver>/parameter/<option></constant>.
|
||||||
|
The driver can be unconfigured by passing an empty string. You cannot
|
||||||
|
change the configuration while the debugger is attached. Make sure
|
||||||
|
to detach the debugger with the <constant>detach</constant> command
|
||||||
|
prior to trying to unconfigure a kgdb I/O driver.
|
||||||
|
</para>
|
||||||
|
<sect1 id="ConnectingGDB">
|
||||||
|
<title>Connecting with gdb to a serial port</title>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>Configure kgdboc</para>
|
||||||
|
<para>Boot kernel with arguments:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para><constant>kgdboc=ttyS0,115200</constant></para></listitem>
|
||||||
|
</itemizedlist></para>
|
||||||
|
<para>OR</para>
|
||||||
|
<para>Configure kgdboc after the kernel booted:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para><constant>echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
||||||
|
</itemizedlist></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Stop kernel execution (break into the debugger)</para>
|
||||||
|
<para>In order to connect to gdb via kgdboc, the kernel must
|
||||||
|
first be stopped. There are several ways to stop the kernel which
|
||||||
|
include using kgdbwait as a boot argument, via a sysrq-g, or running
|
||||||
|
the kernel until it takes an exception where it waits for the
|
||||||
|
debugger to attach.
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>When logged in as root or with a super user session you can run:</para>
|
||||||
|
<para><constant>echo g > /proc/sysrq-trigger</constant></para></listitem>
|
||||||
|
<listitem><para>Example using minicom 2.2</para>
|
||||||
|
<para>Press: <constant>Control-a</constant></para>
|
||||||
|
<para>Press: <constant>f</constant></para>
|
||||||
|
<para>Press: <constant>g</constant></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>When you have telneted to a terminal server that supports sending a remote break</para>
|
||||||
|
<para>Press: <constant>Control-]</constant></para>
|
||||||
|
<para>Type in:<constant>send break</constant></para>
|
||||||
|
<para>Press: <constant>Enter</constant></para>
|
||||||
|
<para>Press: <constant>g</constant></para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Connect from from gdb</para>
|
||||||
<para>
|
<para>
|
||||||
Example (using a serial port):
|
Example (using a directly connected port):
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
% gdb ./vmlinux
|
% gdb ./vmlinux
|
||||||
@@ -266,7 +499,7 @@
|
|||||||
(gdb) target remote /dev/ttyS0
|
(gdb) target remote /dev/ttyS0
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
Example (kgdb to a terminal server on tcp port 2012):
|
Example (kgdb to a terminal server on TCP port 2012):
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
% gdb ./vmlinux
|
% gdb ./vmlinux
|
||||||
@@ -283,6 +516,83 @@
|
|||||||
communications. You do this prior to issuing the <constant>target
|
communications. You do this prior to issuing the <constant>target
|
||||||
remote</constant> command by typing in: <constant>set debug remote 1</constant>
|
remote</constant> command by typing in: <constant>set debug remote 1</constant>
|
||||||
</para>
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
<para>Remember if you continue in gdb, and need to "break in" again,
|
||||||
|
you need to issue an other sysrq-g. It is easy to create a simple
|
||||||
|
entry point by putting a breakpoint at <constant>sys_sync</constant>
|
||||||
|
and then you can run "sync" from a shell or script to break into the
|
||||||
|
debugger.</para>
|
||||||
|
</sect1>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="switchKdbKgdb">
|
||||||
|
<title>kgdb and kdb interoperability</title>
|
||||||
|
<para>It is possible to transition between kdb and kgdb dynamically.
|
||||||
|
The debug core will remember which you used the last time and
|
||||||
|
automatically start in the same mode.</para>
|
||||||
|
<sect1>
|
||||||
|
<title>Switching between kdb and kgdb</title>
|
||||||
|
<sect2>
|
||||||
|
<title>Switching from kgdb to kdb</title>
|
||||||
|
<para>
|
||||||
|
There are two ways to switch from kgdb to kdb: you can use gdb to
|
||||||
|
issue a maintenance packet, or you can blindly type the command $3#33.
|
||||||
|
Whenever kernel debugger stops in kgdb mode it will print the
|
||||||
|
message <constant>KGDB or $3#33 for KDB</constant>. It is important
|
||||||
|
to note that you have to type the sequence correctly in one pass.
|
||||||
|
You cannot type a backspace or delete because kgdb will interpret
|
||||||
|
that as part of the debug stream.
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>Change from kgdb to kdb by blindly typing:</para>
|
||||||
|
<para><constant>$3#33</constant></para></listitem>
|
||||||
|
<listitem><para>Change from kgdb to kdb with gdb</para>
|
||||||
|
<para><constant>maintenance packet 3</constant></para>
|
||||||
|
<para>NOTE: Now you must kill gdb. Typically you press control-z and
|
||||||
|
issue the command: kill -9 %</para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
<sect2>
|
||||||
|
<title>Change from kdb to kgdb</title>
|
||||||
|
<para>There are two ways you can change from kdb to kgdb. You can
|
||||||
|
manually enter kgdb mode by issuing the kgdb command from the kdb
|
||||||
|
shell prompt, or you can connect gdb while the kdb shell prompt is
|
||||||
|
active. The kdb shell looks for the typical first commands that gdb
|
||||||
|
would issue with the gdb remote protocol and if it sees one of those
|
||||||
|
commands it automatically changes into kgdb mode.</para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>From kdb issue the command:</para>
|
||||||
|
<para><constant>kgdb</constant></para>
|
||||||
|
<para>Now disconnect your terminal program and connect gdb in its place</para></listitem>
|
||||||
|
<listitem><para>At the kdb prompt, disconnect the terminal program and connect gdb in its place.</para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</sect2>
|
||||||
|
</sect1>
|
||||||
|
<sect1>
|
||||||
|
<title>Running kdb commands from gdb</title>
|
||||||
|
<para>It is possible to run a limited set of kdb commands from gdb,
|
||||||
|
using the gdb monitor command. You don't want to execute any of the
|
||||||
|
run control or breakpoint operations, because it can disrupt the
|
||||||
|
state of the kernel debugger. You should be using gdb for
|
||||||
|
breakpoints and run control operations if you have gdb connected.
|
||||||
|
The more useful commands to run are things like lsmod, dmesg, ps or
|
||||||
|
possibly some of the memory information commands. To see all the kdb
|
||||||
|
commands you can run <constant>monitor help</constant>.</para>
|
||||||
|
<para>Example:
|
||||||
|
<informalexample><programlisting>
|
||||||
|
(gdb) monitor ps
|
||||||
|
1 idle process (state I) and
|
||||||
|
27 sleeping system daemon (state M) processes suppressed,
|
||||||
|
use 'ps A' to see all.
|
||||||
|
Task Addr Pid Parent [*] cpu State Thread Command
|
||||||
|
|
||||||
|
0xc78291d0 1 0 0 0 S 0xc7829404 init
|
||||||
|
0xc7954150 942 1 0 0 S 0xc7954384 dropbear
|
||||||
|
0xc78789c0 944 1 0 0 S 0xc7878bf4 sh
|
||||||
|
(gdb)
|
||||||
|
</programlisting></informalexample>
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="KGDBTestSuite">
|
<chapter id="KGDBTestSuite">
|
||||||
<title>kgdb Test Suite</title>
|
<title>kgdb Test Suite</title>
|
||||||
@@ -309,34 +619,36 @@
|
|||||||
</para>
|
</para>
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="CommonBackEndReq">
|
<chapter id="CommonBackEndReq">
|
||||||
<title>KGDB Internals</title>
|
<title>Kernel Debugger Internals</title>
|
||||||
<sect1 id="kgdbArchitecture">
|
<sect1 id="kgdbArchitecture">
|
||||||
<title>Architecture Specifics</title>
|
<title>Architecture Specifics</title>
|
||||||
<para>
|
<para>
|
||||||
Kgdb is organized into three basic components:
|
The kernel debugger is organized into a number of components:
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
<listitem><para>kgdb core</para>
|
<listitem><para>The debug core</para>
|
||||||
<para>
|
<para>
|
||||||
The kgdb core is found in kernel/kgdb.c. It contains:
|
The debug core is found in kernel/debugger/debug_core.c. It contains:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>All the logic to implement the gdb serial protocol</para></listitem>
|
<listitem><para>A generic OS exception handler which includes
|
||||||
<listitem><para>A generic OS exception handler which includes sync'ing the processors into a stopped state on an multi cpu system.</para></listitem>
|
sync'ing the processors into a stopped state on an multi-CPU
|
||||||
|
system.</para></listitem>
|
||||||
<listitem><para>The API to talk to the kgdb I/O drivers</para></listitem>
|
<listitem><para>The API to talk to the kgdb I/O drivers</para></listitem>
|
||||||
<listitem><para>The API to make calls to the arch specific kgdb implementation</para></listitem>
|
<listitem><para>The API to make calls to the arch-specific kgdb implementation</para></listitem>
|
||||||
<listitem><para>The logic to perform safe memory reads and writes to memory while using the debugger</para></listitem>
|
<listitem><para>The logic to perform safe memory reads and writes to memory while using the debugger</para></listitem>
|
||||||
<listitem><para>A full implementation for software breakpoints unless overridden by the arch</para></listitem>
|
<listitem><para>A full implementation for software breakpoints unless overridden by the arch</para></listitem>
|
||||||
|
<listitem><para>The API to invoke either the kdb or kgdb frontend to the debug core.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para>kgdb arch specific implementation</para>
|
<listitem><para>kgdb arch-specific implementation</para>
|
||||||
<para>
|
<para>
|
||||||
This implementation is generally found in arch/*/kernel/kgdb.c.
|
This implementation is generally found in arch/*/kernel/kgdb.c.
|
||||||
As an example, arch/x86/kernel/kgdb.c contains the specifics to
|
As an example, arch/x86/kernel/kgdb.c contains the specifics to
|
||||||
implement HW breakpoint as well as the initialization to
|
implement HW breakpoint as well as the initialization to
|
||||||
dynamically register and unregister for the trap handlers on
|
dynamically register and unregister for the trap handlers on
|
||||||
this architecture. The arch specific portion implements:
|
this architecture. The arch-specific portion implements:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>contains an arch specific trap catcher which
|
<listitem><para>contains an arch-specific trap catcher which
|
||||||
invokes kgdb_handle_exception() to start kgdb about doing its
|
invokes kgdb_handle_exception() to start kgdb about doing its
|
||||||
work</para></listitem>
|
work</para></listitem>
|
||||||
<listitem><para>translation to and from gdb specific packet format to pt_regs</para></listitem>
|
<listitem><para>translation to and from gdb specific packet format to pt_regs</para></listitem>
|
||||||
@@ -347,11 +659,35 @@
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem><para>gdbstub frontend (aka kgdb)</para>
|
||||||
|
<para>The gdbstub is located in kernel/debug/gdbstub.c. It contains:</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>All the logic to implement the gdb serial protocol</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
|
<listitem><para>kdb frontend</para>
|
||||||
|
<para>The kdb debugger shell is broken down into a number of
|
||||||
|
components. The kdb core is located in kernel/debug/kdb. There
|
||||||
|
are a number of helper functions in some of the other kernel
|
||||||
|
components to make it possible for kdb to examine and report
|
||||||
|
information about the kernel without taking locks that could
|
||||||
|
cause a kernel deadlock. The kdb core contains implements the following functionality.</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>A simple shell</para></listitem>
|
||||||
|
<listitem><para>The kdb core command set</para></listitem>
|
||||||
|
<listitem><para>A registration API to register additional kdb shell commands.</para>
|
||||||
|
<para>A good example of a self-contained kdb module is the "ftdump" command for dumping the ftrace buffer. See: kernel/trace/trace_kdb.c</para></listitem>
|
||||||
|
<listitem><para>The implementation for kdb_printf() which
|
||||||
|
emits messages directly to I/O drivers, bypassing the kernel
|
||||||
|
log.</para></listitem>
|
||||||
|
<listitem><para>SW / HW breakpoint management for the kdb shell</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
<listitem><para>kgdb I/O driver</para>
|
<listitem><para>kgdb I/O driver</para>
|
||||||
<para>
|
<para>
|
||||||
Each kgdb I/O driver has to provide an implemenation for the following:
|
Each kgdb I/O driver has to provide an implementation for the following:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>configuration via builtin or module</para></listitem>
|
<listitem><para>configuration via built-in or module</para></listitem>
|
||||||
<listitem><para>dynamic configuration and kgdb hook registration calls</para></listitem>
|
<listitem><para>dynamic configuration and kgdb hook registration calls</para></listitem>
|
||||||
<listitem><para>read and write character interface</para></listitem>
|
<listitem><para>read and write character interface</para></listitem>
|
||||||
<listitem><para>A cleanup handler for unconfiguring from the kgdb core</para></listitem>
|
<listitem><para>A cleanup handler for unconfiguring from the kgdb core</para></listitem>
|
||||||
@@ -416,15 +752,15 @@
|
|||||||
underlying low level to the hardware driver having "polling hooks"
|
underlying low level to the hardware driver having "polling hooks"
|
||||||
which the to which the tty driver is attached. In the initial
|
which the to which the tty driver is attached. In the initial
|
||||||
implementation of kgdboc it the serial_core was changed to expose a
|
implementation of kgdboc it the serial_core was changed to expose a
|
||||||
low level uart hook for doing polled mode reading and writing of a
|
low level UART hook for doing polled mode reading and writing of a
|
||||||
single character while in an atomic context. When kgdb makes an I/O
|
single character while in an atomic context. When kgdb makes an I/O
|
||||||
request to the debugger, kgdboc invokes a call back in the serial
|
request to the debugger, kgdboc invokes a call back in the serial
|
||||||
core which in turn uses the call back in the uart driver. It is
|
core which in turn uses the call back in the UART driver. It is
|
||||||
certainly possible to extend kgdboc to work with non-uart based
|
certainly possible to extend kgdboc to work with non-UART based
|
||||||
consoles in the future.
|
consoles in the future.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
When using kgdboc with a uart, the uart driver must implement two callbacks in the <constant>struct uart_ops</constant>. Example from drivers/8250.c:<programlisting>
|
When using kgdboc with a UART, the UART driver must implement two callbacks in the <constant>struct uart_ops</constant>. Example from drivers/8250.c:<programlisting>
|
||||||
#ifdef CONFIG_CONSOLE_POLL
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
.poll_get_char = serial8250_get_poll_char,
|
.poll_get_char = serial8250_get_poll_char,
|
||||||
.poll_put_char = serial8250_put_poll_char,
|
.poll_put_char = serial8250_put_poll_char,
|
||||||
@@ -434,7 +770,7 @@
|
|||||||
<constant>#ifdef CONFIG_CONSOLE_POLL</constant>, as shown above.
|
<constant>#ifdef CONFIG_CONSOLE_POLL</constant>, as shown above.
|
||||||
Keep in mind that polling hooks have to be implemented in such a way
|
Keep in mind that polling hooks have to be implemented in such a way
|
||||||
that they can be called from an atomic context and have to restore
|
that they can be called from an atomic context and have to restore
|
||||||
the state of the uart chip on return such that the system can return
|
the state of the UART chip on return such that the system can return
|
||||||
to normal when the debugger detaches. You need to be very careful
|
to normal when the debugger detaches. You need to be very careful
|
||||||
with any kind of lock you consider, because failing here is most
|
with any kind of lock you consider, because failing here is most
|
||||||
going to mean pressing the reset button.
|
going to mean pressing the reset button.
|
||||||
@@ -453,6 +789,10 @@
|
|||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Jason Wessel<email>jason.wessel@windriver.com</email></para></listitem>
|
<listitem><para>Jason Wessel<email>jason.wessel@windriver.com</email></para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
In Jan 2010 this document was updated to include kdb.
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>Jason Wessel<email>jason.wessel@windriver.com</email></para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</chapter>
|
</chapter>
|
||||||
</book>
|
</book>
|
||||||
|
|||||||
@@ -81,16 +81,14 @@ void (*port_disable) (struct ata_port *);
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Called from ata_bus_probe() and ata_bus_reset() error paths,
|
Called from ata_bus_probe() error path, as well as when
|
||||||
as well as when unregistering from the SCSI module (rmmod, hot
|
unregistering from the SCSI module (rmmod, hot unplug).
|
||||||
unplug).
|
|
||||||
This function should do whatever needs to be done to take the
|
This function should do whatever needs to be done to take the
|
||||||
port out of use. In most cases, ata_port_disable() can be used
|
port out of use. In most cases, ata_port_disable() can be used
|
||||||
as this hook.
|
as this hook.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Called from ata_bus_probe() on a failed probe.
|
Called from ata_bus_probe() on a failed probe.
|
||||||
Called from ata_bus_reset() on a failed bus reset.
|
|
||||||
Called from ata_scsi_release().
|
Called from ata_scsi_release().
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@@ -107,10 +105,6 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
|
|||||||
issue of SET FEATURES - XFER MODE, and prior to operation.
|
issue of SET FEATURES - XFER MODE, and prior to operation.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Called by ata_device_add() after ata_dev_identify() determines
|
|
||||||
a device is present.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
This entry may be specified as NULL in ata_port_operations.
|
This entry may be specified as NULL in ata_port_operations.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@@ -154,8 +148,8 @@ unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned in
|
|||||||
|
|
||||||
<sect2><title>Taskfile read/write</title>
|
<sect2><title>Taskfile read/write</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
|
void (*sff_tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
|
||||||
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
|
void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -164,36 +158,35 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
|
|||||||
hardware registers / DMA buffers, to obtain the current set of
|
hardware registers / DMA buffers, to obtain the current set of
|
||||||
taskfile register values.
|
taskfile register values.
|
||||||
Most drivers for taskfile-based hardware (PIO or MMIO) use
|
Most drivers for taskfile-based hardware (PIO or MMIO) use
|
||||||
ata_tf_load() and ata_tf_read() for these hooks.
|
ata_sff_tf_load() and ata_sff_tf_read() for these hooks.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2><title>PIO data read/write</title>
|
<sect2><title>PIO data read/write</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
|
void (*sff_data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
All bmdma-style drivers must implement this hook. This is the low-level
|
All bmdma-style drivers must implement this hook. This is the low-level
|
||||||
operation that actually copies the data bytes during a PIO data
|
operation that actually copies the data bytes during a PIO data
|
||||||
transfer.
|
transfer.
|
||||||
Typically the driver
|
Typically the driver will choose one of ata_sff_data_xfer_noirq(),
|
||||||
will choose one of ata_pio_data_xfer_noirq(), ata_pio_data_xfer(), or
|
ata_sff_data_xfer(), or ata_sff_data_xfer32().
|
||||||
ata_mmio_data_xfer().
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2><title>ATA command execute</title>
|
<sect2><title>ATA command execute</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
|
void (*sff_exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
causes an ATA command, previously loaded with
|
causes an ATA command, previously loaded with
|
||||||
->tf_load(), to be initiated in hardware.
|
->tf_load(), to be initiated in hardware.
|
||||||
Most drivers for taskfile-based hardware use ata_exec_command()
|
Most drivers for taskfile-based hardware use ata_sff_exec_command()
|
||||||
for this hook.
|
for this hook.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@@ -218,8 +211,8 @@ command.
|
|||||||
|
|
||||||
<sect2><title>Read specific ATA shadow registers</title>
|
<sect2><title>Read specific ATA shadow registers</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
u8 (*check_status)(struct ata_port *ap);
|
u8 (*sff_check_status)(struct ata_port *ap);
|
||||||
u8 (*check_altstatus)(struct ata_port *ap);
|
u8 (*sff_check_altstatus)(struct ata_port *ap);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -227,20 +220,26 @@ u8 (*check_altstatus)(struct ata_port *ap);
|
|||||||
hardware. On some hardware, reading the Status register has
|
hardware. On some hardware, reading the Status register has
|
||||||
the side effect of clearing the interrupt condition.
|
the side effect of clearing the interrupt condition.
|
||||||
Most drivers for taskfile-based hardware use
|
Most drivers for taskfile-based hardware use
|
||||||
ata_check_status() for this hook.
|
ata_sff_check_status() for this hook.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2><title>Write specific ATA shadow register</title>
|
||||||
|
<programlisting>
|
||||||
|
void (*sff_set_devctl)(struct ata_port *ap, u8 ctl);
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Note that because this is called from ata_device_add(), at
|
Write the device control ATA shadow register to the hardware.
|
||||||
least a dummy function that clears device interrupts must be
|
Most drivers don't need to define this.
|
||||||
provided for all drivers, even if the controller doesn't
|
|
||||||
actually have a taskfile status register.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2><title>Select ATA device on bus</title>
|
<sect2><title>Select ATA device on bus</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
void (*dev_select)(struct ata_port *ap, unsigned int device);
|
void (*sff_dev_select)(struct ata_port *ap, unsigned int device);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -251,9 +250,7 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Most drivers for taskfile-based hardware use
|
Most drivers for taskfile-based hardware use
|
||||||
ata_std_dev_select() for this hook. Controllers which do not
|
ata_sff_dev_select() for this hook.
|
||||||
support second drives on a port (such as SATA contollers) will
|
|
||||||
use ata_noop_dev_select().
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
@@ -441,13 +438,13 @@ void (*irq_clear) (struct ata_port *);
|
|||||||
to struct ata_host_set.
|
to struct ata_host_set.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Most legacy IDE drivers use ata_interrupt() for the
|
Most legacy IDE drivers use ata_sff_interrupt() for the
|
||||||
irq_handler hook, which scans all ports in the host_set,
|
irq_handler hook, which scans all ports in the host_set,
|
||||||
determines which queued command was active (if any), and calls
|
determines which queued command was active (if any), and calls
|
||||||
ata_host_intr(ap,qc).
|
ata_sff_host_intr(ap,qc).
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Most legacy IDE drivers use ata_bmdma_irq_clear() for the
|
Most legacy IDE drivers use ata_sff_irq_clear() for the
|
||||||
irq_clear() hook, which simply clears the interrupt and error
|
irq_clear() hook, which simply clears the interrupt and error
|
||||||
flags in the DMA status register.
|
flags in the DMA status register.
|
||||||
</para>
|
</para>
|
||||||
@@ -490,16 +487,12 @@ void (*host_stop) (struct ata_host_set *host_set);
|
|||||||
allocates space for a legacy IDE PRD table and returns.
|
allocates space for a legacy IDE PRD table and returns.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
->port_stop() is called after ->host_stop(). It's sole function
|
->port_stop() is called after ->host_stop(). Its sole function
|
||||||
is to release DMA/memory resources, now that they are no longer
|
is to release DMA/memory resources, now that they are no longer
|
||||||
actively being used. Many drivers also free driver-private
|
actively being used. Many drivers also free driver-private
|
||||||
data from port at this time.
|
data from port at this time.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Many drivers use ata_port_stop() as this hook, which frees the
|
|
||||||
PRD table.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
->host_stop() is called after all ->port_stop() calls
|
->host_stop() is called after all ->port_stop() calls
|
||||||
have completed. The hook must finalize hardware shutdown, release DMA
|
have completed. The hook must finalize hardware shutdown, release DMA
|
||||||
and other resources, etc.
|
and other resources, etc.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
<!ENTITY VIDIOC-DBG-G-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_G_REGISTER</constant></link>">
|
<!ENTITY VIDIOC-DBG-G-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_G_REGISTER</constant></link>">
|
||||||
<!ENTITY VIDIOC-DBG-S-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_S_REGISTER</constant></link>">
|
<!ENTITY VIDIOC-DBG-S-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_S_REGISTER</constant></link>">
|
||||||
<!ENTITY VIDIOC-DQBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_DQBUF</constant></link>">
|
<!ENTITY VIDIOC-DQBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_DQBUF</constant></link>">
|
||||||
|
<!ENTITY VIDIOC-DQEVENT "<link linkend='vidioc-dqevent'><constant>VIDIOC_DQEVENT</constant></link>">
|
||||||
<!ENTITY VIDIOC-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_ENCODER_CMD</constant></link>">
|
<!ENTITY VIDIOC-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_ENCODER_CMD</constant></link>">
|
||||||
<!ENTITY VIDIOC-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>">
|
<!ENTITY VIDIOC-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>">
|
||||||
<!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>">
|
<!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>">
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
<!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>">
|
<!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>">
|
||||||
<!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>">
|
<!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>">
|
||||||
<!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>">
|
<!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>">
|
||||||
|
<!ENTITY VIDIOC-SUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_SUBSCRIBE_EVENT</constant></link>">
|
||||||
<!ENTITY VIDIOC-S-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_S_AUDIO</constant></link>">
|
<!ENTITY VIDIOC-S-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_S_AUDIO</constant></link>">
|
||||||
<!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>">
|
<!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>">
|
||||||
<!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
|
<!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
|
||||||
@@ -83,6 +85,7 @@
|
|||||||
<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
|
<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
|
||||||
<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
|
<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
|
||||||
<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
|
<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
|
||||||
|
<!ENTITY VIDIOC-UNSUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_UNSUBSCRIBE_EVENT</constant></link>">
|
||||||
|
|
||||||
<!-- Types -->
|
<!-- Types -->
|
||||||
<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
|
<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
|
||||||
@@ -141,6 +144,9 @@
|
|||||||
<!ENTITY v4l2-enc-idx "struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
|
<!ENTITY v4l2-enc-idx "struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
|
||||||
<!ENTITY v4l2-enc-idx-entry "struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
|
<!ENTITY v4l2-enc-idx-entry "struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
|
||||||
<!ENTITY v4l2-encoder-cmd "struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
|
<!ENTITY v4l2-encoder-cmd "struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
|
||||||
|
<!ENTITY v4l2-event "struct <link linkend='v4l2-event'>v4l2_event</link>">
|
||||||
|
<!ENTITY v4l2-event-subscription "struct <link linkend='v4l2-event-subscription'>v4l2_event_subscription</link>">
|
||||||
|
<!ENTITY v4l2-event-vsync "struct <link linkend='v4l2-event-vsync'>v4l2_event_vsync</link>">
|
||||||
<!ENTITY v4l2-ext-control "struct <link linkend='v4l2-ext-control'>v4l2_ext_control</link>">
|
<!ENTITY v4l2-ext-control "struct <link linkend='v4l2-ext-control'>v4l2_ext_control</link>">
|
||||||
<!ENTITY v4l2-ext-controls "struct <link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>">
|
<!ENTITY v4l2-ext-controls "struct <link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>">
|
||||||
<!ENTITY v4l2-fmtdesc "struct <link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>">
|
<!ENTITY v4l2-fmtdesc "struct <link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>">
|
||||||
@@ -200,6 +206,7 @@
|
|||||||
<!ENTITY sub-controls SYSTEM "v4l/controls.xml">
|
<!ENTITY sub-controls SYSTEM "v4l/controls.xml">
|
||||||
<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml">
|
<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml">
|
||||||
<!ENTITY sub-dev-codec SYSTEM "v4l/dev-codec.xml">
|
<!ENTITY sub-dev-codec SYSTEM "v4l/dev-codec.xml">
|
||||||
|
<!ENTITY sub-dev-event SYSTEM "v4l/dev-event.xml">
|
||||||
<!ENTITY sub-dev-effect SYSTEM "v4l/dev-effect.xml">
|
<!ENTITY sub-dev-effect SYSTEM "v4l/dev-effect.xml">
|
||||||
<!ENTITY sub-dev-osd SYSTEM "v4l/dev-osd.xml">
|
<!ENTITY sub-dev-osd SYSTEM "v4l/dev-osd.xml">
|
||||||
<!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml">
|
<!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml">
|
||||||
@@ -292,6 +299,8 @@
|
|||||||
<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
|
<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
|
||||||
<!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.xml">
|
<!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.xml">
|
||||||
<!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml">
|
<!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml">
|
||||||
|
<!ENTITY sub-dqevent SYSTEM "v4l/vidioc-dqevent.xml">
|
||||||
|
<!ENTITY sub-subscribe-event SYSTEM "v4l/vidioc-subscribe-event.xml">
|
||||||
<!ENTITY sub-intro SYSTEM "dvb/intro.xml">
|
<!ENTITY sub-intro SYSTEM "dvb/intro.xml">
|
||||||
<!ENTITY sub-frontend SYSTEM "dvb/frontend.xml">
|
<!ENTITY sub-frontend SYSTEM "dvb/frontend.xml">
|
||||||
<!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">
|
<!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">
|
||||||
@@ -381,3 +390,5 @@
|
|||||||
<!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
|
<!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
|
||||||
<!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
|
<!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
|
||||||
<!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml">
|
<!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml">
|
||||||
|
<!ENTITY dqevent SYSTEM "v4l/vidioc-dqevent.xml">
|
||||||
|
<!ENTITY subscribe_event SYSTEM "v4l/vidioc-subscribe-event.xml">
|
||||||
|
|||||||
@@ -19,13 +19,17 @@
|
|||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2008</year>
|
<year>2008-2010</year>
|
||||||
<holder>Paul Mundt</holder>
|
<holder>Paul Mundt</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2008</year>
|
<year>2008-2010</year>
|
||||||
<holder>Renesas Technology Corp.</holder>
|
<holder>Renesas Technology Corp.</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
<copyright>
|
||||||
|
<year>2010</year>
|
||||||
|
<holder>Renesas Electronics Corp.</holder>
|
||||||
|
</copyright>
|
||||||
|
|
||||||
<legalnotice>
|
<legalnotice>
|
||||||
<para>
|
<para>
|
||||||
@@ -77,7 +81,7 @@
|
|||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="clk">
|
<chapter id="clk">
|
||||||
<title>Clock Framework Extensions</title>
|
<title>Clock Framework Extensions</title>
|
||||||
!Iarch/sh/include/asm/clock.h
|
!Iinclude/linux/sh_clk.h
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="mach">
|
<chapter id="mach">
|
||||||
<title>Machine Specific Interfaces</title>
|
<title>Machine Specific Interfaces</title>
|
||||||
|
|||||||
@@ -2332,6 +2332,17 @@ more information.</para>
|
|||||||
</listitem>
|
</listitem>
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
|
<title>V4L2 in Linux 2.6.34</title>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Added
|
||||||
|
<constant>V4L2_CID_IRIS_ABSOLUTE</constant> and
|
||||||
|
<constant>V4L2_CID_IRIS_RELATIVE</constant> controls to the
|
||||||
|
<link linkend="camera-controls">Camera controls class</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="other">
|
<section id="other">
|
||||||
@@ -2455,6 +2466,7 @@ interfaces and should not be implemented in new drivers.</para>
|
|||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Local Variables:
|
Local Variables:
|
||||||
|
|||||||
@@ -266,6 +266,12 @@ minimum value disables backlight compensation.</entry>
|
|||||||
<entry>boolean</entry>
|
<entry>boolean</entry>
|
||||||
<entry>Chroma automatic gain control.</entry>
|
<entry>Chroma automatic gain control.</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><constant>V4L2_CID_CHROMA_GAIN</constant></entry>
|
||||||
|
<entry>integer</entry>
|
||||||
|
<entry>Adjusts the Chroma gain control (for use when chroma AGC
|
||||||
|
is disabled).</entry>
|
||||||
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><constant>V4L2_CID_COLOR_KILLER</constant></entry>
|
<entry><constant>V4L2_CID_COLOR_KILLER</constant></entry>
|
||||||
<entry>boolean</entry>
|
<entry>boolean</entry>
|
||||||
@@ -277,8 +283,15 @@ minimum value disables backlight compensation.</entry>
|
|||||||
<entry>Selects a color effect. Possible values for
|
<entry>Selects a color effect. Possible values for
|
||||||
<constant>enum v4l2_colorfx</constant> are:
|
<constant>enum v4l2_colorfx</constant> are:
|
||||||
<constant>V4L2_COLORFX_NONE</constant> (0),
|
<constant>V4L2_COLORFX_NONE</constant> (0),
|
||||||
<constant>V4L2_COLORFX_BW</constant> (1) and
|
<constant>V4L2_COLORFX_BW</constant> (1),
|
||||||
<constant>V4L2_COLORFX_SEPIA</constant> (2).</entry>
|
<constant>V4L2_COLORFX_SEPIA</constant> (2),
|
||||||
|
<constant>V4L2_COLORFX_NEGATIVE</constant> (3),
|
||||||
|
<constant>V4L2_COLORFX_EMBOSS</constant> (4),
|
||||||
|
<constant>V4L2_COLORFX_SKETCH</constant> (5),
|
||||||
|
<constant>V4L2_COLORFX_SKY_BLUE</constant> (6),
|
||||||
|
<constant>V4L2_COLORFX_GRASS_GREEN</constant> (7),
|
||||||
|
<constant>V4L2_COLORFX_SKIN_WHITEN</constant> (8) and
|
||||||
|
<constant>V4L2_COLORFX_VIVID</constant> (9).</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><constant>V4L2_CID_ROTATE</constant></entry>
|
<entry><constant>V4L2_CID_ROTATE</constant></entry>
|
||||||
@@ -1824,6 +1837,25 @@ wide-angle direction. The zoom speed unit is driver-specific.</entry>
|
|||||||
</row>
|
</row>
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry spanname="id"><constant>V4L2_CID_IRIS_ABSOLUTE</constant> </entry>
|
||||||
|
<entry>integer</entry>
|
||||||
|
</row><row><entry spanname="descr">This control sets the
|
||||||
|
camera's aperture to the specified value. The unit is undefined.
|
||||||
|
Larger values open the iris wider, smaller values close it.</entry>
|
||||||
|
</row>
|
||||||
|
<row><entry></entry></row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry spanname="id"><constant>V4L2_CID_IRIS_RELATIVE</constant> </entry>
|
||||||
|
<entry>integer</entry>
|
||||||
|
</row><row><entry spanname="descr">This control modifies the
|
||||||
|
camera's aperture by the specified amount. The unit is undefined.
|
||||||
|
Positive values open the iris one step further, negative values close
|
||||||
|
it one step further. This is a write-only control.</entry>
|
||||||
|
</row>
|
||||||
|
<row><entry></entry></row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry spanname="id"><constant>V4L2_CID_PRIVACY</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_PRIVACY</constant> </entry>
|
||||||
<entry>boolean</entry>
|
<entry>boolean</entry>
|
||||||
|
|||||||
31
Documentation/DocBook/v4l/dev-event.xml
Normal file
31
Documentation/DocBook/v4l/dev-event.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<title>Event Interface</title>
|
||||||
|
|
||||||
|
<para>The V4L2 event interface provides means for user to get
|
||||||
|
immediately notified on certain conditions taking place on a device.
|
||||||
|
This might include start of frame or loss of signal events, for
|
||||||
|
example.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>To receive events, the events the user is interested in first must
|
||||||
|
be subscribed using the &VIDIOC-SUBSCRIBE-EVENT; ioctl. Once an event is
|
||||||
|
subscribed, the events of subscribed types are dequeueable using the
|
||||||
|
&VIDIOC-DQEVENT; ioctl. Events may be unsubscribed using
|
||||||
|
VIDIOC_UNSUBSCRIBE_EVENT ioctl. The special event type V4L2_EVENT_ALL may
|
||||||
|
be used to unsubscribe all the events the driver supports.</para>
|
||||||
|
|
||||||
|
<para>The event subscriptions and event queues are specific to file
|
||||||
|
handles. Subscribing an event on one file handle does not affect
|
||||||
|
other file handles.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The information on dequeueable events is obtained by using select or
|
||||||
|
poll system calls on video devices. The V4L2 events use POLLPRI events on
|
||||||
|
poll system call and exceptions on select system call. </para>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Local Variables:
|
||||||
|
mode: sgml
|
||||||
|
sgml-parent-document: "v4l2.sgml"
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
||||||
|
-->
|
||||||
@@ -701,6 +701,16 @@ buffer cannot be on both queues at the same time, the
|
|||||||
They can be both cleared however, then the buffer is in "dequeued"
|
They can be both cleared however, then the buffer is in "dequeued"
|
||||||
state, in the application domain to say so.</entry>
|
state, in the application domain to say so.</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><constant>V4L2_BUF_FLAG_ERROR</constant></entry>
|
||||||
|
<entry>0x0040</entry>
|
||||||
|
<entry>When this flag is set, the buffer has been dequeued
|
||||||
|
successfully, although the data might have been corrupted.
|
||||||
|
This is recoverable, streaming may continue as normal and
|
||||||
|
the buffer may be reused normally.
|
||||||
|
Drivers set this flag when the <constant>VIDIOC_DQBUF</constant>
|
||||||
|
ioctl is called.</entry>
|
||||||
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry>
|
<entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry>
|
||||||
<entry>0x0008</entry>
|
<entry>0x0008</entry>
|
||||||
@@ -918,8 +928,8 @@ order</emphasis>.</para>
|
|||||||
|
|
||||||
<para>When the driver provides or accepts images field by field
|
<para>When the driver provides or accepts images field by field
|
||||||
rather than interleaved, it is also important applications understand
|
rather than interleaved, it is also important applications understand
|
||||||
how the fields combine to frames. We distinguish between top and
|
how the fields combine to frames. We distinguish between top (aka odd) and
|
||||||
bottom fields, the <emphasis>spatial order</emphasis>: The first line
|
bottom (aka even) fields, the <emphasis>spatial order</emphasis>: The first line
|
||||||
of the top field is the first line of an interlaced frame, the first
|
of the top field is the first line of an interlaced frame, the first
|
||||||
line of the bottom field is the second line of that frame.</para>
|
line of the bottom field is the second line of that frame.</para>
|
||||||
|
|
||||||
@@ -972,12 +982,12 @@ between <constant>V4L2_FIELD_TOP</constant> and
|
|||||||
<row>
|
<row>
|
||||||
<entry><constant>V4L2_FIELD_TOP</constant></entry>
|
<entry><constant>V4L2_FIELD_TOP</constant></entry>
|
||||||
<entry>2</entry>
|
<entry>2</entry>
|
||||||
<entry>Images consist of the top field only.</entry>
|
<entry>Images consist of the top (aka odd) field only.</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
|
<entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
|
||||||
<entry>3</entry>
|
<entry>3</entry>
|
||||||
<entry>Images consist of the bottom field only.
|
<entry>Images consist of the bottom (aka even) field only.
|
||||||
Applications may wish to prevent a device from capturing interlaced
|
Applications may wish to prevent a device from capturing interlaced
|
||||||
images because they will have "comb" or "feathering" artefacts around
|
images because they will have "comb" or "feathering" artefacts around
|
||||||
moving objects.</entry>
|
moving objects.</entry>
|
||||||
|
|||||||
@@ -792,6 +792,18 @@ http://www.thedirks.org/winnov/</ulink></para></entry>
|
|||||||
<entry>'YYUV'</entry>
|
<entry>'YYUV'</entry>
|
||||||
<entry>unknown</entry>
|
<entry>unknown</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row id="V4L2-PIX-FMT-Y4">
|
||||||
|
<entry><constant>V4L2_PIX_FMT_Y4</constant></entry>
|
||||||
|
<entry>'Y04 '</entry>
|
||||||
|
<entry>Old 4-bit greyscale format. Only the least significant 4 bits of each byte are used,
|
||||||
|
the other bits are set to 0.</entry>
|
||||||
|
</row>
|
||||||
|
<row id="V4L2-PIX-FMT-Y6">
|
||||||
|
<entry><constant>V4L2_PIX_FMT_Y6</constant></entry>
|
||||||
|
<entry>'Y06 '</entry>
|
||||||
|
<entry>Old 6-bit greyscale format. Only the least significant 6 bits of each byte are used,
|
||||||
|
the other bits are set to 0.</entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -401,6 +401,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||||||
<section id="ttx"> &sub-dev-teletext; </section>
|
<section id="ttx"> &sub-dev-teletext; </section>
|
||||||
<section id="radio"> &sub-dev-radio; </section>
|
<section id="radio"> &sub-dev-radio; </section>
|
||||||
<section id="rds"> &sub-dev-rds; </section>
|
<section id="rds"> &sub-dev-rds; </section>
|
||||||
|
<section id="event"> &sub-dev-event; </section>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="driver">
|
<chapter id="driver">
|
||||||
@@ -426,6 +427,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||||||
&sub-cropcap;
|
&sub-cropcap;
|
||||||
&sub-dbg-g-chip-ident;
|
&sub-dbg-g-chip-ident;
|
||||||
&sub-dbg-g-register;
|
&sub-dbg-g-register;
|
||||||
|
&sub-dqevent;
|
||||||
&sub-encoder-cmd;
|
&sub-encoder-cmd;
|
||||||
&sub-enumaudio;
|
&sub-enumaudio;
|
||||||
&sub-enumaudioout;
|
&sub-enumaudioout;
|
||||||
@@ -467,6 +469,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||||||
&sub-reqbufs;
|
&sub-reqbufs;
|
||||||
&sub-s-hw-freq-seek;
|
&sub-s-hw-freq-seek;
|
||||||
&sub-streamon;
|
&sub-streamon;
|
||||||
|
&sub-subscribe-event;
|
||||||
<!-- End of ioctls. -->
|
<!-- End of ioctls. -->
|
||||||
&sub-mmap;
|
&sub-mmap;
|
||||||
&sub-munmap;
|
&sub-munmap;
|
||||||
|
|||||||
@@ -1018,6 +1018,13 @@ enum <link linkend="v4l2-colorfx">v4l2_colorfx</link> {
|
|||||||
V4L2_COLORFX_NONE = 0,
|
V4L2_COLORFX_NONE = 0,
|
||||||
V4L2_COLORFX_BW = 1,
|
V4L2_COLORFX_BW = 1,
|
||||||
V4L2_COLORFX_SEPIA = 2,
|
V4L2_COLORFX_SEPIA = 2,
|
||||||
|
V4L2_COLORFX_NEGATIVE = 3,
|
||||||
|
V4L2_COLORFX_EMBOSS = 4,
|
||||||
|
V4L2_COLORFX_SKETCH = 5,
|
||||||
|
V4L2_COLORFX_SKY_BLUE = 6,
|
||||||
|
V4L2_COLORFX_GRASS_GREEN = 7,
|
||||||
|
V4L2_COLORFX_SKIN_WHITEN = 8,
|
||||||
|
V4L2_COLORFX_VIVID = 9.
|
||||||
};
|
};
|
||||||
#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
|
#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
|
||||||
#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
|
#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
|
||||||
@@ -1271,6 +1278,9 @@ enum <link linkend="v4l2-exposure-auto-type">v4l2_exposure_auto_type</link> {
|
|||||||
|
|
||||||
#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
|
#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
|
||||||
|
|
||||||
|
#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17)
|
||||||
|
#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18)
|
||||||
|
|
||||||
/* FM Modulator class control IDs */
|
/* FM Modulator class control IDs */
|
||||||
#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
|
#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
|
||||||
#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
|
#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
|
||||||
|
|||||||
131
Documentation/DocBook/v4l/vidioc-dqevent.xml
Normal file
131
Documentation/DocBook/v4l/vidioc-dqevent.xml
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
<refentry id="vidioc-dqevent">
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>ioctl VIDIOC_DQEVENT</refentrytitle>
|
||||||
|
&manvol;
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>VIDIOC_DQEVENT</refname>
|
||||||
|
<refpurpose>Dequeue event</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>ioctl</function></funcdef>
|
||||||
|
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>request</parameter></paramdef>
|
||||||
|
<paramdef>struct v4l2_event
|
||||||
|
*<parameter>argp</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Arguments</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>fd</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para>&fd;</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>request</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para>VIDIOC_DQEVENT</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>argp</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para></para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>Dequeue an event from a video device. No input is required
|
||||||
|
for this ioctl. All the fields of the &v4l2-event; structure are
|
||||||
|
filled by the driver. The file handle will also receive exceptions
|
||||||
|
which the application may get by e.g. using the select system
|
||||||
|
call.</para>
|
||||||
|
|
||||||
|
<table frame="none" pgwide="1" id="v4l2-event">
|
||||||
|
<title>struct <structname>v4l2_event</structname></title>
|
||||||
|
<tgroup cols="4">
|
||||||
|
&cs-str;
|
||||||
|
<tbody valign="top">
|
||||||
|
<row>
|
||||||
|
<entry>__u32</entry>
|
||||||
|
<entry><structfield>type</structfield></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>Type of the event.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>union</entry>
|
||||||
|
<entry><structfield>u</structfield></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>&v4l2-event-vsync;</entry>
|
||||||
|
<entry><structfield>vsync</structfield></entry>
|
||||||
|
<entry>Event data for event V4L2_EVENT_VSYNC.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>__u8</entry>
|
||||||
|
<entry><structfield>data</structfield>[64]</entry>
|
||||||
|
<entry>Event data. Defined by the event type. The union
|
||||||
|
should be used to define easily accessible type for
|
||||||
|
events.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>__u32</entry>
|
||||||
|
<entry><structfield>pending</structfield></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>Number of pending events excluding this one.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>__u32</entry>
|
||||||
|
<entry><structfield>sequence</structfield></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>Event sequence number. The sequence number is
|
||||||
|
incremented for every subscribed event that takes place.
|
||||||
|
If sequence numbers are not contiguous it means that
|
||||||
|
events have been lost.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>struct timespec</entry>
|
||||||
|
<entry><structfield>timestamp</structfield></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>Event timestamp.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>__u32</entry>
|
||||||
|
<entry><structfield>reserved</structfield>[9]</entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>Reserved for future extensions. Drivers must set
|
||||||
|
the array to zero.</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</refsect1>
|
||||||
|
</refentry>
|
||||||
|
<!--
|
||||||
|
Local Variables:
|
||||||
|
mode: sgml
|
||||||
|
sgml-parent-document: "v4l2.sgml"
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
||||||
|
-->
|
||||||
@@ -283,7 +283,7 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
|
|||||||
<entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
|
<entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
|
<entry><constant>V4L2_IN_CAP_CUSTOM_TIMINGS</constant></entry>
|
||||||
<entry>0x00000002</entry>
|
<entry>0x00000002</entry>
|
||||||
<entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
|
<entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|||||||
@@ -111,7 +111,11 @@ from the driver's outgoing queue. They just set the
|
|||||||
and <structfield>reserved</structfield>
|
and <structfield>reserved</structfield>
|
||||||
fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant>
|
fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant>
|
||||||
is called with a pointer to this structure the driver fills the
|
is called with a pointer to this structure the driver fills the
|
||||||
remaining fields or returns an error code.</para>
|
remaining fields or returns an error code. The driver may also set
|
||||||
|
<constant>V4L2_BUF_FLAG_ERROR</constant> in the <structfield>flags</structfield>
|
||||||
|
field. It indicates a non-critical (recoverable) streaming error. In such case
|
||||||
|
the application may continue as normal, but should be aware that data in the
|
||||||
|
dequeued buffer might be corrupted.</para>
|
||||||
|
|
||||||
<para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
|
<para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
|
||||||
buffer is in the outgoing queue. When the
|
buffer is in the outgoing queue. When the
|
||||||
@@ -158,7 +162,13 @@ enqueue a user pointer buffer.</para>
|
|||||||
<para><constant>VIDIOC_DQBUF</constant> failed due to an
|
<para><constant>VIDIOC_DQBUF</constant> failed due to an
|
||||||
internal error. Can also indicate temporary problems like signal
|
internal error. Can also indicate temporary problems like signal
|
||||||
loss. Note the driver might dequeue an (empty) buffer despite
|
loss. Note the driver might dequeue an (empty) buffer despite
|
||||||
returning an error, or even stop capturing.</para>
|
returning an error, or even stop capturing. Reusing such buffer may be unsafe
|
||||||
|
though and its details (e.g. <structfield>index</structfield>) may not be
|
||||||
|
returned either. It is recommended that drivers indicate recoverable errors
|
||||||
|
by setting the <constant>V4L2_BUF_FLAG_ERROR</constant> and returning 0 instead.
|
||||||
|
In that case the application should be able to safely reuse the buffer and
|
||||||
|
continue streaming.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ should be part of the control documentation.</entry>
|
|||||||
<entry>n/a</entry>
|
<entry>n/a</entry>
|
||||||
<entry>This is not a control. When
|
<entry>This is not a control. When
|
||||||
<constant>VIDIOC_QUERYCTRL</constant> is called with a control ID
|
<constant>VIDIOC_QUERYCTRL</constant> is called with a control ID
|
||||||
equal to a control class code (see <xref linkend="ctrl-class" />), the
|
equal to a control class code (see <xref linkend="ctrl-class" />) + 1, the
|
||||||
ioctl returns the name of the control class and this control type.
|
ioctl returns the name of the control class and this control type.
|
||||||
Older drivers which do not support this feature return an
|
Older drivers which do not support this feature return an
|
||||||
&EINVAL;.</entry>
|
&EINVAL;.</entry>
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ fields of the <structname>v4l2_requestbuffers</structname> structure.
|
|||||||
They set the <structfield>type</structfield> field to the respective
|
They set the <structfield>type</structfield> field to the respective
|
||||||
stream or buffer type, the <structfield>count</structfield> field to
|
stream or buffer type, the <structfield>count</structfield> field to
|
||||||
the desired number of buffers, <structfield>memory</structfield>
|
the desired number of buffers, <structfield>memory</structfield>
|
||||||
must be set to the requested I/O method and the reserved array
|
must be set to the requested I/O method and the <structfield>reserved</structfield> array
|
||||||
must be zeroed. When the ioctl
|
must be zeroed. When the ioctl
|
||||||
is called with a pointer to this structure the driver will attempt to allocate
|
is called with a pointer to this structure the driver will attempt to allocate
|
||||||
the requested number of buffers and it stores the actual number
|
the requested number of buffers and it stores the actual number
|
||||||
|
|||||||
133
Documentation/DocBook/v4l/vidioc-subscribe-event.xml
Normal file
133
Documentation/DocBook/v4l/vidioc-subscribe-event.xml
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
<refentry id="vidioc-subscribe-event">
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>ioctl VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</refentrytitle>
|
||||||
|
&manvol;
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</refname>
|
||||||
|
<refpurpose>Subscribe or unsubscribe event</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>ioctl</function></funcdef>
|
||||||
|
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>request</parameter></paramdef>
|
||||||
|
<paramdef>struct v4l2_event_subscription
|
||||||
|
*<parameter>argp</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Arguments</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>fd</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para>&fd;</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>request</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para>VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>argp</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para></para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>Subscribe or unsubscribe V4L2 event. Subscribed events are
|
||||||
|
dequeued by using the &VIDIOC-DQEVENT; ioctl.</para>
|
||||||
|
|
||||||
|
<table frame="none" pgwide="1" id="v4l2-event-subscription">
|
||||||
|
<title>struct <structname>v4l2_event_subscription</structname></title>
|
||||||
|
<tgroup cols="3">
|
||||||
|
&cs-str;
|
||||||
|
<tbody valign="top">
|
||||||
|
<row>
|
||||||
|
<entry>__u32</entry>
|
||||||
|
<entry><structfield>type</structfield></entry>
|
||||||
|
<entry>Type of the event.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>__u32</entry>
|
||||||
|
<entry><structfield>reserved</structfield>[7]</entry>
|
||||||
|
<entry>Reserved for future extensions. Drivers and applications
|
||||||
|
must set the array to zero.</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table frame="none" pgwide="1" id="event-type">
|
||||||
|
<title>Event Types</title>
|
||||||
|
<tgroup cols="3">
|
||||||
|
&cs-def;
|
||||||
|
<tbody valign="top">
|
||||||
|
<row>
|
||||||
|
<entry><constant>V4L2_EVENT_ALL</constant></entry>
|
||||||
|
<entry>0</entry>
|
||||||
|
<entry>All events. V4L2_EVENT_ALL is valid only for
|
||||||
|
VIDIOC_UNSUBSCRIBE_EVENT for unsubscribing all events at once.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><constant>V4L2_EVENT_VSYNC</constant></entry>
|
||||||
|
<entry>1</entry>
|
||||||
|
<entry>This event is triggered on the vertical sync.
|
||||||
|
This event has &v4l2-event-vsync; associated with it.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><constant>V4L2_EVENT_EOS</constant></entry>
|
||||||
|
<entry>2</entry>
|
||||||
|
<entry>This event is triggered when the end of a stream is reached.
|
||||||
|
This is typically used with MPEG decoders to report to the application
|
||||||
|
when the last of the MPEG stream has been decoded.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
|
||||||
|
<entry>0x08000000</entry>
|
||||||
|
<entry>Base event number for driver-private events.</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table frame="none" pgwide="1" id="v4l2-event-vsync">
|
||||||
|
<title>struct <structname>v4l2_event_vsync</structname></title>
|
||||||
|
<tgroup cols="3">
|
||||||
|
&cs-str;
|
||||||
|
<tbody valign="top">
|
||||||
|
<row>
|
||||||
|
<entry>__u8</entry>
|
||||||
|
<entry><structfield>field</structfield></entry>
|
||||||
|
<entry>The upcoming field. See &v4l2-field;.</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</refsect1>
|
||||||
|
</refentry>
|
||||||
|
<!--
|
||||||
|
Local Variables:
|
||||||
|
mode: sgml
|
||||||
|
sgml-parent-document: "v4l2.sgml"
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
||||||
|
-->
|
||||||
@@ -5518,34 +5518,41 @@ struct _snd_pcm_runtime {
|
|||||||
]]>
|
]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</informalexample>
|
</informalexample>
|
||||||
|
|
||||||
|
For the raw data, <structfield>size</structfield> field must be
|
||||||
|
set properly. This specifies the maximum size of the proc file access.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The callback is much more complicated than the text-file
|
The read/write callbacks of raw mode are more direct than the text mode.
|
||||||
version. You need to use a low-level I/O functions such as
|
You need to use a low-level I/O functions such as
|
||||||
<function>copy_from/to_user()</function> to transfer the
|
<function>copy_from/to_user()</function> to transfer the
|
||||||
data.
|
data.
|
||||||
|
|
||||||
<informalexample>
|
<informalexample>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
static long my_file_io_read(struct snd_info_entry *entry,
|
static ssize_t my_file_io_read(struct snd_info_entry *entry,
|
||||||
void *file_private_data,
|
void *file_private_data,
|
||||||
struct file *file,
|
struct file *file,
|
||||||
char *buf,
|
char *buf,
|
||||||
unsigned long count,
|
size_t count,
|
||||||
unsigned long pos)
|
loff_t pos)
|
||||||
{
|
{
|
||||||
long size = count;
|
if (copy_to_user(buf, local_data + pos, count))
|
||||||
if (pos + size > local_max_size)
|
|
||||||
size = local_max_size - pos;
|
|
||||||
if (copy_to_user(buf, local_data + pos, size))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return size;
|
return count;
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</informalexample>
|
</informalexample>
|
||||||
|
|
||||||
|
If the size of the info entry has been set up properly,
|
||||||
|
<structfield>count</structfield> and <structfield>pos</structfield> are
|
||||||
|
guaranteed to fit within 0 and the given size.
|
||||||
|
You don't have to check the range in the callbacks unless any
|
||||||
|
other condition is required.
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ static inline void skel_delete (struct usb_skel *dev)
|
|||||||
{
|
{
|
||||||
kfree (dev->bulk_in_buffer);
|
kfree (dev->bulk_in_buffer);
|
||||||
if (dev->bulk_out_buffer != NULL)
|
if (dev->bulk_out_buffer != NULL)
|
||||||
usb_buffer_free (dev->udev, dev->bulk_out_size,
|
usb_free_coherent (dev->udev, dev->bulk_out_size,
|
||||||
dev->bulk_out_buffer,
|
dev->bulk_out_buffer,
|
||||||
dev->write_urb->transfer_dma);
|
dev->write_urb->transfer_dma);
|
||||||
usb_free_urb (dev->write_urb);
|
usb_free_urb (dev->write_urb);
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ The driver should return one of the following result codes:
|
|||||||
|
|
||||||
- PCI_ERS_RESULT_NEED_RESET
|
- PCI_ERS_RESULT_NEED_RESET
|
||||||
Driver returns this if it thinks the device is not
|
Driver returns this if it thinks the device is not
|
||||||
recoverable in it's current state and it needs a slot
|
recoverable in its current state and it needs a slot
|
||||||
reset to proceed.
|
reset to proceed.
|
||||||
|
|
||||||
- PCI_ERS_RESULT_DISCONNECT
|
- PCI_ERS_RESULT_DISCONNECT
|
||||||
@@ -241,7 +241,7 @@ in working condition.
|
|||||||
|
|
||||||
The driver is not supposed to restart normal driver I/O operations
|
The driver is not supposed to restart normal driver I/O operations
|
||||||
at this point. It should limit itself to "probing" the device to
|
at this point. It should limit itself to "probing" the device to
|
||||||
check it's recoverability status. If all is right, then the platform
|
check its recoverability status. If all is right, then the platform
|
||||||
will call resume() once all drivers have ack'd link_reset().
|
will call resume() once all drivers have ack'd link_reset().
|
||||||
|
|
||||||
Result codes:
|
Result codes:
|
||||||
|
|||||||
@@ -3,35 +3,79 @@ Using RCU's CPU Stall Detector
|
|||||||
The CONFIG_RCU_CPU_STALL_DETECTOR kernel config parameter enables
|
The CONFIG_RCU_CPU_STALL_DETECTOR kernel config parameter enables
|
||||||
RCU's CPU stall detector, which detects conditions that unduly delay
|
RCU's CPU stall detector, which detects conditions that unduly delay
|
||||||
RCU grace periods. The stall detector's idea of what constitutes
|
RCU grace periods. The stall detector's idea of what constitutes
|
||||||
"unduly delayed" is controlled by a pair of C preprocessor macros:
|
"unduly delayed" is controlled by a set of C preprocessor macros:
|
||||||
|
|
||||||
RCU_SECONDS_TILL_STALL_CHECK
|
RCU_SECONDS_TILL_STALL_CHECK
|
||||||
|
|
||||||
This macro defines the period of time that RCU will wait from
|
This macro defines the period of time that RCU will wait from
|
||||||
the beginning of a grace period until it issues an RCU CPU
|
the beginning of a grace period until it issues an RCU CPU
|
||||||
stall warning. It is normally ten seconds.
|
stall warning. This time period is normally ten seconds.
|
||||||
|
|
||||||
RCU_SECONDS_TILL_STALL_RECHECK
|
RCU_SECONDS_TILL_STALL_RECHECK
|
||||||
|
|
||||||
This macro defines the period of time that RCU will wait after
|
This macro defines the period of time that RCU will wait after
|
||||||
issuing a stall warning until it issues another stall warning.
|
issuing a stall warning until it issues another stall warning
|
||||||
It is normally set to thirty seconds.
|
for the same stall. This time period is normally set to thirty
|
||||||
|
seconds.
|
||||||
|
|
||||||
RCU_STALL_RAT_DELAY
|
RCU_STALL_RAT_DELAY
|
||||||
|
|
||||||
The CPU stall detector tries to make the offending CPU rat on itself,
|
The CPU stall detector tries to make the offending CPU print its
|
||||||
as this often gives better-quality stack traces. However, if
|
own warnings, as this often gives better-quality stack traces.
|
||||||
the offending CPU does not detect its own stall in the number
|
However, if the offending CPU does not detect its own stall in
|
||||||
of jiffies specified by RCU_STALL_RAT_DELAY, then other CPUs will
|
the number of jiffies specified by RCU_STALL_RAT_DELAY, then
|
||||||
complain. This is normally set to two jiffies.
|
some other CPU will complain. This delay is normally set to
|
||||||
|
two jiffies.
|
||||||
|
|
||||||
The following problems can result in an RCU CPU stall warning:
|
When a CPU detects that it is stalling, it will print a message similar
|
||||||
|
to the following:
|
||||||
|
|
||||||
|
INFO: rcu_sched_state detected stall on CPU 5 (t=2500 jiffies)
|
||||||
|
|
||||||
|
This message indicates that CPU 5 detected that it was causing a stall,
|
||||||
|
and that the stall was affecting RCU-sched. This message will normally be
|
||||||
|
followed by a stack dump of the offending CPU. On TREE_RCU kernel builds,
|
||||||
|
RCU and RCU-sched are implemented by the same underlying mechanism,
|
||||||
|
while on TREE_PREEMPT_RCU kernel builds, RCU is instead implemented
|
||||||
|
by rcu_preempt_state.
|
||||||
|
|
||||||
|
On the other hand, if the offending CPU fails to print out a stall-warning
|
||||||
|
message quickly enough, some other CPU will print a message similar to
|
||||||
|
the following:
|
||||||
|
|
||||||
|
INFO: rcu_bh_state detected stalls on CPUs/tasks: { 3 5 } (detected by 2, 2502 jiffies)
|
||||||
|
|
||||||
|
This message indicates that CPU 2 detected that CPUs 3 and 5 were both
|
||||||
|
causing stalls, and that the stall was affecting RCU-bh. This message
|
||||||
|
will normally be followed by stack dumps for each CPU. Please note that
|
||||||
|
TREE_PREEMPT_RCU builds can be stalled by tasks as well as by CPUs,
|
||||||
|
and that the tasks will be indicated by PID, for example, "P3421".
|
||||||
|
It is even possible for a rcu_preempt_state stall to be caused by both
|
||||||
|
CPUs -and- tasks, in which case the offending CPUs and tasks will all
|
||||||
|
be called out in the list.
|
||||||
|
|
||||||
|
Finally, if the grace period ends just as the stall warning starts
|
||||||
|
printing, there will be a spurious stall-warning message:
|
||||||
|
|
||||||
|
INFO: rcu_bh_state detected stalls on CPUs/tasks: { } (detected by 4, 2502 jiffies)
|
||||||
|
|
||||||
|
This is rare, but does happen from time to time in real life.
|
||||||
|
|
||||||
|
So your kernel printed an RCU CPU stall warning. The next question is
|
||||||
|
"What caused it?" The following problems can result in RCU CPU stall
|
||||||
|
warnings:
|
||||||
|
|
||||||
o A CPU looping in an RCU read-side critical section.
|
o A CPU looping in an RCU read-side critical section.
|
||||||
|
|
||||||
o A CPU looping with interrupts disabled.
|
o A CPU looping with interrupts disabled. This condition can
|
||||||
|
result in RCU-sched and RCU-bh stalls.
|
||||||
|
|
||||||
o A CPU looping with preemption disabled.
|
o A CPU looping with preemption disabled. This condition can
|
||||||
|
result in RCU-sched stalls and, if ksoftirqd is in use, RCU-bh
|
||||||
|
stalls.
|
||||||
|
|
||||||
|
o A CPU looping with bottom halves disabled. This condition can
|
||||||
|
result in RCU-sched and RCU-bh stalls.
|
||||||
|
|
||||||
o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
|
o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
|
||||||
without invoking schedule().
|
without invoking schedule().
|
||||||
@@ -39,20 +83,24 @@ o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
|
|||||||
o A bug in the RCU implementation.
|
o A bug in the RCU implementation.
|
||||||
|
|
||||||
o A hardware failure. This is quite unlikely, but has occurred
|
o A hardware failure. This is quite unlikely, but has occurred
|
||||||
at least once in a former life. A CPU failed in a running system,
|
at least once in real life. A CPU failed in a running system,
|
||||||
becoming unresponsive, but not causing an immediate crash.
|
becoming unresponsive, but not causing an immediate crash.
|
||||||
This resulted in a series of RCU CPU stall warnings, eventually
|
This resulted in a series of RCU CPU stall warnings, eventually
|
||||||
leading the realization that the CPU had failed.
|
leading the realization that the CPU had failed.
|
||||||
|
|
||||||
The RCU, RCU-sched, and RCU-bh implementations have CPU stall warning.
|
The RCU, RCU-sched, and RCU-bh implementations have CPU stall
|
||||||
SRCU does not do so directly, but its calls to synchronize_sched() will
|
warning. SRCU does not have its own CPU stall warnings, but its
|
||||||
result in RCU-sched detecting any CPU stalls that might be occurring.
|
calls to synchronize_sched() will result in RCU-sched detecting
|
||||||
|
RCU-sched-related CPU stalls. Please note that RCU only detects
|
||||||
|
CPU stalls when there is a grace period in progress. No grace period,
|
||||||
|
no CPU stall warnings.
|
||||||
|
|
||||||
To diagnose the cause of the stall, inspect the stack traces. The offending
|
To diagnose the cause of the stall, inspect the stack traces.
|
||||||
function will usually be near the top of the stack. If you have a series
|
The offending function will usually be near the top of the stack.
|
||||||
of stall warnings from a single extended stall, comparing the stack traces
|
If you have a series of stall warnings from a single extended stall,
|
||||||
can often help determine where the stall is occurring, which will usually
|
comparing the stack traces can often help determine where the stall
|
||||||
be in the function nearest the top of the stack that stays the same from
|
is occurring, which will usually be in the function nearest the top of
|
||||||
trace to trace.
|
that portion of the stack which remains the same from trace to trace.
|
||||||
|
If you can reliably trigger the stall, ftrace can be quite helpful.
|
||||||
|
|
||||||
RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE.
|
RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE.
|
||||||
|
|||||||
@@ -182,16 +182,6 @@ Similarly, sched_expedited RCU provides the following:
|
|||||||
sched_expedited-torture: Reader Pipe: 12660320201 95875 0 0 0 0 0 0 0 0 0
|
sched_expedited-torture: Reader Pipe: 12660320201 95875 0 0 0 0 0 0 0 0 0
|
||||||
sched_expedited-torture: Reader Batch: 12660424885 0 0 0 0 0 0 0 0 0 0
|
sched_expedited-torture: Reader Batch: 12660424885 0 0 0 0 0 0 0 0 0 0
|
||||||
sched_expedited-torture: Free-Block Circulation: 1090795 1090795 1090794 1090793 1090792 1090791 1090790 1090789 1090788 1090787 0
|
sched_expedited-torture: Free-Block Circulation: 1090795 1090795 1090794 1090793 1090792 1090791 1090790 1090789 1090788 1090787 0
|
||||||
state: -1 / 0:0 3:0 4:0
|
|
||||||
|
|
||||||
As before, the first four lines are similar to those for RCU.
|
|
||||||
The last line shows the task-migration state. The first number is
|
|
||||||
-1 if synchronize_sched_expedited() is idle, -2 if in the process of
|
|
||||||
posting wakeups to the migration kthreads, and N when waiting on CPU N.
|
|
||||||
Each of the colon-separated fields following the "/" is a CPU:state pair.
|
|
||||||
Valid states are "0" for idle, "1" for waiting for quiescent state,
|
|
||||||
"2" for passed through quiescent state, and "3" when a race with a
|
|
||||||
CPU-hotplug event forces use of the synchronize_sched() primitive.
|
|
||||||
|
|
||||||
|
|
||||||
USAGE
|
USAGE
|
||||||
|
|||||||
@@ -256,23 +256,23 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
|
|||||||
The output of "cat rcu/rcu_pending" looks as follows:
|
The output of "cat rcu/rcu_pending" looks as follows:
|
||||||
|
|
||||||
rcu_sched:
|
rcu_sched:
|
||||||
0 np=255892 qsp=53936 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
|
0 np=255892 qsp=53936 rpq=85 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
|
||||||
1 np=261224 qsp=54638 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
|
1 np=261224 qsp=54638 rpq=33 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
|
||||||
2 np=237496 qsp=49664 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
|
2 np=237496 qsp=49664 rpq=23 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
|
||||||
3 np=236249 qsp=48766 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
|
3 np=236249 qsp=48766 rpq=98 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
|
||||||
4 np=221310 qsp=46850 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
|
4 np=221310 qsp=46850 rpq=7 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
|
||||||
5 np=237332 qsp=48449 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
|
5 np=237332 qsp=48449 rpq=9 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
|
||||||
6 np=219995 qsp=46718 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
|
6 np=219995 qsp=46718 rpq=12 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
|
||||||
7 np=249893 qsp=49390 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
|
7 np=249893 qsp=49390 rpq=42 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
|
||||||
rcu_bh:
|
rcu_bh:
|
||||||
0 np=146741 qsp=1419 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
|
0 np=146741 qsp=1419 rpq=6 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
|
||||||
1 np=155792 qsp=12597 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
|
1 np=155792 qsp=12597 rpq=3 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
|
||||||
2 np=136629 qsp=18680 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
|
2 np=136629 qsp=18680 rpq=1 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
|
||||||
3 np=137723 qsp=2843 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
|
3 np=137723 qsp=2843 rpq=0 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
|
||||||
4 np=123110 qsp=12433 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
|
4 np=123110 qsp=12433 rpq=0 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
|
||||||
5 np=137456 qsp=4210 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
|
5 np=137456 qsp=4210 rpq=1 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
|
||||||
6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
|
6 np=120834 qsp=9902 rpq=2 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
|
||||||
7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
|
7 np=144888 qsp=26336 rpq=0 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
|
||||||
|
|
||||||
As always, this is once again split into "rcu_sched" and "rcu_bh"
|
As always, this is once again split into "rcu_sched" and "rcu_bh"
|
||||||
portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
|
portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
|
||||||
@@ -284,6 +284,9 @@ o "np" is the number of times that __rcu_pending() has been invoked
|
|||||||
o "qsp" is the number of times that the RCU was waiting for a
|
o "qsp" is the number of times that the RCU was waiting for a
|
||||||
quiescent state from this CPU.
|
quiescent state from this CPU.
|
||||||
|
|
||||||
|
o "rpq" is the number of times that the CPU had passed through
|
||||||
|
a quiescent state, but not yet reported it to RCU.
|
||||||
|
|
||||||
o "cbr" is the number of times that this CPU had RCU callbacks
|
o "cbr" is the number of times that this CPU had RCU callbacks
|
||||||
that had passed through a grace period, and were thus ready
|
that had passed through a grace period, and were thus ready
|
||||||
to be invoked.
|
to be invoked.
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ NOTE: Smack labels are limited to 23 characters. The attr command
|
|||||||
If you don't do anything special all users will get the floor ("_")
|
If you don't do anything special all users will get the floor ("_")
|
||||||
label when they log in. If you do want to log in via the hacked ssh
|
label when they log in. If you do want to log in via the hacked ssh
|
||||||
at other labels use the attr command to set the smack value on the
|
at other labels use the attr command to set the smack value on the
|
||||||
home directory and it's contents.
|
home directory and its contents.
|
||||||
|
|
||||||
You can add access rules in /etc/smack/accesses. They take the form:
|
You can add access rules in /etc/smack/accesses. They take the form:
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ Samsung-S3C24XX
|
|||||||
- S3C24XX ARM Linux Overview
|
- S3C24XX ARM Linux Overview
|
||||||
Sharp-LH
|
Sharp-LH
|
||||||
- Linux on Sharp LH79524 and LH7A40X System On a Chip (SOC)
|
- Linux on Sharp LH79524 and LH7A40X System On a Chip (SOC)
|
||||||
|
SPEAr
|
||||||
|
- ST SPEAr platform Linux Overview
|
||||||
VFP/
|
VFP/
|
||||||
- Release notes for Linux Kernel Vector Floating Point support code
|
- Release notes for Linux Kernel Vector Floating Point support code
|
||||||
empeg/
|
empeg/
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Notes:
|
|||||||
|
|
||||||
- The flash on board is divided into 3 partitions.
|
- The flash on board is divided into 3 partitions.
|
||||||
You should be careful to use flash on board.
|
You should be careful to use flash on board.
|
||||||
It's partition is different from GraphicsClient Plus and GraphicsMaster
|
Its partition is different from GraphicsClient Plus and GraphicsMaster
|
||||||
|
|
||||||
- 16bpp mode requires a different cable than what ships with the board.
|
- 16bpp mode requires a different cable than what ships with the board.
|
||||||
Contact ADS or look through the manual to wire your own. Currently,
|
Contact ADS or look through the manual to wire your own. Currently,
|
||||||
|
|||||||
60
Documentation/arm/SPEAr/overview.txt
Normal file
60
Documentation/arm/SPEAr/overview.txt
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
SPEAr ARM Linux Overview
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
SPEAr (Structured Processor Enhanced Architecture).
|
||||||
|
weblink : http://www.st.com/spear
|
||||||
|
|
||||||
|
The ST Microelectronics SPEAr range of ARM9/CortexA9 System-on-Chip CPUs are
|
||||||
|
supported by the 'spear' platform of ARM Linux. Currently SPEAr300,
|
||||||
|
SPEAr310, SPEAr320 and SPEAr600 SOCs are supported. Support for the SPEAr13XX
|
||||||
|
series is in progress.
|
||||||
|
|
||||||
|
Hierarchy in SPEAr is as follows:
|
||||||
|
|
||||||
|
SPEAr (Platform)
|
||||||
|
- SPEAr3XX (3XX SOC series, based on ARM9)
|
||||||
|
- SPEAr300 (SOC)
|
||||||
|
- SPEAr300_EVB (Evaluation Board)
|
||||||
|
- SPEAr310 (SOC)
|
||||||
|
- SPEAr310_EVB (Evaluation Board)
|
||||||
|
- SPEAr320 (SOC)
|
||||||
|
- SPEAr320_EVB (Evaluation Board)
|
||||||
|
- SPEAr6XX (6XX SOC series, based on ARM9)
|
||||||
|
- SPEAr600 (SOC)
|
||||||
|
- SPEAr600_EVB (Evaluation Board)
|
||||||
|
- SPEAr13XX (13XX SOC series, based on ARM CORTEXA9)
|
||||||
|
- SPEAr1300 (SOC)
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
A generic configuration is provided for each machine, and can be used as the
|
||||||
|
default by
|
||||||
|
make spear600_defconfig
|
||||||
|
make spear300_defconfig
|
||||||
|
make spear310_defconfig
|
||||||
|
make spear320_defconfig
|
||||||
|
|
||||||
|
Layout
|
||||||
|
------
|
||||||
|
|
||||||
|
The common files for multiple machine families (SPEAr3XX, SPEAr6XX and
|
||||||
|
SPEAr13XX) are located in the platform code contained in arch/arm/plat-spear
|
||||||
|
with headers in plat/.
|
||||||
|
|
||||||
|
Each machine series have a directory with name arch/arm/mach-spear followed by
|
||||||
|
series name. Like mach-spear3xx, mach-spear6xx and mach-spear13xx.
|
||||||
|
|
||||||
|
Common file for machines of spear3xx family is mach-spear3xx/spear3xx.c and for
|
||||||
|
spear6xx is mach-spear6xx/spear6xx.c. mach-spear* also contain soc/machine
|
||||||
|
specific files, like spear300.c, spear310.c, spear320.c and spear600.c.
|
||||||
|
mach-spear* also contains board specific files for each machine type.
|
||||||
|
|
||||||
|
|
||||||
|
Document Author
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Viresh Kumar, (c) 2010 ST Microelectronics
|
||||||
@@ -7,7 +7,7 @@ The driver only implements a four-wire touch panel protocol.
|
|||||||
|
|
||||||
The touchscreen driver is maintenance free except for the pen-down or
|
The touchscreen driver is maintenance free except for the pen-down or
|
||||||
touch threshold. Some resistive displays and board combinations may
|
touch threshold. Some resistive displays and board combinations may
|
||||||
require tuning of this threshold. The driver exposes some of it's
|
require tuning of this threshold. The driver exposes some of its
|
||||||
internal state in the sys filesystem. If the kernel is configured
|
internal state in the sys filesystem. If the kernel is configured
|
||||||
with it, CONFIG_SYSFS, and sysfs is mounted at /sys, there will be a
|
with it, CONFIG_SYSFS, and sysfs is mounted at /sys, there will be a
|
||||||
directory
|
directory
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ counter decrement would not become globally visible until the
|
|||||||
obj->active update does.
|
obj->active update does.
|
||||||
|
|
||||||
As a historical note, 32-bit Sparc used to only allow usage of
|
As a historical note, 32-bit Sparc used to only allow usage of
|
||||||
24-bits of it's atomic_t type. This was because it used 8 bits
|
24-bits of its atomic_t type. This was because it used 8 bits
|
||||||
as a spinlock for SMP safety. Sparc32 lacked a "compare and swap"
|
as a spinlock for SMP safety. Sparc32 lacked a "compare and swap"
|
||||||
type instruction. However, 32-bit Sparc has since been moved over
|
type instruction. However, 32-bit Sparc has since been moved over
|
||||||
to a "hash table of spinlocks" scheme, that allows the full 32-bit
|
to a "hash table of spinlocks" scheme, that allows the full 32-bit
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
void bfin_gpio_irq_free(unsigned gpio);
|
void bfin_gpio_irq_free(unsigned gpio);
|
||||||
|
|
||||||
The request functions will record the function state for a certain pin,
|
The request functions will record the function state for a certain pin,
|
||||||
the free functions will clear it's function state.
|
the free functions will clear its function state.
|
||||||
Once a pin is requested, it can't be requested again before it is freed by
|
Once a pin is requested, it can't be requested again before it is freed by
|
||||||
previous caller, otherwise kernel will dump stacks, and the request
|
previous caller, otherwise kernel will dump stacks, and the request
|
||||||
function fail.
|
function fail.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
This document describes the cache/tlb flushing interfaces called
|
This document describes the cache/tlb flushing interfaces called
|
||||||
by the Linux VM subsystem. It enumerates over each interface,
|
by the Linux VM subsystem. It enumerates over each interface,
|
||||||
describes it's intended purpose, and what side effect is expected
|
describes its intended purpose, and what side effect is expected
|
||||||
after the interface is invoked.
|
after the interface is invoked.
|
||||||
|
|
||||||
The side effects described below are stated for a uniprocessor
|
The side effects described below are stated for a uniprocessor
|
||||||
@@ -231,7 +231,7 @@ require a whole different set of interfaces to handle properly.
|
|||||||
The biggest problem is that of virtual aliasing in the data cache
|
The biggest problem is that of virtual aliasing in the data cache
|
||||||
of a processor.
|
of a processor.
|
||||||
|
|
||||||
Is your port susceptible to virtual aliasing in it's D-cache?
|
Is your port susceptible to virtual aliasing in its D-cache?
|
||||||
Well, if your D-cache is virtually indexed, is larger in size than
|
Well, if your D-cache is virtually indexed, is larger in size than
|
||||||
PAGE_SIZE, and does not prevent multiple cache lines for the same
|
PAGE_SIZE, and does not prevent multiple cache lines for the same
|
||||||
physical address from existing at once, you have this problem.
|
physical address from existing at once, you have this problem.
|
||||||
@@ -249,7 +249,7 @@ one way to solve this (in particular SPARC_FLAG_MMAPSHARED).
|
|||||||
Next, you have to solve the D-cache aliasing issue for all
|
Next, you have to solve the D-cache aliasing issue for all
|
||||||
other cases. Please keep in mind that fact that, for a given page
|
other cases. Please keep in mind that fact that, for a given page
|
||||||
mapped into some user address space, there is always at least one more
|
mapped into some user address space, there is always at least one more
|
||||||
mapping, that of the kernel in it's linear mapping starting at
|
mapping, that of the kernel in its linear mapping starting at
|
||||||
PAGE_OFFSET. So immediately, once the first user maps a given
|
PAGE_OFFSET. So immediately, once the first user maps a given
|
||||||
physical page into its address space, by implication the D-cache
|
physical page into its address space, by implication the D-cache
|
||||||
aliasing problem has the potential to exist since the kernel already
|
aliasing problem has the potential to exist since the kernel already
|
||||||
|
|||||||
@@ -572,7 +572,7 @@ void cancel_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
|
|||||||
|
|
||||||
Called when a task attach operation has failed after can_attach() has succeeded.
|
Called when a task attach operation has failed after can_attach() has succeeded.
|
||||||
A subsystem whose can_attach() has some side-effects should provide this
|
A subsystem whose can_attach() has some side-effects should provide this
|
||||||
function, so that the subsytem can implement a rollback. If not, not necessary.
|
function, so that the subsystem can implement a rollback. If not, not necessary.
|
||||||
This will be called only about subsystems whose can_attach() operation have
|
This will be called only about subsystems whose can_attach() operation have
|
||||||
succeeded.
|
succeeded.
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Nodes to a set of tasks. In this document "Memory Node" refers to
|
|||||||
an on-line node that contains memory.
|
an on-line node that contains memory.
|
||||||
|
|
||||||
Cpusets constrain the CPU and Memory placement of tasks to only
|
Cpusets constrain the CPU and Memory placement of tasks to only
|
||||||
the resources within a tasks current cpuset. They form a nested
|
the resources within a task's current cpuset. They form a nested
|
||||||
hierarchy visible in a virtual file system. These are the essential
|
hierarchy visible in a virtual file system. These are the essential
|
||||||
hooks, beyond what is already present, required to manage dynamic
|
hooks, beyond what is already present, required to manage dynamic
|
||||||
job placement on large systems.
|
job placement on large systems.
|
||||||
@@ -53,11 +53,11 @@ Documentation/cgroups/cgroups.txt.
|
|||||||
Requests by a task, using the sched_setaffinity(2) system call to
|
Requests by a task, using the sched_setaffinity(2) system call to
|
||||||
include CPUs in its CPU affinity mask, and using the mbind(2) and
|
include CPUs in its CPU affinity mask, and using the mbind(2) and
|
||||||
set_mempolicy(2) system calls to include Memory Nodes in its memory
|
set_mempolicy(2) system calls to include Memory Nodes in its memory
|
||||||
policy, are both filtered through that tasks cpuset, filtering out any
|
policy, are both filtered through that task's cpuset, filtering out any
|
||||||
CPUs or Memory Nodes not in that cpuset. The scheduler will not
|
CPUs or Memory Nodes not in that cpuset. The scheduler will not
|
||||||
schedule a task on a CPU that is not allowed in its cpus_allowed
|
schedule a task on a CPU that is not allowed in its cpus_allowed
|
||||||
vector, and the kernel page allocator will not allocate a page on a
|
vector, and the kernel page allocator will not allocate a page on a
|
||||||
node that is not allowed in the requesting tasks mems_allowed vector.
|
node that is not allowed in the requesting task's mems_allowed vector.
|
||||||
|
|
||||||
User level code may create and destroy cpusets by name in the cgroup
|
User level code may create and destroy cpusets by name in the cgroup
|
||||||
virtual file system, manage the attributes and permissions of these
|
virtual file system, manage the attributes and permissions of these
|
||||||
@@ -121,9 +121,9 @@ Cpusets extends these two mechanisms as follows:
|
|||||||
- Each task in the system is attached to a cpuset, via a pointer
|
- Each task in the system is attached to a cpuset, via a pointer
|
||||||
in the task structure to a reference counted cgroup structure.
|
in the task structure to a reference counted cgroup structure.
|
||||||
- Calls to sched_setaffinity are filtered to just those CPUs
|
- Calls to sched_setaffinity are filtered to just those CPUs
|
||||||
allowed in that tasks cpuset.
|
allowed in that task's cpuset.
|
||||||
- Calls to mbind and set_mempolicy are filtered to just
|
- Calls to mbind and set_mempolicy are filtered to just
|
||||||
those Memory Nodes allowed in that tasks cpuset.
|
those Memory Nodes allowed in that task's cpuset.
|
||||||
- The root cpuset contains all the systems CPUs and Memory
|
- The root cpuset contains all the systems CPUs and Memory
|
||||||
Nodes.
|
Nodes.
|
||||||
- For any cpuset, one can define child cpusets containing a subset
|
- For any cpuset, one can define child cpusets containing a subset
|
||||||
@@ -141,11 +141,11 @@ into the rest of the kernel, none in performance critical paths:
|
|||||||
- in init/main.c, to initialize the root cpuset at system boot.
|
- in init/main.c, to initialize the root cpuset at system boot.
|
||||||
- in fork and exit, to attach and detach a task from its cpuset.
|
- in fork and exit, to attach and detach a task from its cpuset.
|
||||||
- in sched_setaffinity, to mask the requested CPUs by what's
|
- in sched_setaffinity, to mask the requested CPUs by what's
|
||||||
allowed in that tasks cpuset.
|
allowed in that task's cpuset.
|
||||||
- in sched.c migrate_live_tasks(), to keep migrating tasks within
|
- in sched.c migrate_live_tasks(), to keep migrating tasks within
|
||||||
the CPUs allowed by their cpuset, if possible.
|
the CPUs allowed by their cpuset, if possible.
|
||||||
- in the mbind and set_mempolicy system calls, to mask the requested
|
- in the mbind and set_mempolicy system calls, to mask the requested
|
||||||
Memory Nodes by what's allowed in that tasks cpuset.
|
Memory Nodes by what's allowed in that task's cpuset.
|
||||||
- in page_alloc.c, to restrict memory to allowed nodes.
|
- in page_alloc.c, to restrict memory to allowed nodes.
|
||||||
- in vmscan.c, to restrict page recovery to the current cpuset.
|
- in vmscan.c, to restrict page recovery to the current cpuset.
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ new system calls are added for cpusets - all support for querying and
|
|||||||
modifying cpusets is via this cpuset file system.
|
modifying cpusets is via this cpuset file system.
|
||||||
|
|
||||||
The /proc/<pid>/status file for each task has four added lines,
|
The /proc/<pid>/status file for each task has four added lines,
|
||||||
displaying the tasks cpus_allowed (on which CPUs it may be scheduled)
|
displaying the task's cpus_allowed (on which CPUs it may be scheduled)
|
||||||
and mems_allowed (on which Memory Nodes it may obtain memory),
|
and mems_allowed (on which Memory Nodes it may obtain memory),
|
||||||
in the two formats seen in the following example:
|
in the two formats seen in the following example:
|
||||||
|
|
||||||
@@ -323,17 +323,17 @@ stack segment pages of a task.
|
|||||||
|
|
||||||
By default, both kinds of memory spreading are off, and memory
|
By default, both kinds of memory spreading are off, and memory
|
||||||
pages are allocated on the node local to where the task is running,
|
pages are allocated on the node local to where the task is running,
|
||||||
except perhaps as modified by the tasks NUMA mempolicy or cpuset
|
except perhaps as modified by the task's NUMA mempolicy or cpuset
|
||||||
configuration, so long as sufficient free memory pages are available.
|
configuration, so long as sufficient free memory pages are available.
|
||||||
|
|
||||||
When new cpusets are created, they inherit the memory spread settings
|
When new cpusets are created, they inherit the memory spread settings
|
||||||
of their parent.
|
of their parent.
|
||||||
|
|
||||||
Setting memory spreading causes allocations for the affected page
|
Setting memory spreading causes allocations for the affected page
|
||||||
or slab caches to ignore the tasks NUMA mempolicy and be spread
|
or slab caches to ignore the task's NUMA mempolicy and be spread
|
||||||
instead. Tasks using mbind() or set_mempolicy() calls to set NUMA
|
instead. Tasks using mbind() or set_mempolicy() calls to set NUMA
|
||||||
mempolicies will not notice any change in these calls as a result of
|
mempolicies will not notice any change in these calls as a result of
|
||||||
their containing tasks memory spread settings. If memory spreading
|
their containing task's memory spread settings. If memory spreading
|
||||||
is turned off, then the currently specified NUMA mempolicy once again
|
is turned off, then the currently specified NUMA mempolicy once again
|
||||||
applies to memory page allocations.
|
applies to memory page allocations.
|
||||||
|
|
||||||
@@ -357,7 +357,7 @@ pages from the node returned by cpuset_mem_spread_node().
|
|||||||
|
|
||||||
The cpuset_mem_spread_node() routine is also simple. It uses the
|
The cpuset_mem_spread_node() routine is also simple. It uses the
|
||||||
value of a per-task rotor cpuset_mem_spread_rotor to select the next
|
value of a per-task rotor cpuset_mem_spread_rotor to select the next
|
||||||
node in the current tasks mems_allowed to prefer for the allocation.
|
node in the current task's mems_allowed to prefer for the allocation.
|
||||||
|
|
||||||
This memory placement policy is also known (in other contexts) as
|
This memory placement policy is also known (in other contexts) as
|
||||||
round-robin or interleave.
|
round-robin or interleave.
|
||||||
@@ -594,7 +594,7 @@ is attached, is subtle.
|
|||||||
If a cpuset has its Memory Nodes modified, then for each task attached
|
If a cpuset has its Memory Nodes modified, then for each task attached
|
||||||
to that cpuset, the next time that the kernel attempts to allocate
|
to that cpuset, the next time that the kernel attempts to allocate
|
||||||
a page of memory for that task, the kernel will notice the change
|
a page of memory for that task, the kernel will notice the change
|
||||||
in the tasks cpuset, and update its per-task memory placement to
|
in the task's cpuset, and update its per-task memory placement to
|
||||||
remain within the new cpusets memory placement. If the task was using
|
remain within the new cpusets memory placement. If the task was using
|
||||||
mempolicy MPOL_BIND, and the nodes to which it was bound overlap with
|
mempolicy MPOL_BIND, and the nodes to which it was bound overlap with
|
||||||
its new cpuset, then the task will continue to use whatever subset
|
its new cpuset, then the task will continue to use whatever subset
|
||||||
@@ -603,13 +603,13 @@ was using MPOL_BIND and now none of its MPOL_BIND nodes are allowed
|
|||||||
in the new cpuset, then the task will be essentially treated as if it
|
in the new cpuset, then the task will be essentially treated as if it
|
||||||
was MPOL_BIND bound to the new cpuset (even though its NUMA placement,
|
was MPOL_BIND bound to the new cpuset (even though its NUMA placement,
|
||||||
as queried by get_mempolicy(), doesn't change). If a task is moved
|
as queried by get_mempolicy(), doesn't change). If a task is moved
|
||||||
from one cpuset to another, then the kernel will adjust the tasks
|
from one cpuset to another, then the kernel will adjust the task's
|
||||||
memory placement, as above, the next time that the kernel attempts
|
memory placement, as above, the next time that the kernel attempts
|
||||||
to allocate a page of memory for that task.
|
to allocate a page of memory for that task.
|
||||||
|
|
||||||
If a cpuset has its 'cpuset.cpus' modified, then each task in that cpuset
|
If a cpuset has its 'cpuset.cpus' modified, then each task in that cpuset
|
||||||
will have its allowed CPU placement changed immediately. Similarly,
|
will have its allowed CPU placement changed immediately. Similarly,
|
||||||
if a tasks pid is written to another cpusets 'cpuset.tasks' file, then its
|
if a task's pid is written to another cpusets 'cpuset.tasks' file, then its
|
||||||
allowed CPU placement is changed immediately. If such a task had been
|
allowed CPU placement is changed immediately. If such a task had been
|
||||||
bound to some subset of its cpuset using the sched_setaffinity() call,
|
bound to some subset of its cpuset using the sched_setaffinity() call,
|
||||||
the task will be allowed to run on any CPU allowed in its new cpuset,
|
the task will be allowed to run on any CPU allowed in its new cpuset,
|
||||||
@@ -626,16 +626,16 @@ cpusets memory placement policy 'cpuset.mems' subsequently changes.
|
|||||||
If the cpuset flag file 'cpuset.memory_migrate' is set true, then when
|
If the cpuset flag file 'cpuset.memory_migrate' is set true, then when
|
||||||
tasks are attached to that cpuset, any pages that task had
|
tasks are attached to that cpuset, any pages that task had
|
||||||
allocated to it on nodes in its previous cpuset are migrated
|
allocated to it on nodes in its previous cpuset are migrated
|
||||||
to the tasks new cpuset. The relative placement of the page within
|
to the task's new cpuset. The relative placement of the page within
|
||||||
the cpuset is preserved during these migration operations if possible.
|
the cpuset is preserved during these migration operations if possible.
|
||||||
For example if the page was on the second valid node of the prior cpuset
|
For example if the page was on the second valid node of the prior cpuset
|
||||||
then the page will be placed on the second valid node of the new cpuset.
|
then the page will be placed on the second valid node of the new cpuset.
|
||||||
|
|
||||||
Also if 'cpuset.memory_migrate' is set true, then if that cpusets
|
Also if 'cpuset.memory_migrate' is set true, then if that cpuset's
|
||||||
'cpuset.mems' file is modified, pages allocated to tasks in that
|
'cpuset.mems' file is modified, pages allocated to tasks in that
|
||||||
cpuset, that were on nodes in the previous setting of 'cpuset.mems',
|
cpuset, that were on nodes in the previous setting of 'cpuset.mems',
|
||||||
will be moved to nodes in the new setting of 'mems.'
|
will be moved to nodes in the new setting of 'mems.'
|
||||||
Pages that were not in the tasks prior cpuset, or in the cpusets
|
Pages that were not in the task's prior cpuset, or in the cpuset's
|
||||||
prior 'cpuset.mems' setting, will not be moved.
|
prior 'cpuset.mems' setting, will not be moved.
|
||||||
|
|
||||||
There is an exception to the above. If hotplug functionality is used
|
There is an exception to the above. If hotplug functionality is used
|
||||||
@@ -655,7 +655,7 @@ There is a second exception to the above. GFP_ATOMIC requests are
|
|||||||
kernel internal allocations that must be satisfied, immediately.
|
kernel internal allocations that must be satisfied, immediately.
|
||||||
The kernel may drop some request, in rare cases even panic, if a
|
The kernel may drop some request, in rare cases even panic, if a
|
||||||
GFP_ATOMIC alloc fails. If the request cannot be satisfied within
|
GFP_ATOMIC alloc fails. If the request cannot be satisfied within
|
||||||
the current tasks cpuset, then we relax the cpuset, and look for
|
the current task's cpuset, then we relax the cpuset, and look for
|
||||||
memory anywhere we can find it. It's better to violate the cpuset
|
memory anywhere we can find it. It's better to violate the cpuset
|
||||||
than stress the kernel.
|
than stress the kernel.
|
||||||
|
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y.
|
|||||||
we have to check if OLDPAGE/NEWPAGE is a valid page after commit().
|
we have to check if OLDPAGE/NEWPAGE is a valid page after commit().
|
||||||
|
|
||||||
8. LRU
|
8. LRU
|
||||||
Each memcg has its own private LRU. Now, it's handling is under global
|
Each memcg has its own private LRU. Now, its handling is under global
|
||||||
VM's control (means that it's handled under global zone->lru_lock).
|
VM's control (means that it's handled under global zone->lru_lock).
|
||||||
Almost all routines around memcg's LRU is called by global LRU's
|
Almost all routines around memcg's LRU is called by global LRU's
|
||||||
list management functions under zone->lru_lock().
|
list management functions under zone->lru_lock().
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ some of the pages cached in the cgroup (page cache pages).
|
|||||||
|
|
||||||
4.2 Task migration
|
4.2 Task migration
|
||||||
|
|
||||||
When a task migrates from one cgroup to another, it's charge is not
|
When a task migrates from one cgroup to another, its charge is not
|
||||||
carried forward by default. The pages allocated from the original cgroup still
|
carried forward by default. The pages allocated from the original cgroup still
|
||||||
remain charged to it, the charge is dropped when the page is freed or
|
remain charged to it, the charge is dropped when the page is freed or
|
||||||
reclaimed.
|
reclaimed.
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ int cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask);
|
|||||||
int gfp_mask - GFP mask.
|
int gfp_mask - GFP mask.
|
||||||
|
|
||||||
Note: When registering new callback user, connector core assigns
|
Note: When registering new callback user, connector core assigns
|
||||||
netlink group to the user which is equal to it's id.idx.
|
netlink group to the user which is equal to its id.idx.
|
||||||
|
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
Protocol description.
|
Protocol description.
|
||||||
|
|||||||
@@ -408,9 +408,6 @@ This should be used inside the RCU read lock, as in the following example:
|
|||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
A function need not get RCU read lock to use __task_cred() if it is holding a
|
|
||||||
spinlock at the time as this implicitly holds the RCU read lock.
|
|
||||||
|
|
||||||
Should it be necessary to hold another task's credentials for a long period of
|
Should it be necessary to hold another task's credentials for a long period of
|
||||||
time, and possibly to sleep whilst doing so, then the caller should get a
|
time, and possibly to sleep whilst doing so, then the caller should get a
|
||||||
reference on them using:
|
reference on them using:
|
||||||
@@ -426,17 +423,16 @@ credentials, hiding the RCU magic from the caller:
|
|||||||
uid_t task_uid(task) Task's real UID
|
uid_t task_uid(task) Task's real UID
|
||||||
uid_t task_euid(task) Task's effective UID
|
uid_t task_euid(task) Task's effective UID
|
||||||
|
|
||||||
If the caller is holding a spinlock or the RCU read lock at the time anyway,
|
If the caller is holding the RCU read lock at the time anyway, then:
|
||||||
then:
|
|
||||||
|
|
||||||
__task_cred(task)->uid
|
__task_cred(task)->uid
|
||||||
__task_cred(task)->euid
|
__task_cred(task)->euid
|
||||||
|
|
||||||
should be used instead. Similarly, if multiple aspects of a task's credentials
|
should be used instead. Similarly, if multiple aspects of a task's credentials
|
||||||
need to be accessed, RCU read lock or a spinlock should be used, __task_cred()
|
need to be accessed, RCU read lock should be used, __task_cred() called, the
|
||||||
called, the result stored in a temporary pointer and then the credential
|
result stored in a temporary pointer and then the credential aspects called
|
||||||
aspects called from that before dropping the lock. This prevents the
|
from that before dropping the lock. This prevents the potentially expensive
|
||||||
potentially expensive RCU magic from being invoked multiple times.
|
RCU magic from being invoked multiple times.
|
||||||
|
|
||||||
Should some other single aspect of another task's credentials need to be
|
Should some other single aspect of another task's credentials need to be
|
||||||
accessed, then this can be used:
|
accessed, then this can be used:
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ This application requires the following to function properly as of now.
|
|||||||
|
|
||||||
* Cards that fall in this category
|
* Cards that fall in this category
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
At present the cards that fall in this category are the Twinhan and it's
|
At present the cards that fall in this category are the Twinhan and its
|
||||||
clones, these cards are available as VVMER, Tomato, Hercules, Orange and
|
clones, these cards are available as VVMER, Tomato, Hercules, Orange and
|
||||||
so on.
|
so on.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Thanks go to the following people for patches and contributions:
|
Thanks go to the following people for patches and contributions:
|
||||||
|
|
||||||
Michael Hunold <m.hunold@gmx.de>
|
Michael Hunold <m.hunold@gmx.de>
|
||||||
for the initial saa7146 driver and it's recent overhaul
|
for the initial saa7146 driver and its recent overhaul
|
||||||
|
|
||||||
Christian Theiss
|
Christian Theiss
|
||||||
for his work on the initial Linux DVB driver
|
for his work on the initial Linux DVB driver
|
||||||
|
|||||||
@@ -241,16 +241,6 @@ Who: Thomas Gleixner <tglx@linutronix.de>
|
|||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What (Why):
|
|
||||||
- xt_recent: the old ipt_recent proc dir
|
|
||||||
(superseded by /proc/net/xt_recent)
|
|
||||||
|
|
||||||
When: January 2009 or Linux 2.7.0, whichever comes first
|
|
||||||
Why: Superseded by newer revisions or modules
|
|
||||||
Who: Jan Engelhardt <jengelh@computergmbh.de>
|
|
||||||
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
What: GPIO autorequest on gpio_direction_{input,output}() in gpiolib
|
What: GPIO autorequest on gpio_direction_{input,output}() in gpiolib
|
||||||
When: February 2010
|
When: February 2010
|
||||||
Why: All callers should use explicit gpio_request()/gpio_free().
|
Why: All callers should use explicit gpio_request()/gpio_free().
|
||||||
@@ -520,26 +510,21 @@ Who: Hans de Goede <hdegoede@redhat.com>
|
|||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
What: corgikbd, spitzkbd, tosakbd driver
|
What: sysfs-class-rfkill state file
|
||||||
When: 2.6.35
|
When: Feb 2014
|
||||||
Files: drivers/input/keyboard/{corgi,spitz,tosa}kbd.c
|
Files: net/rfkill/core.c
|
||||||
Why: We now have a generic GPIO based matrix keyboard driver that
|
Why: Documented as obsolete since Feb 2010. This file is limited to 3
|
||||||
are fully capable of handling all the keys on these devices.
|
states while the rfkill drivers can have 4 states.
|
||||||
The original drivers manipulate the GPIO registers directly
|
Who: anybody or Florian Mickler <florian@mickler.org>
|
||||||
and so are difficult to maintain.
|
|
||||||
Who: Eric Miao <eric.y.miao@gmail.com>
|
|
||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
What: corgi_ssp and corgi_ts driver
|
What: sysfs-class-rfkill claim file
|
||||||
When: 2.6.35
|
When: Feb 2012
|
||||||
Files: arch/arm/mach-pxa/corgi_ssp.c, drivers/input/touchscreen/corgi_ts.c
|
Files: net/rfkill/core.c
|
||||||
Why: The corgi touchscreen is now deprecated in favour of the generic
|
Why: It is not possible to claim an rfkill driver since 2007. This is
|
||||||
ads7846.c driver. The noise reduction technique used in corgi_ts.c,
|
Documented as obsolete since Feb 2010.
|
||||||
that's to wait till vsync before ADC sampling, is also integrated into
|
Who: anybody or Florian Mickler <florian@mickler.org>
|
||||||
ads7846 driver now. Provided that the original driver is not generic
|
|
||||||
and is difficult to maintain, it will be removed later.
|
|
||||||
Who: Eric Miao <eric.y.miao@gmail.com>
|
|
||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
@@ -564,6 +549,16 @@ Who: Avi Kivity <avi@redhat.com>
|
|||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
What: xtime, wall_to_monotonic
|
||||||
|
When: 2.6.36+
|
||||||
|
Files: kernel/time/timekeeping.c include/linux/time.h
|
||||||
|
Why: Cleaning up timekeeping internal values. Please use
|
||||||
|
existing timekeeping accessor functions to access
|
||||||
|
the equivalent functionality.
|
||||||
|
Who: John Stultz <johnstul@us.ibm.com>
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
What: KVM kernel-allocated memory slots
|
What: KVM kernel-allocated memory slots
|
||||||
When: July 2010
|
When: July 2010
|
||||||
Why: Since 2.6.25, kvm supports user-allocated memory slots, which are
|
Why: Since 2.6.25, kvm supports user-allocated memory slots, which are
|
||||||
@@ -589,3 +584,65 @@ Why: Useful in 2003, implementation is a hack.
|
|||||||
Generally invoked by accident today.
|
Generally invoked by accident today.
|
||||||
Seen as doing more harm than good.
|
Seen as doing more harm than good.
|
||||||
Who: Len Brown <len.brown@intel.com>
|
Who: Len Brown <len.brown@intel.com>
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
What: iwlwifi 50XX module parameters
|
||||||
|
When: 2.6.40
|
||||||
|
Why: The "..50" modules parameters were used to configure 5000 series and
|
||||||
|
up devices; different set of module parameters also available for 4965
|
||||||
|
with same functionalities. Consolidate both set into single place
|
||||||
|
in drivers/net/wireless/iwlwifi/iwl-agn.c
|
||||||
|
|
||||||
|
Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
What: iwl4965 alias support
|
||||||
|
When: 2.6.40
|
||||||
|
Why: Internal alias support has been present in module-init-tools for some
|
||||||
|
time, the MODULE_ALIAS("iwl4965") boilerplate aliases can be removed
|
||||||
|
with no impact.
|
||||||
|
|
||||||
|
Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: xt_NOTRACK
|
||||||
|
Files: net/netfilter/xt_NOTRACK.c
|
||||||
|
When: April 2011
|
||||||
|
Why: Superseded by xt_CT
|
||||||
|
Who: Netfilter developer team <netfilter-devel@vger.kernel.org>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: video4linux /dev/vtx teletext API support
|
||||||
|
When: 2.6.35
|
||||||
|
Files: drivers/media/video/saa5246a.c drivers/media/video/saa5249.c
|
||||||
|
include/linux/videotext.h
|
||||||
|
Why: The vtx device nodes have been superseded by vbi device nodes
|
||||||
|
for many years. No applications exist that use the vtx support.
|
||||||
|
Of the two i2c drivers that actually support this API the saa5249
|
||||||
|
has been impossible to use for a year now and no known hardware
|
||||||
|
that supports this device exists. The saa5246a is theoretically
|
||||||
|
supported by the old mxb boards, but it never actually worked.
|
||||||
|
|
||||||
|
In summary: there is no hardware that can use this API and there
|
||||||
|
are no applications actually implementing this API.
|
||||||
|
|
||||||
|
The vtx support still reserves minors 192-223 and we would really
|
||||||
|
like to reuse those for upcoming new functionality. In the unlikely
|
||||||
|
event that new hardware appears that wants to use the functionality
|
||||||
|
provided by the vtx API, then that functionality should be build
|
||||||
|
around the sliced VBI API instead.
|
||||||
|
Who: Hans Verkuil <hverkuil@xs4all.nl>
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
What: IRQF_DISABLED
|
||||||
|
When: 2.6.36
|
||||||
|
Why: The flag is a NOOP as we run interrupt handlers with interrupts disabled
|
||||||
|
Who: Thomas Gleixner <tglx@linutronix.de>
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ prototypes:
|
|||||||
locking rules:
|
locking rules:
|
||||||
All except set_page_dirty may block
|
All except set_page_dirty may block
|
||||||
|
|
||||||
BKL PageLocked(page) i_sem
|
BKL PageLocked(page) i_mutex
|
||||||
writepage: no yes, unlocks (see below)
|
writepage: no yes, unlocks (see below)
|
||||||
readpage: no yes, unlocks
|
readpage: no yes, unlocks
|
||||||
sync_page: no maybe
|
sync_page: no maybe
|
||||||
@@ -429,7 +429,7 @@ check_flags: no
|
|||||||
implementations. If your fs is not using generic_file_llseek, you
|
implementations. If your fs is not using generic_file_llseek, you
|
||||||
need to acquire and release the appropriate locks in your ->llseek().
|
need to acquire and release the appropriate locks in your ->llseek().
|
||||||
For many filesystems, it is probably safe to acquire the inode
|
For many filesystems, it is probably safe to acquire the inode
|
||||||
semaphore. Note some filesystems (i.e. remote ones) provide no
|
mutex. Note some filesystems (i.e. remote ones) provide no
|
||||||
protection for i_size so you will need to use the BKL.
|
protection for i_size so you will need to use the BKL.
|
||||||
|
|
||||||
Note: ext2_release() was *the* source of contention on fs-intensive
|
Note: ext2_release() was *the* source of contention on fs-intensive
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ found to be inadequate, in this case. The Generic Netlink system was
|
|||||||
used for this as raw Netlink would lead to a significant increase in
|
used for this as raw Netlink would lead to a significant increase in
|
||||||
complexity. There's no question that the Generic Netlink system is an
|
complexity. There's no question that the Generic Netlink system is an
|
||||||
elegant solution for common case ioctl functions but it's not a complete
|
elegant solution for common case ioctl functions but it's not a complete
|
||||||
replacement probably because it's primary purpose in life is to be a
|
replacement probably because its primary purpose in life is to be a
|
||||||
message bus implementation rather than specifically an ioctl replacement.
|
message bus implementation rather than specifically an ioctl replacement.
|
||||||
While it would be possible to work around this there is one concern
|
While it would be possible to work around this there is one concern
|
||||||
that lead to the decision to not use it. This is that the autofs
|
that lead to the decision to not use it. This is that the autofs
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ Mount Options
|
|||||||
Specify the IP and/or port the client should bind to locally.
|
Specify the IP and/or port the client should bind to locally.
|
||||||
There is normally not much reason to do this. If the IP is not
|
There is normally not much reason to do this. If the IP is not
|
||||||
specified, the client's IP address is determined by looking at the
|
specified, the client's IP address is determined by looking at the
|
||||||
address it's connection to the monitor originates from.
|
address its connection to the monitor originates from.
|
||||||
|
|
||||||
wsize=X
|
wsize=X
|
||||||
Specify the maximum write size in bytes. By default there is no
|
Specify the maximum write size in bytes. By default there is no
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ You'll want to start heartbeating on a volume which all the nodes in
|
|||||||
your lockspace can access. The easiest way to do this is via
|
your lockspace can access. The easiest way to do this is via
|
||||||
ocfs2_hb_ctl (distributed with ocfs2-tools). Right now it requires
|
ocfs2_hb_ctl (distributed with ocfs2-tools). Right now it requires
|
||||||
that an OCFS2 file system be in place so that it can automatically
|
that an OCFS2 file system be in place so that it can automatically
|
||||||
find it's heartbeat area, though it will eventually support heartbeat
|
find its heartbeat area, though it will eventually support heartbeat
|
||||||
against raw disks.
|
against raw disks.
|
||||||
|
|
||||||
Please see the ocfs2_hb_ctl and mkfs.ocfs2 manual pages distributed
|
Please see the ocfs2_hb_ctl and mkfs.ocfs2 manual pages distributed
|
||||||
|
|||||||
@@ -59,8 +59,19 @@ commit=nrsec (*) Ext3 can be told to sync all its data and metadata
|
|||||||
Setting it to very large values will improve
|
Setting it to very large values will improve
|
||||||
performance.
|
performance.
|
||||||
|
|
||||||
barrier=1 This enables/disables barriers. barrier=0 disables
|
barrier=<0(*)|1> This enables/disables the use of write barriers in
|
||||||
it, barrier=1 enables it.
|
barrier the jbd code. barrier=0 disables, barrier=1 enables.
|
||||||
|
nobarrier (*) This also requires an IO stack which can support
|
||||||
|
barriers, and if jbd gets an error on a barrier
|
||||||
|
write, it will disable again with a warning.
|
||||||
|
Write barriers enforce proper on-disk ordering
|
||||||
|
of journal commits, making volatile disk write caches
|
||||||
|
safe to use, at some performance penalty. If
|
||||||
|
your disks are battery-backed in one way or another,
|
||||||
|
disabling barriers may safely improve performance.
|
||||||
|
The mount options "barrier" and "nobarrier" can
|
||||||
|
also be used to enable or disable barriers, for
|
||||||
|
consistency with other ext3 mount options.
|
||||||
|
|
||||||
orlov (*) This enables the new Orlov block allocator. It is
|
orlov (*) This enables the new Orlov block allocator. It is
|
||||||
enabled by default.
|
enabled by default.
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ flags, it will return EBADR and the contents of fm_flags will contain
|
|||||||
the set of flags which caused the error. If the kernel is compatible
|
the set of flags which caused the error. If the kernel is compatible
|
||||||
with all flags passed, the contents of fm_flags will be unmodified.
|
with all flags passed, the contents of fm_flags will be unmodified.
|
||||||
It is up to userspace to determine whether rejection of a particular
|
It is up to userspace to determine whether rejection of a particular
|
||||||
flag is fatal to it's operation. This scheme is intended to allow the
|
flag is fatal to its operation. This scheme is intended to allow the
|
||||||
fiemap interface to grow in the future but without losing
|
fiemap interface to grow in the future but without losing
|
||||||
compatibility with old software.
|
compatibility with old software.
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ If this flag is set, the kernel will sync the file before mapping extents.
|
|||||||
|
|
||||||
* FIEMAP_FLAG_XATTR
|
* FIEMAP_FLAG_XATTR
|
||||||
If this flag is set, the extents returned will describe the inodes
|
If this flag is set, the extents returned will describe the inodes
|
||||||
extended attribute lookup tree, instead of it's data tree.
|
extended attribute lookup tree, instead of its data tree.
|
||||||
|
|
||||||
|
|
||||||
Extent Mapping
|
Extent Mapping
|
||||||
@@ -89,7 +89,7 @@ struct fiemap_extent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
All offsets and lengths are in bytes and mirror those on disk. It is valid
|
All offsets and lengths are in bytes and mirror those on disk. It is valid
|
||||||
for an extents logical offset to start before the request or it's logical
|
for an extents logical offset to start before the request or its logical
|
||||||
length to extend past the request. Unless FIEMAP_EXTENT_NOT_ALIGNED is
|
length to extend past the request. Unless FIEMAP_EXTENT_NOT_ALIGNED is
|
||||||
returned, fe_logical, fe_physical, and fe_length will be aligned to the
|
returned, fe_logical, fe_physical, and fe_length will be aligned to the
|
||||||
block size of the file system. With the exception of extents flagged as
|
block size of the file system. With the exception of extents flagged as
|
||||||
@@ -125,7 +125,7 @@ been allocated for the file yet.
|
|||||||
|
|
||||||
* FIEMAP_EXTENT_DELALLOC
|
* FIEMAP_EXTENT_DELALLOC
|
||||||
- This will also set FIEMAP_EXTENT_UNKNOWN.
|
- This will also set FIEMAP_EXTENT_UNKNOWN.
|
||||||
Delayed allocation - while there is data for this extent, it's
|
Delayed allocation - while there is data for this extent, its
|
||||||
physical location has not been allocated yet.
|
physical location has not been allocated yet.
|
||||||
|
|
||||||
* FIEMAP_EXTENT_ENCODED
|
* FIEMAP_EXTENT_ENCODED
|
||||||
@@ -159,7 +159,7 @@ Data is located within a meta data block.
|
|||||||
Data is packed into a block with data from other files.
|
Data is packed into a block with data from other files.
|
||||||
|
|
||||||
* FIEMAP_EXTENT_UNWRITTEN
|
* FIEMAP_EXTENT_UNWRITTEN
|
||||||
Unwritten extent - the extent is allocated but it's data has not been
|
Unwritten extent - the extent is allocated but its data has not been
|
||||||
initialized. This indicates the extent's data will be all zero if read
|
initialized. This indicates the extent's data will be all zero if read
|
||||||
through the filesystem but the contents are undefined if read directly from
|
through the filesystem but the contents are undefined if read directly from
|
||||||
the device.
|
the device.
|
||||||
@@ -176,7 +176,7 @@ VFS -> File System Implementation
|
|||||||
|
|
||||||
File systems wishing to support fiemap must implement a ->fiemap callback on
|
File systems wishing to support fiemap must implement a ->fiemap callback on
|
||||||
their inode_operations structure. The fs ->fiemap call is responsible for
|
their inode_operations structure. The fs ->fiemap call is responsible for
|
||||||
defining it's set of supported fiemap flags, and calling a helper function on
|
defining its set of supported fiemap flags, and calling a helper function on
|
||||||
each discovered extent:
|
each discovered extent:
|
||||||
|
|
||||||
struct inode_operations {
|
struct inode_operations {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ Mount options
|
|||||||
'default_permissions'
|
'default_permissions'
|
||||||
|
|
||||||
By default FUSE doesn't check file access permissions, the
|
By default FUSE doesn't check file access permissions, the
|
||||||
filesystem is free to implement it's access policy or leave it to
|
filesystem is free to implement its access policy or leave it to
|
||||||
the underlying file access mechanism (e.g. in case of network
|
the underlying file access mechanism (e.g. in case of network
|
||||||
filesystems). This option enables permission checking, restricting
|
filesystems). This option enables permission checking, restricting
|
||||||
access based on file mode. It is usually useful together with the
|
access based on file mode. It is usually useful together with the
|
||||||
@@ -171,7 +171,7 @@ or may honor them by sending a reply to the _original_ request, with
|
|||||||
the error set to EINTR.
|
the error set to EINTR.
|
||||||
|
|
||||||
It is also possible that there's a race between processing the
|
It is also possible that there's a race between processing the
|
||||||
original request and it's INTERRUPT request. There are two possibilities:
|
original request and its INTERRUPT request. There are two possibilities:
|
||||||
|
|
||||||
1) The INTERRUPT request is processed before the original request is
|
1) The INTERRUPT request is processed before the original request is
|
||||||
processed
|
processed
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Global File System
|
Global File System
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
http://sources.redhat.com/cluster/
|
http://sources.redhat.com/cluster/wiki/
|
||||||
|
|
||||||
GFS is a cluster file system. It allows a cluster of computers to
|
GFS is a cluster file system. It allows a cluster of computers to
|
||||||
simultaneously use a block device that is shared between them (with FC,
|
simultaneously use a block device that is shared between them (with FC,
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ to analyze or change OS2SYS.INI.
|
|||||||
Codepages
|
Codepages
|
||||||
|
|
||||||
HPFS can contain several uppercasing tables for several codepages and each
|
HPFS can contain several uppercasing tables for several codepages and each
|
||||||
file has a pointer to codepage it's name is in. However OS/2 was created in
|
file has a pointer to codepage its name is in. However OS/2 was created in
|
||||||
America where people don't care much about codepages and so multiple codepages
|
America where people don't care much about codepages and so multiple codepages
|
||||||
support is quite buggy. I have Czech OS/2 working in codepage 852 on my disk.
|
support is quite buggy. I have Czech OS/2 working in codepage 852 on my disk.
|
||||||
Once I booted English OS/2 working in cp 850 and I created a file on my 852
|
Once I booted English OS/2 working in cp 850 and I created a file on my 852
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Levels
|
|||||||
------
|
------
|
||||||
|
|
||||||
Garbage collection (GC) may fail if all data is written
|
Garbage collection (GC) may fail if all data is written
|
||||||
indiscriminately. One requirement of GC is that data is seperated
|
indiscriminately. One requirement of GC is that data is separated
|
||||||
roughly according to the distance between the tree root and the data.
|
roughly according to the distance between the tree root and the data.
|
||||||
Effectively that means all file data is on level 0, indirect blocks
|
Effectively that means all file data is on level 0, indirect blocks
|
||||||
are on levels 1, 2, 3 4 or 5 for 1x, 2x, 3x, 4x or 5x indirect blocks,
|
are on levels 1, 2, 3 4 or 5 for 1x, 2x, 3x, 4x or 5x indirect blocks,
|
||||||
@@ -67,7 +67,7 @@ respectively. Inode file data is on level 6 for the inodes and 7-11
|
|||||||
for indirect blocks.
|
for indirect blocks.
|
||||||
|
|
||||||
Each segment contains objects of a single level only. As a result,
|
Each segment contains objects of a single level only. As a result,
|
||||||
each level requires its own seperate segment to be open for writing.
|
each level requires its own separate segment to be open for writing.
|
||||||
|
|
||||||
Inode File
|
Inode File
|
||||||
----------
|
----------
|
||||||
@@ -106,9 +106,9 @@ Vim
|
|||||||
---
|
---
|
||||||
|
|
||||||
By cleverly predicting the life time of data, it is possible to
|
By cleverly predicting the life time of data, it is possible to
|
||||||
seperate long-living data from short-living data and thereby reduce
|
separate long-living data from short-living data and thereby reduce
|
||||||
the GC overhead later. Each type of distinc life expectency (vim) can
|
the GC overhead later. Each type of distinc life expectency (vim) can
|
||||||
have a seperate segment open for writing. Each (level, vim) tupel can
|
have a separate segment open for writing. Each (level, vim) tupel can
|
||||||
be open just once. If an open segment with unknown vim is encountered
|
be open just once. If an open segment with unknown vim is encountered
|
||||||
at mount time, it is closed and ignored henceforth.
|
at mount time, it is closed and ignored henceforth.
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ NS*| OPENATTR | OPT | | Section 18.17 |
|
|||||||
| READ | REQ | | Section 18.22 |
|
| READ | REQ | | Section 18.22 |
|
||||||
| READDIR | REQ | | Section 18.23 |
|
| READDIR | REQ | | Section 18.23 |
|
||||||
| READLINK | OPT | | Section 18.24 |
|
| READLINK | OPT | | Section 18.24 |
|
||||||
NS | RECLAIM_COMPLETE | REQ | | Section 18.51 |
|
| RECLAIM_COMPLETE | REQ | | Section 18.51 |
|
||||||
| RELEASE_LOCKOWNER | MNI | | N/A |
|
| RELEASE_LOCKOWNER | MNI | | N/A |
|
||||||
| REMOVE | REQ | | Section 18.25 |
|
| REMOVE | REQ | | Section 18.25 |
|
||||||
| RENAME | REQ | | Section 18.26 |
|
| RENAME | REQ | | Section 18.26 |
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ failed lookup meant a definite 'no'.
|
|||||||
request/response format
|
request/response format
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
While each cache is free to use it's own format for requests
|
While each cache is free to use its own format for requests
|
||||||
and responses over channel, the following is recommended as
|
and responses over channel, the following is recommended as
|
||||||
appropriate and support routines are available to help:
|
appropriate and support routines are available to help:
|
||||||
Each request or response record should be printable ASCII
|
Each request or response record should be printable ASCII
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ NILFS2 supports the following mount options:
|
|||||||
(*) == default
|
(*) == default
|
||||||
|
|
||||||
nobarrier Disables barriers.
|
nobarrier Disables barriers.
|
||||||
errors=continue(*) Keep going on a filesystem error.
|
errors=continue Keep going on a filesystem error.
|
||||||
errors=remount-ro Remount the filesystem read-only on an error.
|
errors=remount-ro(*) Remount the filesystem read-only on an error.
|
||||||
errors=panic Panic and halt the machine if an error occurs.
|
errors=panic Panic and halt the machine if an error occurs.
|
||||||
cp=n Specify the checkpoint-number of the snapshot to be
|
cp=n Specify the checkpoint-number of the snapshot to be
|
||||||
mounted. Checkpoints and snapshots are listed by lscp
|
mounted. Checkpoints and snapshots are listed by lscp
|
||||||
|
|||||||
@@ -80,3 +80,10 @@ user_xattr (*) Enables Extended User Attributes.
|
|||||||
nouser_xattr Disables Extended User Attributes.
|
nouser_xattr Disables Extended User Attributes.
|
||||||
acl Enables POSIX Access Control Lists support.
|
acl Enables POSIX Access Control Lists support.
|
||||||
noacl (*) Disables POSIX Access Control Lists support.
|
noacl (*) Disables POSIX Access Control Lists support.
|
||||||
|
resv_level=2 (*) Set how agressive allocation reservations will be.
|
||||||
|
Valid values are between 0 (reservations off) to 8
|
||||||
|
(maximum space for reservations).
|
||||||
|
dir_resv_level= (*) By default, directory reservations will scale with file
|
||||||
|
reservations - users should rarely need to change this
|
||||||
|
value. If allocation reservations are turned off, this
|
||||||
|
option will have no effect.
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
|
|||||||
cgtime guest time of the task children in jiffies
|
cgtime guest time of the task children in jiffies
|
||||||
..............................................................................
|
..............................................................................
|
||||||
|
|
||||||
The /proc/PID/map file containing the currently mapped memory regions and
|
The /proc/PID/maps file containing the currently mapped memory regions and
|
||||||
their access permissions.
|
their access permissions.
|
||||||
|
|
||||||
The format is:
|
The format is:
|
||||||
@@ -316,7 +316,7 @@ address perms offset dev inode pathname
|
|||||||
08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test
|
08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test
|
||||||
0804a000-0806b000 rw-p 00000000 00:00 0 [heap]
|
0804a000-0806b000 rw-p 00000000 00:00 0 [heap]
|
||||||
a7cb1000-a7cb2000 ---p 00000000 00:00 0
|
a7cb1000-a7cb2000 ---p 00000000 00:00 0
|
||||||
a7cb2000-a7eb2000 rw-p 00000000 00:00 0 [threadstack:001ff4b4]
|
a7cb2000-a7eb2000 rw-p 00000000 00:00 0
|
||||||
a7eb2000-a7eb3000 ---p 00000000 00:00 0
|
a7eb2000-a7eb3000 ---p 00000000 00:00 0
|
||||||
a7eb3000-a7ed5000 rw-p 00000000 00:00 0
|
a7eb3000-a7ed5000 rw-p 00000000 00:00 0
|
||||||
a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6
|
a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6
|
||||||
@@ -352,7 +352,6 @@ is not associated with a file:
|
|||||||
[stack] = the stack of the main process
|
[stack] = the stack of the main process
|
||||||
[vdso] = the "virtual dynamic shared object",
|
[vdso] = the "virtual dynamic shared object",
|
||||||
the kernel system call handler
|
the kernel system call handler
|
||||||
[threadstack:xxxxxxxx] = the stack of the thread, xxxxxxxx is the stack size
|
|
||||||
|
|
||||||
or if empty, the mapping is anonymous.
|
or if empty, the mapping is anonymous.
|
||||||
|
|
||||||
@@ -566,6 +565,10 @@ The default_smp_affinity mask applies to all non-active IRQs, which are the
|
|||||||
IRQs which have not yet been allocated/activated, and hence which lack a
|
IRQs which have not yet been allocated/activated, and hence which lack a
|
||||||
/proc/irq/[0-9]* directory.
|
/proc/irq/[0-9]* directory.
|
||||||
|
|
||||||
|
The node file on an SMP system shows the node to which the device using the IRQ
|
||||||
|
reports itself as being attached. This hardware locality information does not
|
||||||
|
include information about any possible driver locality preference.
|
||||||
|
|
||||||
prof_cpu_mask specifies which CPUs are to be profiled by the system wide
|
prof_cpu_mask specifies which CPUs are to be profiled by the system wide
|
||||||
profiler. Default value is ffffffff (all cpus).
|
profiler. Default value is ffffffff (all cpus).
|
||||||
|
|
||||||
@@ -965,7 +968,7 @@ your system and how much traffic was routed over those devices:
|
|||||||
...] 1375103 17405 0 0 0 0 0 0
|
...] 1375103 17405 0 0 0 0 0 0
|
||||||
...] 1703981 5535 0 0 0 3 0 0
|
...] 1703981 5535 0 0 0 3 0 0
|
||||||
|
|
||||||
In addition, each Channel Bond interface has it's own directory. For
|
In addition, each Channel Bond interface has its own directory. For
|
||||||
example, the bond0 device will have a directory called /proc/net/bond0/.
|
example, the bond0 device will have a directory called /proc/net/bond0/.
|
||||||
It will contain information that is specific to that bond, such as the
|
It will contain information that is specific to that bond, such as the
|
||||||
current slaves of the bond, the link status of the slaves, and how
|
current slaves of the bond, the link status of the slaves, and how
|
||||||
@@ -1362,7 +1365,7 @@ been accounted as having caused 1MB of write.
|
|||||||
In other words: The number of bytes which this process caused to not happen,
|
In other words: The number of bytes which this process caused to not happen,
|
||||||
by truncating pagecache. A task can cause "negative" IO too. If this task
|
by truncating pagecache. A task can cause "negative" IO too. If this task
|
||||||
truncates some dirty pagecache, some IO which another task has been accounted
|
truncates some dirty pagecache, some IO which another task has been accounted
|
||||||
for (in it's write_bytes) will not be happening. We _could_ just subtract that
|
for (in its write_bytes) will not be happening. We _could_ just subtract that
|
||||||
from the truncating task's write_bytes, but there is information loss in doing
|
from the truncating task's write_bytes, but there is information loss in doing
|
||||||
that.
|
that.
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ protocol used by Windows for Workgroups, Windows 95 and Windows NT.
|
|||||||
Smbfs was inspired by Samba, the program written by Andrew Tridgell
|
Smbfs was inspired by Samba, the program written by Andrew Tridgell
|
||||||
that turns any Unix host into a file server for DOS or Windows clients.
|
that turns any Unix host into a file server for DOS or Windows clients.
|
||||||
|
|
||||||
Smbfs is a SMB client, but uses parts of samba for it's operation. For
|
Smbfs is a SMB client, but uses parts of samba for its operation. For
|
||||||
more info on samba, including documentation, please go to
|
more info on samba, including documentation, please go to
|
||||||
http://www.samba.org/ and then on to your nearest mirror.
|
http://www.samba.org/ and then on to your nearest mirror.
|
||||||
|
|||||||
42
Documentation/filesystems/sysfs-tagging.txt
Normal file
42
Documentation/filesystems/sysfs-tagging.txt
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
Sysfs tagging
|
||||||
|
-------------
|
||||||
|
|
||||||
|
(Taken almost verbatim from Eric Biederman's netns tagging patch
|
||||||
|
commit msg)
|
||||||
|
|
||||||
|
The problem. Network devices show up in sysfs and with the network
|
||||||
|
namespace active multiple devices with the same name can show up in
|
||||||
|
the same directory, ouch!
|
||||||
|
|
||||||
|
To avoid that problem and allow existing applications in network
|
||||||
|
namespaces to see the same interface that is currently presented in
|
||||||
|
sysfs, sysfs now has tagging directory support.
|
||||||
|
|
||||||
|
By using the network namespace pointers as tags to separate out the
|
||||||
|
the sysfs directory entries we ensure that we don't have conflicts
|
||||||
|
in the directories and applications only see a limited set of
|
||||||
|
the network devices.
|
||||||
|
|
||||||
|
Each sysfs directory entry may be tagged with zero or one
|
||||||
|
namespaces. A sysfs_dirent is augmented with a void *s_ns. If a
|
||||||
|
directory entry is tagged, then sysfs_dirent->s_flags will have a
|
||||||
|
flag between KOBJ_NS_TYPE_NONE and KOBJ_NS_TYPES, and s_ns will
|
||||||
|
point to the namespace to which it belongs.
|
||||||
|
|
||||||
|
Each sysfs superblock's sysfs_super_info contains an array void
|
||||||
|
*ns[KOBJ_NS_TYPES]. When a a task in a tagging namespace
|
||||||
|
kobj_nstype first mounts sysfs, a new superblock is created. It
|
||||||
|
will be differentiated from other sysfs mounts by having its
|
||||||
|
s_fs_info->ns[kobj_nstype] set to the new namespace. Note that
|
||||||
|
through bind mounting and mounts propagation, a task can easily view
|
||||||
|
the contents of other namespaces' sysfs mounts. Therefore, when a
|
||||||
|
namespace exits, it will call kobj_ns_exit() to invalidate any
|
||||||
|
sysfs_dirent->s_ns pointers pointing to it.
|
||||||
|
|
||||||
|
Users of this interface:
|
||||||
|
- define a type in the kobj_ns_type enumeration.
|
||||||
|
- call kobj_ns_type_register() with its kobj_ns_type_operations which has
|
||||||
|
- current_ns() which returns current's namespace
|
||||||
|
- netlink_ns() which returns a socket's namespace
|
||||||
|
- initial_ns() which returns the initial namesapce
|
||||||
|
- call kobj_ns_exit() when an individual tag is no longer valid
|
||||||
@@ -72,7 +72,7 @@ structure (this is the kernel-side implementation of file
|
|||||||
descriptors). The freshly allocated file structure is initialized with
|
descriptors). The freshly allocated file structure is initialized with
|
||||||
a pointer to the dentry and a set of file operation member functions.
|
a pointer to the dentry and a set of file operation member functions.
|
||||||
These are taken from the inode data. The open() file method is then
|
These are taken from the inode data. The open() file method is then
|
||||||
called so the specific filesystem implementation can do it's work. You
|
called so the specific filesystem implementation can do its work. You
|
||||||
can see that this is another switch performed by the VFS. The file
|
can see that this is another switch performed by the VFS. The file
|
||||||
structure is placed into the file descriptor table for the process.
|
structure is placed into the file descriptor table for the process.
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ temperature configuration points:
|
|||||||
|
|
||||||
There are three PWM outputs. The LM85 datasheet suggests that the
|
There are three PWM outputs. The LM85 datasheet suggests that the
|
||||||
pwm3 output control both fan3 and fan4. Each PWM can be individually
|
pwm3 output control both fan3 and fan4. Each PWM can be individually
|
||||||
configured and assigned to a zone for it's control value. Each PWM can be
|
configured and assigned to a zone for its control value. Each PWM can be
|
||||||
configured individually according to the following options.
|
configured individually according to the following options.
|
||||||
|
|
||||||
* pwm#_auto_pwm_min - this specifies the PWM value for temp#_auto_temp_off
|
* pwm#_auto_pwm_min - this specifies the PWM value for temp#_auto_temp_off
|
||||||
|
|||||||
@@ -27,7 +27,13 @@ Authors:
|
|||||||
Module Parameters
|
Module Parameters
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
None.
|
* disable_features (bit vector)
|
||||||
|
Disable selected features normally supported by the device. This makes it
|
||||||
|
possible to work around possible driver or hardware bugs if the feature in
|
||||||
|
question doesn't work as intended for whatever reason. Bit values:
|
||||||
|
1 disable SMBus PEC
|
||||||
|
2 disable the block buffer
|
||||||
|
8 disable the I2C block read functionality
|
||||||
|
|
||||||
|
|
||||||
Description
|
Description
|
||||||
|
|||||||
@@ -74,6 +74,11 @@ structure at all. You should use this to keep device-specific data.
|
|||||||
/* retrieve the value */
|
/* retrieve the value */
|
||||||
void *i2c_get_clientdata(const struct i2c_client *client);
|
void *i2c_get_clientdata(const struct i2c_client *client);
|
||||||
|
|
||||||
|
Note that starting with kernel 2.6.34, you don't have to set the `data' field
|
||||||
|
to NULL in remove() or if probe() failed anymore. The i2c-core does this
|
||||||
|
automatically on these occasions. Those are also the only times the core will
|
||||||
|
touch this field.
|
||||||
|
|
||||||
|
|
||||||
Accessing the client
|
Accessing the client
|
||||||
====================
|
====================
|
||||||
|
|||||||
@@ -333,14 +333,14 @@ byte 0:
|
|||||||
byte 1:
|
byte 1:
|
||||||
|
|
||||||
bit 7 6 5 4 3 2 1 0
|
bit 7 6 5 4 3 2 1 0
|
||||||
x15 x14 x13 x12 x11 x10 x9 x8
|
. . . . . x10 x9 x8
|
||||||
|
|
||||||
byte 2:
|
byte 2:
|
||||||
|
|
||||||
bit 7 6 5 4 3 2 1 0
|
bit 7 6 5 4 3 2 1 0
|
||||||
x7 x6 x5 x4 x4 x2 x1 x0
|
x7 x6 x5 x4 x4 x2 x1 x0
|
||||||
|
|
||||||
x15..x0 = absolute x value (horizontal)
|
x10..x0 = absolute x value (horizontal)
|
||||||
|
|
||||||
byte 3:
|
byte 3:
|
||||||
|
|
||||||
@@ -350,14 +350,14 @@ byte 3:
|
|||||||
byte 4:
|
byte 4:
|
||||||
|
|
||||||
bit 7 6 5 4 3 2 1 0
|
bit 7 6 5 4 3 2 1 0
|
||||||
y15 y14 y13 y12 y11 y10 y8 y8
|
. . . . . . y9 y8
|
||||||
|
|
||||||
byte 5:
|
byte 5:
|
||||||
|
|
||||||
bit 7 6 5 4 3 2 1 0
|
bit 7 6 5 4 3 2 1 0
|
||||||
y7 y6 y5 y4 y3 y2 y1 y0
|
y7 y6 y5 y4 y3 y2 y1 y0
|
||||||
|
|
||||||
y15..y0 = absolute y value (vertical)
|
y9..y0 = absolute y value (vertical)
|
||||||
|
|
||||||
|
|
||||||
4.2.2 Two finger touch
|
4.2.2 Two finger touch
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ for the port of the SoundFusion is supported by the cs461x.c module.
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The Live! has a special PCI gameport, which, although it doesn't provide
|
The Live! has a special PCI gameport, which, although it doesn't provide
|
||||||
any "Enhanced" stuff like 4DWave and friends, is quite a bit faster than
|
any "Enhanced" stuff like 4DWave and friends, is quite a bit faster than
|
||||||
it's ISA counterparts. It also requires special support, hence the
|
its ISA counterparts. It also requires special support, hence the
|
||||||
emu10k1-gp.c module for it instead of the normal ns558.c one.
|
emu10k1-gp.c module for it instead of the normal ns558.c one.
|
||||||
|
|
||||||
3.15 SoundBlaster 64 and 128 - ES1370 and ES1371, ESS Solo1 and S3 SonicVibes
|
3.15 SoundBlaster 64 and 128 - ES1370 and ES1371, ESS Solo1 and S3 SonicVibes
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ o Tboot then applies an (optional) user-defined launch policy to
|
|||||||
o Tboot adjusts the e820 table provided by the bootloader to reserve
|
o Tboot adjusts the e820 table provided by the bootloader to reserve
|
||||||
its own location in memory as well as to reserve certain other
|
its own location in memory as well as to reserve certain other
|
||||||
TXT-related regions.
|
TXT-related regions.
|
||||||
o As part of it's launch, tboot DMA protects all of RAM (using the
|
o As part of its launch, tboot DMA protects all of RAM (using the
|
||||||
VT-d PMRs). Thus, the kernel must be booted with 'intel_iommu=on'
|
VT-d PMRs). Thus, the kernel must be booted with 'intel_iommu=on'
|
||||||
in order to remove this blanket protection and use VT-d's
|
in order to remove this blanket protection and use VT-d's
|
||||||
page-level protection.
|
page-level protection.
|
||||||
@@ -161,13 +161,15 @@ o In order to put a system into any of the sleep states after a TXT
|
|||||||
has been restored, it will restore the TPM PCRs and then
|
has been restored, it will restore the TPM PCRs and then
|
||||||
transfer control back to the kernel's S3 resume vector.
|
transfer control back to the kernel's S3 resume vector.
|
||||||
In order to preserve system integrity across S3, the kernel
|
In order to preserve system integrity across S3, the kernel
|
||||||
provides tboot with a set of memory ranges (kernel
|
provides tboot with a set of memory ranges (RAM and RESERVED_KERN
|
||||||
code/data/bss, S3 resume code, and AP trampoline) that tboot
|
in the e820 table, but not any memory that BIOS might alter over
|
||||||
will calculate a MAC (message authentication code) over and then
|
the S3 transition) that tboot will calculate a MAC (message
|
||||||
seal with the TPM. On resume and once the measured environment
|
authentication code) over and then seal with the TPM. On resume
|
||||||
has been re-established, tboot will re-calculate the MAC and
|
and once the measured environment has been re-established, tboot
|
||||||
verify it against the sealed value. Tboot's policy determines
|
will re-calculate the MAC and verify it against the sealed value.
|
||||||
what happens if the verification fails.
|
Tboot's policy determines what happens if the verification fails.
|
||||||
|
Note that the c/s 194 of tboot which has the new MAC code supports
|
||||||
|
this.
|
||||||
|
|
||||||
That's pretty much it for TXT support.
|
That's pretty much it for TXT support.
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ Expressions are listed in decreasing order of precedence.
|
|||||||
(7) Returns the result of max(/expr/, /expr/).
|
(7) Returns the result of max(/expr/, /expr/).
|
||||||
|
|
||||||
An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
|
An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
|
||||||
respectively for calculations). A menu entry becomes visible when it's
|
respectively for calculations). A menu entry becomes visible when its
|
||||||
expression evaluates to 'm' or 'y'.
|
expression evaluates to 'm' or 'y'.
|
||||||
|
|
||||||
There are two types of symbols: constant and non-constant symbols.
|
There are two types of symbols: constant and non-constant symbols.
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ Environment variables for 'silentoldconfig'
|
|||||||
KCONFIG_NOSILENTUPDATE
|
KCONFIG_NOSILENTUPDATE
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
If this variable has a non-blank value, it prevents silent kernel
|
If this variable has a non-blank value, it prevents silent kernel
|
||||||
config udpates (requires explicit updates).
|
config updates (requires explicit updates).
|
||||||
|
|
||||||
KCONFIG_AUTOCONFIG
|
KCONFIG_AUTOCONFIG
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
Author: Ingo Molnar, Gadi Oxman and Miguel de Icaza.
|
Author: Ingo Molnar, Gadi Oxman and Miguel de Icaza.
|
||||||
URL: http://www.linuxjournal.com/article.php?sid=2391
|
URL: http://www.linuxjournal.com/article.php?sid=2391
|
||||||
Keywords: RAID, MD driver.
|
Keywords: RAID, MD driver.
|
||||||
Description: Linux Journal Kernel Korner article. Here is it's
|
Description: Linux Journal Kernel Korner article. Here is its
|
||||||
abstract: "A description of the implementation of the RAID-1,
|
abstract: "A description of the implementation of the RAID-1,
|
||||||
RAID-4 and RAID-5 personalities of the MD device driver in the
|
RAID-4 and RAID-5 personalities of the MD device driver in the
|
||||||
Linux kernel, providing users with high performance and reliable,
|
Linux kernel, providing users with high performance and reliable,
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
URL: http://www.linuxjournal.com/article.php?sid=1219
|
URL: http://www.linuxjournal.com/article.php?sid=1219
|
||||||
Keywords: device driver, module, loading/unloading modules,
|
Keywords: device driver, module, loading/unloading modules,
|
||||||
allocating resources.
|
allocating resources.
|
||||||
Description: Linux Journal Kernel Korner article. Here is it's
|
Description: Linux Journal Kernel Korner article. Here is its
|
||||||
abstract: "This is the first of a series of four articles
|
abstract: "This is the first of a series of four articles
|
||||||
co-authored by Alessandro Rubini and Georg Zezchwitz which present
|
co-authored by Alessandro Rubini and Georg Zezchwitz which present
|
||||||
a practical approach to writing Linux device drivers as kernel
|
a practical approach to writing Linux device drivers as kernel
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
Keywords: character driver, init_module, clean_up module,
|
Keywords: character driver, init_module, clean_up module,
|
||||||
autodetection, mayor number, minor number, file operations,
|
autodetection, mayor number, minor number, file operations,
|
||||||
open(), close().
|
open(), close().
|
||||||
Description: Linux Journal Kernel Korner article. Here is it's
|
Description: Linux Journal Kernel Korner article. Here is its
|
||||||
abstract: "This article, the second of four, introduces part of
|
abstract: "This article, the second of four, introduces part of
|
||||||
the actual code to create custom module implementing a character
|
the actual code to create custom module implementing a character
|
||||||
device driver. It describes the code for module initialization and
|
device driver. It describes the code for module initialization and
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
URL: http://www.linuxjournal.com/article.php?sid=1221
|
URL: http://www.linuxjournal.com/article.php?sid=1221
|
||||||
Keywords: read(), write(), select(), ioctl(), blocking/non
|
Keywords: read(), write(), select(), ioctl(), blocking/non
|
||||||
blocking mode, interrupt handler.
|
blocking mode, interrupt handler.
|
||||||
Description: Linux Journal Kernel Korner article. Here is it's
|
Description: Linux Journal Kernel Korner article. Here is its
|
||||||
abstract: "This article, the third of four on writing character
|
abstract: "This article, the third of four on writing character
|
||||||
device drivers, introduces concepts of reading, writing, and using
|
device drivers, introduces concepts of reading, writing, and using
|
||||||
ioctl-calls".
|
ioctl-calls".
|
||||||
@@ -161,7 +161,7 @@
|
|||||||
Author: Alessandro Rubini and Georg v. Zezschwitz.
|
Author: Alessandro Rubini and Georg v. Zezschwitz.
|
||||||
URL: http://www.linuxjournal.com/article.php?sid=1222
|
URL: http://www.linuxjournal.com/article.php?sid=1222
|
||||||
Keywords: interrupts, irqs, DMA, bottom halves, task queues.
|
Keywords: interrupts, irqs, DMA, bottom halves, task queues.
|
||||||
Description: Linux Journal Kernel Korner article. Here is it's
|
Description: Linux Journal Kernel Korner article. Here is its
|
||||||
abstract: "This is the fourth in a series of articles about
|
abstract: "This is the fourth in a series of articles about
|
||||||
writing character device drivers as loadable kernel modules. This
|
writing character device drivers as loadable kernel modules. This
|
||||||
month, we further investigate the field of interrupt handling.
|
month, we further investigate the field of interrupt handling.
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ parameter is applicable:
|
|||||||
ISAPNP ISA PnP code is enabled.
|
ISAPNP ISA PnP code is enabled.
|
||||||
ISDN Appropriate ISDN support is enabled.
|
ISDN Appropriate ISDN support is enabled.
|
||||||
JOY Appropriate joystick support is enabled.
|
JOY Appropriate joystick support is enabled.
|
||||||
|
KGDB Kernel debugger support is enabled.
|
||||||
KVM Kernel Virtual Machine support is enabled.
|
KVM Kernel Virtual Machine support is enabled.
|
||||||
LIBATA Libata driver is enabled
|
LIBATA Libata driver is enabled
|
||||||
LP Printer support is enabled.
|
LP Printer support is enabled.
|
||||||
@@ -99,6 +100,7 @@ parameter is applicable:
|
|||||||
SWSUSP Software suspend (hibernation) is enabled.
|
SWSUSP Software suspend (hibernation) is enabled.
|
||||||
SUSPEND System suspend states are enabled.
|
SUSPEND System suspend states are enabled.
|
||||||
FTRACE Function tracing enabled.
|
FTRACE Function tracing enabled.
|
||||||
|
TPM TPM drivers are enabled.
|
||||||
TS Appropriate touchscreen support is enabled.
|
TS Appropriate touchscreen support is enabled.
|
||||||
UMS USB Mass Storage support is enabled.
|
UMS USB Mass Storage support is enabled.
|
||||||
USB USB support is enabled.
|
USB USB support is enabled.
|
||||||
@@ -151,6 +153,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||||||
strict -- Be less tolerant of platforms that are not
|
strict -- Be less tolerant of platforms that are not
|
||||||
strictly ACPI specification compliant.
|
strictly ACPI specification compliant.
|
||||||
rsdt -- prefer RSDT over (default) XSDT
|
rsdt -- prefer RSDT over (default) XSDT
|
||||||
|
copy_dsdt -- copy DSDT to memory
|
||||||
|
|
||||||
See also Documentation/power/pm.txt, pci=noacpi
|
See also Documentation/power/pm.txt, pci=noacpi
|
||||||
|
|
||||||
@@ -324,6 +327,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||||||
they are unmapped. Otherwise they are
|
they are unmapped. Otherwise they are
|
||||||
flushed before they will be reused, which
|
flushed before they will be reused, which
|
||||||
is a lot of faster
|
is a lot of faster
|
||||||
|
off - do not initialize any AMD IOMMU found in
|
||||||
|
the system
|
||||||
|
|
||||||
amijoy.map= [HW,JOY] Amiga joystick support
|
amijoy.map= [HW,JOY] Amiga joystick support
|
||||||
Map of devices attached to JOY0DAT and JOY1DAT
|
Map of devices attached to JOY0DAT and JOY1DAT
|
||||||
@@ -708,6 +713,12 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||||||
The VGA output is eventually overwritten by the real
|
The VGA output is eventually overwritten by the real
|
||||||
console.
|
console.
|
||||||
|
|
||||||
|
ekgdboc= [X86,KGDB] Allow early kernel console debugging
|
||||||
|
ekgdboc=kbd
|
||||||
|
|
||||||
|
This is desgined to be used in conjunction with
|
||||||
|
the boot argument: earlyprintk=vga
|
||||||
|
|
||||||
eata= [HW,SCSI]
|
eata= [HW,SCSI]
|
||||||
|
|
||||||
edd= [EDD]
|
edd= [EDD]
|
||||||
@@ -784,8 +795,12 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||||||
as early as possible in order to facilitate early
|
as early as possible in order to facilitate early
|
||||||
boot debugging.
|
boot debugging.
|
||||||
|
|
||||||
ftrace_dump_on_oops
|
ftrace_dump_on_oops[=orig_cpu]
|
||||||
[FTRACE] will dump the trace buffers on oops.
|
[FTRACE] will dump the trace buffers on oops.
|
||||||
|
If no parameter is passed, ftrace will dump
|
||||||
|
buffers of all CPUs, but if you pass orig_cpu, it will
|
||||||
|
dump only the buffer of the CPU that triggered the
|
||||||
|
oops.
|
||||||
|
|
||||||
ftrace_filter=[function-list]
|
ftrace_filter=[function-list]
|
||||||
[FTRACE] Limit the functions traced by the function
|
[FTRACE] Limit the functions traced by the function
|
||||||
@@ -1112,10 +1127,26 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||||||
use the HighMem zone if it exists, and the Normal
|
use the HighMem zone if it exists, and the Normal
|
||||||
zone if it does not.
|
zone if it does not.
|
||||||
|
|
||||||
kgdboc= [HW] kgdb over consoles.
|
kgdbdbgp= [KGDB,HW] kgdb over EHCI usb debug port.
|
||||||
Requires a tty driver that supports console polling.
|
Format: <Controller#>[,poll interval]
|
||||||
(only serial supported for now)
|
The controller # is the number of the ehci usb debug
|
||||||
Format: <serial_device>[,baud]
|
port as it is probed via PCI. The poll interval is
|
||||||
|
optional and is the number seconds in between
|
||||||
|
each poll cycle to the debug port in case you need
|
||||||
|
the functionality for interrupting the kernel with
|
||||||
|
gdb or control-c on the dbgp connection. When
|
||||||
|
not using this parameter you use sysrq-g to break into
|
||||||
|
the kernel debugger.
|
||||||
|
|
||||||
|
kgdboc= [KGDB,HW] kgdb over consoles.
|
||||||
|
Requires a tty driver that supports console polling,
|
||||||
|
or a supported polling keyboard driver (non-usb).
|
||||||
|
Serial only format: <serial_device>[,baud]
|
||||||
|
keyboard only format: kbd
|
||||||
|
keyboard and serial format: kbd,<serial_device>[,baud]
|
||||||
|
|
||||||
|
kgdbwait [KGDB] Stop kernel execution and enter the
|
||||||
|
kernel debugger at the earliest opportunity.
|
||||||
|
|
||||||
kmac= [MIPS] korina ethernet MAC address.
|
kmac= [MIPS] korina ethernet MAC address.
|
||||||
Configure the RouterBoard 532 series on-chip
|
Configure the RouterBoard 532 series on-chip
|
||||||
@@ -2610,6 +2641,15 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||||||
|
|
||||||
tp720= [HW,PS2]
|
tp720= [HW,PS2]
|
||||||
|
|
||||||
|
tpm_suspend_pcr=[HW,TPM]
|
||||||
|
Format: integer pcr id
|
||||||
|
Specify that at suspend time, the tpm driver
|
||||||
|
should extend the specified pcr with zeros,
|
||||||
|
as a workaround for some chips which fail to
|
||||||
|
flush the last written pcr on TPM_SaveState.
|
||||||
|
This will guarantee that all the other pcrs
|
||||||
|
are saved.
|
||||||
|
|
||||||
trace_buf_size=nn[KMG]
|
trace_buf_size=nn[KMG]
|
||||||
[FTRACE] will set tracing buffer size.
|
[FTRACE] will set tracing buffer size.
|
||||||
|
|
||||||
|
|||||||
@@ -165,8 +165,8 @@ the user entry_handler invocation is also skipped.
|
|||||||
|
|
||||||
1.4 How Does Jump Optimization Work?
|
1.4 How Does Jump Optimization Work?
|
||||||
|
|
||||||
If you configured your kernel with CONFIG_OPTPROBES=y (currently
|
If your kernel is built with CONFIG_OPTPROBES=y (currently this flag
|
||||||
this option is supported on x86/x86-64, non-preemptive kernel) and
|
is automatically set 'y' on x86/x86-64, non-preemptive kernel) and
|
||||||
the "debug.kprobes_optimization" kernel parameter is set to 1 (see
|
the "debug.kprobes_optimization" kernel parameter is set to 1 (see
|
||||||
sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
|
sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
|
||||||
instruction instead of a breakpoint instruction at each probepoint.
|
instruction instead of a breakpoint instruction at each probepoint.
|
||||||
@@ -271,8 +271,6 @@ tweak the kernel's execution path, you need to suppress optimization,
|
|||||||
using one of the following techniques:
|
using one of the following techniques:
|
||||||
- Specify an empty function for the kprobe's post_handler or break_handler.
|
- Specify an empty function for the kprobe's post_handler or break_handler.
|
||||||
or
|
or
|
||||||
- Config CONFIG_OPTPROBES=n.
|
|
||||||
or
|
|
||||||
- Execute 'sysctl -w debug.kprobes_optimization=n'
|
- Execute 'sysctl -w debug.kprobes_optimization=n'
|
||||||
|
|
||||||
2. Architectures Supported
|
2. Architectures Supported
|
||||||
@@ -307,10 +305,6 @@ it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
|
|||||||
so you can use "objdump -d -l vmlinux" to see the source-to-object
|
so you can use "objdump -d -l vmlinux" to see the source-to-object
|
||||||
code mapping.
|
code mapping.
|
||||||
|
|
||||||
If you want to reduce probing overhead, set "Kprobes jump optimization
|
|
||||||
support" (CONFIG_OPTPROBES) to "y". You can find this option under the
|
|
||||||
"Kprobes" line.
|
|
||||||
|
|
||||||
4. API Reference
|
4. API Reference
|
||||||
|
|
||||||
The Kprobes API includes a "register" function and an "unregister"
|
The Kprobes API includes a "register" function and an "unregister"
|
||||||
@@ -332,7 +326,7 @@ occurs during execution of kp->pre_handler or kp->post_handler,
|
|||||||
or during single-stepping of the probed instruction, Kprobes calls
|
or during single-stepping of the probed instruction, Kprobes calls
|
||||||
kp->fault_handler. Any or all handlers can be NULL. If kp->flags
|
kp->fault_handler. Any or all handlers can be NULL. If kp->flags
|
||||||
is set KPROBE_FLAG_DISABLED, that kp will be registered but disabled,
|
is set KPROBE_FLAG_DISABLED, that kp will be registered but disabled,
|
||||||
so, it's handlers aren't hit until calling enable_kprobe(kp).
|
so, its handlers aren't hit until calling enable_kprobe(kp).
|
||||||
|
|
||||||
NOTE:
|
NOTE:
|
||||||
1. With the introduction of the "symbol_name" field to struct kprobe,
|
1. With the introduction of the "symbol_name" field to struct kprobe,
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ Tips & Tricks
|
|||||||
* Drew Scott Daniels observed: "I don't know why, but when I decrease the number
|
* Drew Scott Daniels observed: "I don't know why, but when I decrease the number
|
||||||
of colours that my display uses it consumes less battery power. I've seen
|
of colours that my display uses it consumes less battery power. I've seen
|
||||||
this on powerbooks too. I hope that this is a piece of information that
|
this on powerbooks too. I hope that this is a piece of information that
|
||||||
might be useful to the Laptop Mode patch or it's users."
|
might be useful to the Laptop Mode patch or its users."
|
||||||
|
|
||||||
* In syslog.conf, you can prefix entries with a dash ``-'' to omit syncing the
|
* In syslog.conf, you can prefix entries with a dash ``-'' to omit syncing the
|
||||||
file after every logging. When you're using laptop-mode and your disk doesn't
|
file after every logging. When you're using laptop-mode and your disk doesn't
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ static u8 *get_feature_bits(struct device *dev)
|
|||||||
* Launcher virtual with an offset.
|
* Launcher virtual with an offset.
|
||||||
*
|
*
|
||||||
* This can be tough to get your head around, but usually it just means that we
|
* This can be tough to get your head around, but usually it just means that we
|
||||||
* use these trivial conversion functions when the Guest gives us it's
|
* use these trivial conversion functions when the Guest gives us its
|
||||||
* "physical" addresses:
|
* "physical" addresses:
|
||||||
*/
|
*/
|
||||||
static void *from_guest_phys(unsigned long addr)
|
static void *from_guest_phys(unsigned long addr)
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ raid_disks != 0.
|
|||||||
|
|
||||||
Then uninitialized devices can be added with ADD_NEW_DISK. The
|
Then uninitialized devices can be added with ADD_NEW_DISK. The
|
||||||
structure passed to ADD_NEW_DISK must specify the state of the device
|
structure passed to ADD_NEW_DISK must specify the state of the device
|
||||||
and it's role in the array.
|
and its role in the array.
|
||||||
|
|
||||||
Once started with RUN_ARRAY, uninitialized spares can be added with
|
Once started with RUN_ARRAY, uninitialized spares can be added with
|
||||||
HOT_ADD_DISK.
|
HOT_ADD_DISK.
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ Depending on the exact configuration, translation between the network packet
|
|||||||
label and the internal LSM security identifier can be time consuming. The
|
label and the internal LSM security identifier can be time consuming. The
|
||||||
NetLabel label mapping cache is a caching mechanism which can be used to
|
NetLabel label mapping cache is a caching mechanism which can be used to
|
||||||
sidestep much of this overhead once a mapping has been established. Once the
|
sidestep much of this overhead once a mapping has been established. Once the
|
||||||
LSM has received a packet, used NetLabel to decode it's security attributes,
|
LSM has received a packet, used NetLabel to decode its security attributes,
|
||||||
and translated the security attributes into a LSM internal identifier the LSM
|
and translated the security attributes into a LSM internal identifier the LSM
|
||||||
can use the NetLabel caching functions to associate the LSM internal
|
can use the NetLabel caching functions to associate the LSM internal
|
||||||
identifier with the network packet's label. This means that in the future
|
identifier with the network packet's label. This means that in the future
|
||||||
|
|||||||
212
Documentation/networking/caif/Linux-CAIF.txt
Normal file
212
Documentation/networking/caif/Linux-CAIF.txt
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
Linux CAIF
|
||||||
|
===========
|
||||||
|
copyright (C) ST-Ericsson AB 2010
|
||||||
|
Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
|
||||||
|
License terms: GNU General Public License (GPL) version 2
|
||||||
|
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
CAIF is a MUX protocol used by ST-Ericsson cellular modems for
|
||||||
|
communication between Modem and host. The host processes can open virtual AT
|
||||||
|
channels, initiate GPRS Data connections, Video channels and Utility Channels.
|
||||||
|
The Utility Channels are general purpose pipes between modem and host.
|
||||||
|
|
||||||
|
ST-Ericsson modems support a number of transports between modem
|
||||||
|
and host. Currently, UART and Loopback are available for Linux.
|
||||||
|
|
||||||
|
|
||||||
|
Architecture:
|
||||||
|
------------
|
||||||
|
The implementation of CAIF is divided into:
|
||||||
|
* CAIF Socket Layer, Kernel API, and Net Device.
|
||||||
|
* CAIF Core Protocol Implementation
|
||||||
|
* CAIF Link Layer, implemented as NET devices.
|
||||||
|
|
||||||
|
|
||||||
|
RTNL
|
||||||
|
!
|
||||||
|
! +------+ +------+ +------+
|
||||||
|
! +------+! +------+! +------+!
|
||||||
|
! ! Sock !! !Kernel!! ! Net !!
|
||||||
|
! ! API !+ ! API !+ ! Dev !+ <- CAIF Client APIs
|
||||||
|
! +------+ +------! +------+
|
||||||
|
! ! ! !
|
||||||
|
! +----------!----------+
|
||||||
|
! +------+ <- CAIF Protocol Implementation
|
||||||
|
+-------> ! CAIF !
|
||||||
|
! Core !
|
||||||
|
+------+
|
||||||
|
+--------!--------+
|
||||||
|
! !
|
||||||
|
+------+ +-----+
|
||||||
|
! ! ! TTY ! <- Link Layer (Net Devices)
|
||||||
|
+------+ +-----+
|
||||||
|
|
||||||
|
|
||||||
|
Using the Kernel API
|
||||||
|
----------------------
|
||||||
|
The Kernel API is used for accessing CAIF channels from the
|
||||||
|
kernel.
|
||||||
|
The user of the API has to implement two callbacks for receive
|
||||||
|
and control.
|
||||||
|
The receive callback gives a CAIF packet as a SKB. The control
|
||||||
|
callback will
|
||||||
|
notify of channel initialization complete, and flow-on/flow-
|
||||||
|
off.
|
||||||
|
|
||||||
|
|
||||||
|
struct caif_device caif_dev = {
|
||||||
|
.caif_config = {
|
||||||
|
.name = "MYDEV"
|
||||||
|
.type = CAIF_CHTY_AT
|
||||||
|
}
|
||||||
|
.receive_cb = my_receive,
|
||||||
|
.control_cb = my_control,
|
||||||
|
};
|
||||||
|
caif_add_device(&caif_dev);
|
||||||
|
caif_transmit(&caif_dev, skb);
|
||||||
|
|
||||||
|
See the caif_kernel.h for details about the CAIF kernel API.
|
||||||
|
|
||||||
|
|
||||||
|
I M P L E M E N T A T I O N
|
||||||
|
===========================
|
||||||
|
===========================
|
||||||
|
|
||||||
|
CAIF Core Protocol Layer
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
CAIF Core layer implements the CAIF protocol as defined by ST-Ericsson.
|
||||||
|
It implements the CAIF protocol stack in a layered approach, where
|
||||||
|
each layer described in the specification is implemented as a separate layer.
|
||||||
|
The architecture is inspired by the design patterns "Protocol Layer" and
|
||||||
|
"Protocol Packet".
|
||||||
|
|
||||||
|
== CAIF structure ==
|
||||||
|
The Core CAIF implementation contains:
|
||||||
|
- Simple implementation of CAIF.
|
||||||
|
- Layered architecture (a la Streams), each layer in the CAIF
|
||||||
|
specification is implemented in a separate c-file.
|
||||||
|
- Clients must implement PHY layer to access physical HW
|
||||||
|
with receive and transmit functions.
|
||||||
|
- Clients must call configuration function to add PHY layer.
|
||||||
|
- Clients must implement CAIF layer to consume/produce
|
||||||
|
CAIF payload with receive and transmit functions.
|
||||||
|
- Clients must call configuration function to add and connect the
|
||||||
|
Client layer.
|
||||||
|
- When receiving / transmitting CAIF Packets (cfpkt), ownership is passed
|
||||||
|
to the called function (except for framing layers' receive functions
|
||||||
|
or if a transmit function returns an error, in which case the caller
|
||||||
|
must free the packet).
|
||||||
|
|
||||||
|
Layered Architecture
|
||||||
|
--------------------
|
||||||
|
The CAIF protocol can be divided into two parts: Support functions and Protocol
|
||||||
|
Implementation. The support functions include:
|
||||||
|
|
||||||
|
- CFPKT CAIF Packet. Implementation of CAIF Protocol Packet. The
|
||||||
|
CAIF Packet has functions for creating, destroying and adding content
|
||||||
|
and for adding/extracting header and trailers to protocol packets.
|
||||||
|
|
||||||
|
- CFLST CAIF list implementation.
|
||||||
|
|
||||||
|
- CFGLUE CAIF Glue. Contains OS Specifics, such as memory
|
||||||
|
allocation, endianness, etc.
|
||||||
|
|
||||||
|
The CAIF Protocol implementation contains:
|
||||||
|
|
||||||
|
- CFCNFG CAIF Configuration layer. Configures the CAIF Protocol
|
||||||
|
Stack and provides a Client interface for adding Link-Layer and
|
||||||
|
Driver interfaces on top of the CAIF Stack.
|
||||||
|
|
||||||
|
- CFCTRL CAIF Control layer. Encodes and Decodes control messages
|
||||||
|
such as enumeration and channel setup. Also matches request and
|
||||||
|
response messages.
|
||||||
|
|
||||||
|
- CFSERVL General CAIF Service Layer functionality; handles flow
|
||||||
|
control and remote shutdown requests.
|
||||||
|
|
||||||
|
- CFVEI CAIF VEI layer. Handles CAIF AT Channels on VEI (Virtual
|
||||||
|
External Interface). This layer encodes/decodes VEI frames.
|
||||||
|
|
||||||
|
- CFDGML CAIF Datagram layer. Handles CAIF Datagram layer (IP
|
||||||
|
traffic), encodes/decodes Datagram frames.
|
||||||
|
|
||||||
|
- CFMUX CAIF Mux layer. Handles multiplexing between multiple
|
||||||
|
physical bearers and multiple channels such as VEI, Datagram, etc.
|
||||||
|
The MUX keeps track of the existing CAIF Channels and
|
||||||
|
Physical Instances and selects the apropriate instance based
|
||||||
|
on Channel-Id and Physical-ID.
|
||||||
|
|
||||||
|
- CFFRML CAIF Framing layer. Handles Framing i.e. Frame length
|
||||||
|
and frame checksum.
|
||||||
|
|
||||||
|
- CFSERL CAIF Serial layer. Handles concatenation/split of frames
|
||||||
|
into CAIF Frames with correct length.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
+---------+
|
||||||
|
| Config |
|
||||||
|
| CFCNFG |
|
||||||
|
+---------+
|
||||||
|
!
|
||||||
|
+---------+ +---------+ +---------+
|
||||||
|
| AT | | Control | | Datagram|
|
||||||
|
| CFVEIL | | CFCTRL | | CFDGML |
|
||||||
|
+---------+ +---------+ +---------+
|
||||||
|
\_____________!______________/
|
||||||
|
!
|
||||||
|
+---------+
|
||||||
|
| MUX |
|
||||||
|
| |
|
||||||
|
+---------+
|
||||||
|
_____!_____
|
||||||
|
/ \
|
||||||
|
+---------+ +---------+
|
||||||
|
| CFFRML | | CFFRML |
|
||||||
|
| Framing | | Framing |
|
||||||
|
+---------+ +---------+
|
||||||
|
! !
|
||||||
|
+---------+ +---------+
|
||||||
|
| | | Serial |
|
||||||
|
| | | CFSERL |
|
||||||
|
+---------+ +---------+
|
||||||
|
|
||||||
|
|
||||||
|
In this layered approach the following "rules" apply.
|
||||||
|
- All layers embed the same structure "struct cflayer"
|
||||||
|
- A layer does not depend on any other layer's private data.
|
||||||
|
- Layers are stacked by setting the pointers
|
||||||
|
layer->up , layer->dn
|
||||||
|
- In order to send data upwards, each layer should do
|
||||||
|
layer->up->receive(layer->up, packet);
|
||||||
|
- In order to send data downwards, each layer should do
|
||||||
|
layer->dn->transmit(layer->dn, packet);
|
||||||
|
|
||||||
|
|
||||||
|
Linux Driver Implementation
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Linux GPRS Net Device and CAIF socket are implemented on top of the
|
||||||
|
CAIF Core protocol. The Net device and CAIF socket have an instance of
|
||||||
|
'struct cflayer', just like the CAIF Core protocol stack.
|
||||||
|
Net device and Socket implement the 'receive()' function defined by
|
||||||
|
'struct cflayer', just like the rest of the CAIF stack. In this way, transmit and
|
||||||
|
receive of packets is handled as by the rest of the layers: the 'dn->transmit()'
|
||||||
|
function is called in order to transmit data.
|
||||||
|
|
||||||
|
The layer on top of the CAIF Core implementation is
|
||||||
|
sometimes referred to as the "Client layer".
|
||||||
|
|
||||||
|
|
||||||
|
Configuration of Link Layer
|
||||||
|
---------------------------
|
||||||
|
The Link Layer is implemented as Linux net devices (struct net_device).
|
||||||
|
Payload handling and registration is done using standard Linux mechanisms.
|
||||||
|
|
||||||
|
The CAIF Protocol relies on a loss-less link layer without implementing
|
||||||
|
retransmission. This implies that packet drops must not happen.
|
||||||
|
Therefore a flow-control mechanism is implemented where the physical
|
||||||
|
interface can initiate flow stop for all CAIF Channels.
|
||||||
109
Documentation/networking/caif/README
Normal file
109
Documentation/networking/caif/README
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
Copyright (C) ST-Ericsson AB 2010
|
||||||
|
Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
|
||||||
|
License terms: GNU General Public License (GPL) version 2
|
||||||
|
---------------------------------------------------------
|
||||||
|
|
||||||
|
=== Start ===
|
||||||
|
If you have compiled CAIF for modules do:
|
||||||
|
|
||||||
|
$modprobe crc_ccitt
|
||||||
|
$modprobe caif
|
||||||
|
$modprobe caif_socket
|
||||||
|
$modprobe chnl_net
|
||||||
|
|
||||||
|
|
||||||
|
=== Preparing the setup with a STE modem ===
|
||||||
|
|
||||||
|
If you are working on integration of CAIF you should make sure
|
||||||
|
that the kernel is built with module support.
|
||||||
|
|
||||||
|
There are some things that need to be tweaked to get the host TTY correctly
|
||||||
|
set up to talk to the modem.
|
||||||
|
Since the CAIF stack is running in the kernel and we want to use the existing
|
||||||
|
TTY, we are installing our physical serial driver as a line discipline above
|
||||||
|
the TTY device.
|
||||||
|
|
||||||
|
To achieve this we need to install the N_CAIF ldisc from user space.
|
||||||
|
The benefit is that we can hook up to any TTY.
|
||||||
|
|
||||||
|
The use of Start-of-frame-extension (STX) must also be set as
|
||||||
|
module parameter "ser_use_stx".
|
||||||
|
|
||||||
|
Normally Frame Checksum is always used on UART, but this is also provided as a
|
||||||
|
module parameter "ser_use_fcs".
|
||||||
|
|
||||||
|
$ modprobe caif_serial ser_ttyname=/dev/ttyS0 ser_use_stx=yes
|
||||||
|
$ ifconfig caif_ttyS0 up
|
||||||
|
|
||||||
|
PLEASE NOTE: There is a limitation in Android shell.
|
||||||
|
It only accepts one argument to insmod/modprobe!
|
||||||
|
|
||||||
|
=== Trouble shooting ===
|
||||||
|
|
||||||
|
There are debugfs parameters provided for serial communication.
|
||||||
|
/sys/kernel/debug/caif_serial/<tty-name>/
|
||||||
|
|
||||||
|
* ser_state: Prints the bit-mask status where
|
||||||
|
- 0x02 means SENDING, this is a transient state.
|
||||||
|
- 0x10 means FLOW_OFF_SENT, i.e. the previous frame has not been sent
|
||||||
|
and is blocking further send operation. Flow OFF has been propagated
|
||||||
|
to all CAIF Channels using this TTY.
|
||||||
|
|
||||||
|
* tty_status: Prints the bit-mask tty status information
|
||||||
|
- 0x01 - tty->warned is on.
|
||||||
|
- 0x02 - tty->low_latency is on.
|
||||||
|
- 0x04 - tty->packed is on.
|
||||||
|
- 0x08 - tty->flow_stopped is on.
|
||||||
|
- 0x10 - tty->hw_stopped is on.
|
||||||
|
- 0x20 - tty->stopped is on.
|
||||||
|
|
||||||
|
* last_tx_msg: Binary blob Prints the last transmitted frame.
|
||||||
|
This can be printed with
|
||||||
|
$od --format=x1 /sys/kernel/debug/caif_serial/<tty>/last_rx_msg.
|
||||||
|
The first two tx messages sent look like this. Note: The initial
|
||||||
|
byte 02 is start of frame extension (STX) used for re-syncing
|
||||||
|
upon errors.
|
||||||
|
|
||||||
|
- Enumeration:
|
||||||
|
0000000 02 05 00 00 03 01 d2 02
|
||||||
|
| | | | | |
|
||||||
|
STX(1) | | | |
|
||||||
|
Length(2)| | |
|
||||||
|
Control Channel(1)
|
||||||
|
Command:Enumeration(1)
|
||||||
|
Link-ID(1)
|
||||||
|
Checksum(2)
|
||||||
|
- Channel Setup:
|
||||||
|
0000000 02 07 00 00 00 21 a1 00 48 df
|
||||||
|
| | | | | | | |
|
||||||
|
STX(1) | | | | | |
|
||||||
|
Length(2)| | | | |
|
||||||
|
Control Channel(1)
|
||||||
|
Command:Channel Setup(1)
|
||||||
|
Channel Type(1)
|
||||||
|
Priority and Link-ID(1)
|
||||||
|
Endpoint(1)
|
||||||
|
Checksum(2)
|
||||||
|
|
||||||
|
* last_rx_msg: Prints the last transmitted frame.
|
||||||
|
The RX messages for LinkSetup look almost identical but they have the
|
||||||
|
bit 0x20 set in the command bit, and Channel Setup has added one byte
|
||||||
|
before Checksum containing Channel ID.
|
||||||
|
NOTE: Several CAIF Messages might be concatenated. The maximum debug
|
||||||
|
buffer size is 128 bytes.
|
||||||
|
|
||||||
|
== Error Scenarios:
|
||||||
|
- last_tx_msg contains channel setup message and last_rx_msg is empty ->
|
||||||
|
The host seems to be able to send over the UART, at least the CAIF ldisc get
|
||||||
|
notified that sending is completed.
|
||||||
|
|
||||||
|
- last_tx_msg contains enumeration message and last_rx_msg is empty ->
|
||||||
|
The host is not able to send the message from UART, the tty has not been
|
||||||
|
able to complete the transmit operation.
|
||||||
|
|
||||||
|
- if /sys/kernel/debug/caif_serial/<tty>/tty_status is non-zero there
|
||||||
|
might be problems transmitting over UART.
|
||||||
|
E.g. host and modem wiring is not correct you will typically see
|
||||||
|
tty_status = 0x10 (hw_stopped) and ser_state = 0x10 (FLOW_OFF_SENT).
|
||||||
|
You will probably see the enumeration message in last_tx_message
|
||||||
|
and empty last_rx_message.
|
||||||
@@ -756,7 +756,7 @@ static int enslave(char *master_ifname, char *slave_ifname)
|
|||||||
*/
|
*/
|
||||||
if (abi_ver < 1) {
|
if (abi_ver < 1) {
|
||||||
/* For old ABI, the master needs to be
|
/* For old ABI, the master needs to be
|
||||||
* down before setting it's hwaddr
|
* down before setting its hwaddr
|
||||||
*/
|
*/
|
||||||
res = set_if_down(master_ifname, master_flags.ifr_flags);
|
res = set_if_down(master_ifname, master_flags.ifr_flags);
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|||||||
@@ -588,6 +588,37 @@ ip_local_port_range - 2 INTEGERS
|
|||||||
(i.e. by default) range 1024-4999 is enough to issue up to
|
(i.e. by default) range 1024-4999 is enough to issue up to
|
||||||
2000 connections per second to systems supporting timestamps.
|
2000 connections per second to systems supporting timestamps.
|
||||||
|
|
||||||
|
ip_local_reserved_ports - list of comma separated ranges
|
||||||
|
Specify the ports which are reserved for known third-party
|
||||||
|
applications. These ports will not be used by automatic port
|
||||||
|
assignments (e.g. when calling connect() or bind() with port
|
||||||
|
number 0). Explicit port allocation behavior is unchanged.
|
||||||
|
|
||||||
|
The format used for both input and output is a comma separated
|
||||||
|
list of ranges (e.g. "1,2-4,10-10" for ports 1, 2, 3, 4 and
|
||||||
|
10). Writing to the file will clear all previously reserved
|
||||||
|
ports and update the current list with the one given in the
|
||||||
|
input.
|
||||||
|
|
||||||
|
Note that ip_local_port_range and ip_local_reserved_ports
|
||||||
|
settings are independent and both are considered by the kernel
|
||||||
|
when determining which ports are available for automatic port
|
||||||
|
assignments.
|
||||||
|
|
||||||
|
You can reserve ports which are not in the current
|
||||||
|
ip_local_port_range, e.g.:
|
||||||
|
|
||||||
|
$ cat /proc/sys/net/ipv4/ip_local_port_range
|
||||||
|
32000 61000
|
||||||
|
$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
|
||||||
|
8080,9148
|
||||||
|
|
||||||
|
although this is redundant. However such a setting is useful
|
||||||
|
if later the port range is changed to a value that will
|
||||||
|
include the reserved ports.
|
||||||
|
|
||||||
|
Default: Empty
|
||||||
|
|
||||||
ip_nonlocal_bind - BOOLEAN
|
ip_nonlocal_bind - BOOLEAN
|
||||||
If set, allows processes to bind() to non-local IP addresses,
|
If set, allows processes to bind() to non-local IP addresses,
|
||||||
which can be quite useful - but may break some applications.
|
which can be quite useful - but may break some applications.
|
||||||
|
|||||||
@@ -1,44 +1,95 @@
|
|||||||
This brief document describes how to use the kernel's PPPoL2TP driver
|
This document describes how to use the kernel's L2TP drivers to
|
||||||
to provide L2TP functionality. L2TP is a protocol that tunnels one or
|
provide L2TP functionality. L2TP is a protocol that tunnels one or
|
||||||
more PPP sessions over a UDP tunnel. It is commonly used for VPNs
|
more sessions over an IP tunnel. It is commonly used for VPNs
|
||||||
(L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP
|
(L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP
|
||||||
network infrastructure.
|
network infrastructure. With L2TPv3, it is also useful as a Layer-2
|
||||||
|
tunneling infrastructure.
|
||||||
|
|
||||||
|
Features
|
||||||
|
========
|
||||||
|
|
||||||
|
L2TPv2 (PPP over L2TP (UDP tunnels)).
|
||||||
|
L2TPv3 ethernet pseudowires.
|
||||||
|
L2TPv3 PPP pseudowires.
|
||||||
|
L2TPv3 IP encapsulation.
|
||||||
|
Netlink sockets for L2TPv3 configuration management.
|
||||||
|
|
||||||
|
History
|
||||||
|
=======
|
||||||
|
|
||||||
|
The original pppol2tp driver was introduced in 2.6.23 and provided
|
||||||
|
L2TPv2 functionality (rfc2661). L2TPv2 is used to tunnel one or more PPP
|
||||||
|
sessions over a UDP tunnel.
|
||||||
|
|
||||||
|
L2TPv3 (rfc3931) changes the protocol to allow different frame types
|
||||||
|
to be passed over an L2TP tunnel by moving the PPP-specific parts of
|
||||||
|
the protocol out of the core L2TP packet headers. Each frame type is
|
||||||
|
known as a pseudowire type. Ethernet, PPP, HDLC, Frame Relay and ATM
|
||||||
|
pseudowires for L2TP are defined in separate RFC standards. Another
|
||||||
|
change for L2TPv3 is that it can be carried directly over IP with no
|
||||||
|
UDP header (UDP is optional). It is also possible to create static
|
||||||
|
unmanaged L2TPv3 tunnels manually without a control protocol
|
||||||
|
(userspace daemon) to manage them.
|
||||||
|
|
||||||
|
To support L2TPv3, the original pppol2tp driver was split up to
|
||||||
|
separate the L2TP and PPP functionality. Existing L2TPv2 userspace
|
||||||
|
apps should be unaffected as the original pppol2tp sockets API is
|
||||||
|
retained. L2TPv3, however, uses netlink to manage L2TPv3 tunnels and
|
||||||
|
sessions.
|
||||||
|
|
||||||
Design
|
Design
|
||||||
======
|
======
|
||||||
|
|
||||||
The PPPoL2TP driver, drivers/net/pppol2tp.c, provides a mechanism by
|
The L2TP protocol separates control and data frames. The L2TP kernel
|
||||||
which PPP frames carried through an L2TP session are passed through
|
drivers handle only L2TP data frames; control frames are always
|
||||||
the kernel's PPP subsystem. The standard PPP daemon, pppd, handles all
|
handled by userspace. L2TP control frames carry messages between L2TP
|
||||||
PPP interaction with the peer. PPP network interfaces are created for
|
clients/servers and are used to setup / teardown tunnels and
|
||||||
each local PPP endpoint.
|
sessions. An L2TP client or server is implemented in userspace.
|
||||||
|
|
||||||
The L2TP protocol http://www.faqs.org/rfcs/rfc2661.html defines L2TP
|
Each L2TP tunnel is implemented using a UDP or L2TPIP socket; L2TPIP
|
||||||
control and data frames. L2TP control frames carry messages between
|
provides L2TPv3 IP encapsulation (no UDP) and is implemented using a
|
||||||
L2TP clients/servers and are used to setup / teardown tunnels and
|
new l2tpip socket family. The tunnel socket is typically created by
|
||||||
sessions. An L2TP client or server is implemented in userspace and
|
userspace, though for unmanaged L2TPv3 tunnels, the socket can also be
|
||||||
will use a regular UDP socket per tunnel. L2TP data frames carry PPP
|
created by the kernel. Each L2TP session (pseudowire) gets a network
|
||||||
frames, which may be PPP control or PPP data. The kernel's PPP
|
interface instance. In the case of PPP, these interfaces are created
|
||||||
|
indirectly by pppd using a pppol2tp socket. In the case of ethernet,
|
||||||
|
the netdevice is created upon a netlink request to create an L2TPv3
|
||||||
|
ethernet pseudowire.
|
||||||
|
|
||||||
|
For PPP, the PPPoL2TP driver, net/l2tp/l2tp_ppp.c, provides a
|
||||||
|
mechanism by which PPP frames carried through an L2TP session are
|
||||||
|
passed through the kernel's PPP subsystem. The standard PPP daemon,
|
||||||
|
pppd, handles all PPP interaction with the peer. PPP network
|
||||||
|
interfaces are created for each local PPP endpoint. The kernel's PPP
|
||||||
subsystem arranges for PPP control frames to be delivered to pppd,
|
subsystem arranges for PPP control frames to be delivered to pppd,
|
||||||
while data frames are forwarded as usual.
|
while data frames are forwarded as usual.
|
||||||
|
|
||||||
|
For ethernet, the L2TPETH driver, net/l2tp/l2tp_eth.c, implements a
|
||||||
|
netdevice driver, managing virtual ethernet devices, one per
|
||||||
|
pseudowire. These interfaces can be managed using standard Linux tools
|
||||||
|
such as "ip" and "ifconfig". If only IP frames are passed over the
|
||||||
|
tunnel, the interface can be given an IP addresses of itself and its
|
||||||
|
peer. If non-IP frames are to be passed over the tunnel, the interface
|
||||||
|
can be added to a bridge using brctl. All L2TP datapath protocol
|
||||||
|
functions are handled by the L2TP core driver.
|
||||||
|
|
||||||
Each tunnel and session within a tunnel is assigned a unique tunnel_id
|
Each tunnel and session within a tunnel is assigned a unique tunnel_id
|
||||||
and session_id. These ids are carried in the L2TP header of every
|
and session_id. These ids are carried in the L2TP header of every
|
||||||
control and data packet. The pppol2tp driver uses them to lookup
|
control and data packet. (Actually, in L2TPv3, the tunnel_id isn't
|
||||||
internal tunnel and/or session contexts. Zero tunnel / session ids are
|
present in data frames - it is inferred from the IP connection on
|
||||||
treated specially - zero ids are never assigned to tunnels or sessions
|
which the packet was received.) The L2TP driver uses the ids to lookup
|
||||||
in the network. In the driver, the tunnel context keeps a pointer to
|
internal tunnel and/or session contexts to determine how to handle the
|
||||||
the tunnel UDP socket. The session context keeps a pointer to the
|
packet. Zero tunnel / session ids are treated specially - zero ids are
|
||||||
PPPoL2TP socket, as well as other data that lets the driver interface
|
never assigned to tunnels or sessions in the network. In the driver,
|
||||||
to the kernel PPP subsystem.
|
the tunnel context keeps a reference to the tunnel UDP or L2TPIP
|
||||||
|
socket. The session context holds data that lets the driver interface
|
||||||
|
to the kernel's network frame type subsystems, i.e. PPP, ethernet.
|
||||||
|
|
||||||
Note that the pppol2tp kernel driver handles only L2TP data frames;
|
Userspace Programming
|
||||||
L2TP control frames are simply passed up to userspace in the UDP
|
=====================
|
||||||
tunnel socket. The kernel handles all datapath aspects of the
|
|
||||||
protocol, including data packet resequencing (if enabled).
|
|
||||||
|
|
||||||
There are a number of requirements on the userspace L2TP daemon in
|
For L2TPv2, there are a number of requirements on the userspace L2TP
|
||||||
order to use the pppol2tp driver.
|
daemon in order to use the pppol2tp driver.
|
||||||
|
|
||||||
1. Use a UDP socket per tunnel.
|
1. Use a UDP socket per tunnel.
|
||||||
|
|
||||||
@@ -86,6 +137,35 @@ In addition to the standard PPP ioctls, a PPPIOCGL2TPSTATS is provided
|
|||||||
to retrieve tunnel and session statistics from the kernel using the
|
to retrieve tunnel and session statistics from the kernel using the
|
||||||
PPPoX socket of the appropriate tunnel or session.
|
PPPoX socket of the appropriate tunnel or session.
|
||||||
|
|
||||||
|
For L2TPv3, userspace must use the netlink API defined in
|
||||||
|
include/linux/l2tp.h to manage tunnel and session contexts. The
|
||||||
|
general procedure to create a new L2TP tunnel with one session is:-
|
||||||
|
|
||||||
|
1. Open a GENL socket using L2TP_GENL_NAME for configuring the kernel
|
||||||
|
using netlink.
|
||||||
|
|
||||||
|
2. Create a UDP or L2TPIP socket for the tunnel.
|
||||||
|
|
||||||
|
3. Create a new L2TP tunnel using a L2TP_CMD_TUNNEL_CREATE
|
||||||
|
request. Set attributes according to desired tunnel parameters,
|
||||||
|
referencing the UDP or L2TPIP socket created in the previous step.
|
||||||
|
|
||||||
|
4. Create a new L2TP session in the tunnel using a
|
||||||
|
L2TP_CMD_SESSION_CREATE request.
|
||||||
|
|
||||||
|
The tunnel and all of its sessions are closed when the tunnel socket
|
||||||
|
is closed. The netlink API may also be used to delete sessions and
|
||||||
|
tunnels. Configuration and status info may be set or read using netlink.
|
||||||
|
|
||||||
|
The L2TP driver also supports static (unmanaged) L2TPv3 tunnels. These
|
||||||
|
are where there is no L2TP control message exchange with the peer to
|
||||||
|
setup the tunnel; the tunnel is configured manually at each end of the
|
||||||
|
tunnel. There is no need for an L2TP userspace application in this
|
||||||
|
case -- the tunnel socket is created by the kernel and configured
|
||||||
|
using parameters sent in the L2TP_CMD_TUNNEL_CREATE netlink
|
||||||
|
request. The "ip" utility of iproute2 has commands for managing static
|
||||||
|
L2TPv3 tunnels; do "ip l2tp help" for more information.
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
=========
|
=========
|
||||||
|
|
||||||
@@ -102,6 +182,69 @@ PPPOL2TP_MSG_CONTROL userspace - kernel interface
|
|||||||
PPPOL2TP_MSG_SEQ sequence numbers handling
|
PPPOL2TP_MSG_SEQ sequence numbers handling
|
||||||
PPPOL2TP_MSG_DATA data packets
|
PPPOL2TP_MSG_DATA data packets
|
||||||
|
|
||||||
|
If enabled, files under a l2tp debugfs directory can be used to dump
|
||||||
|
kernel state about L2TP tunnels and sessions. To access it, the
|
||||||
|
debugfs filesystem must first be mounted.
|
||||||
|
|
||||||
|
# mount -t debugfs debugfs /debug
|
||||||
|
|
||||||
|
Files under the l2tp directory can then be accessed.
|
||||||
|
|
||||||
|
# cat /debug/l2tp/tunnels
|
||||||
|
|
||||||
|
The debugfs files should not be used by applications to obtain L2TP
|
||||||
|
state information because the file format is subject to change. It is
|
||||||
|
implemented to provide extra debug information to help diagnose
|
||||||
|
problems.) Users should use the netlink API.
|
||||||
|
|
||||||
|
/proc/net/pppol2tp is also provided for backwards compaibility with
|
||||||
|
the original pppol2tp driver. It lists information about L2TPv2
|
||||||
|
tunnels and sessions only. Its use is discouraged.
|
||||||
|
|
||||||
|
Unmanaged L2TPv3 Tunnels
|
||||||
|
========================
|
||||||
|
|
||||||
|
Some commercial L2TP products support unmanaged L2TPv3 ethernet
|
||||||
|
tunnels, where there is no L2TP control protocol; tunnels are
|
||||||
|
configured at each side manually. New commands are available in
|
||||||
|
iproute2's ip utility to support this.
|
||||||
|
|
||||||
|
To create an L2TPv3 ethernet pseudowire between local host 192.168.1.1
|
||||||
|
and peer 192.168.1.2, using IP addresses 10.5.1.1 and 10.5.1.2 for the
|
||||||
|
tunnel endpoints:-
|
||||||
|
|
||||||
|
# modprobe l2tp_eth
|
||||||
|
# modprobe l2tp_netlink
|
||||||
|
|
||||||
|
# ip l2tp add tunnel tunnel_id 1 peer_tunnel_id 1 udp_sport 5000 \
|
||||||
|
udp_dport 5000 encap udp local 192.168.1.1 remote 192.168.1.2
|
||||||
|
# ip l2tp add session tunnel_id 1 session_id 1 peer_session_id 1
|
||||||
|
# ifconfig -a
|
||||||
|
# ip addr add 10.5.1.2/32 peer 10.5.1.1/32 dev l2tpeth0
|
||||||
|
# ifconfig l2tpeth0 up
|
||||||
|
|
||||||
|
Choose IP addresses to be the address of a local IP interface and that
|
||||||
|
of the remote system. The IP addresses of the l2tpeth0 interface can be
|
||||||
|
anything suitable.
|
||||||
|
|
||||||
|
Repeat the above at the peer, with ports, tunnel/session ids and IP
|
||||||
|
addresses reversed. The tunnel and session IDs can be any non-zero
|
||||||
|
32-bit number, but the values must be reversed at the peer.
|
||||||
|
|
||||||
|
Host 1 Host2
|
||||||
|
udp_sport=5000 udp_sport=5001
|
||||||
|
udp_dport=5001 udp_dport=5000
|
||||||
|
tunnel_id=42 tunnel_id=45
|
||||||
|
peer_tunnel_id=45 peer_tunnel_id=42
|
||||||
|
session_id=128 session_id=5196755
|
||||||
|
peer_session_id=5196755 peer_session_id=128
|
||||||
|
|
||||||
|
When done at both ends of the tunnel, it should be possible to send
|
||||||
|
data over the network. e.g.
|
||||||
|
|
||||||
|
# ping 10.5.1.1
|
||||||
|
|
||||||
|
|
||||||
Sample Userspace Code
|
Sample Userspace Code
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
@@ -158,12 +301,48 @@ Sample Userspace Code
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Miscellaneous
|
Internal Implementation
|
||||||
============
|
=======================
|
||||||
|
|
||||||
The PPPoL2TP driver was developed as part of the OpenL2TP project by
|
The driver keeps a struct l2tp_tunnel context per L2TP tunnel and a
|
||||||
|
struct l2tp_session context for each session. The l2tp_tunnel is
|
||||||
|
always associated with a UDP or L2TP/IP socket and keeps a list of
|
||||||
|
sessions in the tunnel. The l2tp_session context keeps kernel state
|
||||||
|
about the session. It has private data which is used for data specific
|
||||||
|
to the session type. With L2TPv2, the session always carried PPP
|
||||||
|
traffic. With L2TPv3, the session can also carry ethernet frames
|
||||||
|
(ethernet pseudowire) or other data types such as ATM, HDLC or Frame
|
||||||
|
Relay.
|
||||||
|
|
||||||
|
When a tunnel is first opened, the reference count on the socket is
|
||||||
|
increased using sock_hold(). This ensures that the kernel socket
|
||||||
|
cannot be removed while L2TP's data structures reference it.
|
||||||
|
|
||||||
|
Some L2TP sessions also have a socket (PPP pseudowires) while others
|
||||||
|
do not (ethernet pseudowires). We can't use the socket reference count
|
||||||
|
as the reference count for session contexts. The L2TP implementation
|
||||||
|
therefore has its own internal reference counts on the session
|
||||||
|
contexts.
|
||||||
|
|
||||||
|
To Do
|
||||||
|
=====
|
||||||
|
|
||||||
|
Add L2TP tunnel switching support. This would route tunneled traffic
|
||||||
|
from one L2TP tunnel into another. Specified in
|
||||||
|
http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08
|
||||||
|
|
||||||
|
Add L2TPv3 VLAN pseudowire support.
|
||||||
|
|
||||||
|
Add L2TPv3 IP pseudowire support.
|
||||||
|
|
||||||
|
Add L2TPv3 ATM pseudowire support.
|
||||||
|
|
||||||
|
Miscellaneous
|
||||||
|
=============
|
||||||
|
|
||||||
|
The L2TP drivers were developed as part of the OpenL2TP project by
|
||||||
Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server,
|
Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server,
|
||||||
designed from the ground up to have the L2TP datapath in the
|
designed from the ground up to have the L2TP datapath in the
|
||||||
kernel. The project also implemented the pppol2tp plugin for pppd
|
kernel. The project also implemented the pppol2tp plugin for pppd
|
||||||
which allows pppd to use the kernel driver. Details can be found at
|
which allows pppd to use the kernel driver. Details can be found at
|
||||||
http://openl2tp.sourceforge.net.
|
http://www.openl2tp.org.
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ by the kernel.
|
|||||||
The destruction of the socket and all associated resources
|
The destruction of the socket and all associated resources
|
||||||
is done by a simple call to close(fd).
|
is done by a simple call to close(fd).
|
||||||
|
|
||||||
Next I will describe PACKET_MMAP settings and it's constraints,
|
Next I will describe PACKET_MMAP settings and its constraints,
|
||||||
also the mapping of the circular buffer in the user process and
|
also the mapping of the circular buffer in the user process and
|
||||||
the use of this buffer.
|
the use of this buffer.
|
||||||
|
|
||||||
@@ -432,7 +432,7 @@ TP_STATUS_LOSING : indicates there were packet drops from last time
|
|||||||
the PACKET_STATISTICS option.
|
the PACKET_STATISTICS option.
|
||||||
|
|
||||||
TP_STATUS_CSUMNOTREADY: currently it's used for outgoing IP packets which
|
TP_STATUS_CSUMNOTREADY: currently it's used for outgoing IP packets which
|
||||||
it's checksum will be done in hardware. So while
|
its checksum will be done in hardware. So while
|
||||||
reading the packet we should not try to check the
|
reading the packet we should not try to check the
|
||||||
checksum.
|
checksum.
|
||||||
|
|
||||||
|
|||||||
@@ -20,23 +20,23 @@ the rest of the skbuff, if any more information does exist.
|
|||||||
Packet Layer to Device Driver
|
Packet Layer to Device Driver
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
First Byte = 0x00
|
First Byte = 0x00 (X25_IFACE_DATA)
|
||||||
|
|
||||||
This indicates that the rest of the skbuff contains data to be transmitted
|
This indicates that the rest of the skbuff contains data to be transmitted
|
||||||
over the LAPB link. The LAPB link should already exist before any data is
|
over the LAPB link. The LAPB link should already exist before any data is
|
||||||
passed down.
|
passed down.
|
||||||
|
|
||||||
First Byte = 0x01
|
First Byte = 0x01 (X25_IFACE_CONNECT)
|
||||||
|
|
||||||
Establish the LAPB link. If the link is already established then the connect
|
Establish the LAPB link. If the link is already established then the connect
|
||||||
confirmation message should be returned as soon as possible.
|
confirmation message should be returned as soon as possible.
|
||||||
|
|
||||||
First Byte = 0x02
|
First Byte = 0x02 (X25_IFACE_DISCONNECT)
|
||||||
|
|
||||||
Terminate the LAPB link. If it is already disconnected then the disconnect
|
Terminate the LAPB link. If it is already disconnected then the disconnect
|
||||||
confirmation message should be returned as soon as possible.
|
confirmation message should be returned as soon as possible.
|
||||||
|
|
||||||
First Byte = 0x03
|
First Byte = 0x03 (X25_IFACE_PARAMS)
|
||||||
|
|
||||||
LAPB parameters. To be defined.
|
LAPB parameters. To be defined.
|
||||||
|
|
||||||
@@ -44,22 +44,22 @@ LAPB parameters. To be defined.
|
|||||||
Device Driver to Packet Layer
|
Device Driver to Packet Layer
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
First Byte = 0x00
|
First Byte = 0x00 (X25_IFACE_DATA)
|
||||||
|
|
||||||
This indicates that the rest of the skbuff contains data that has been
|
This indicates that the rest of the skbuff contains data that has been
|
||||||
received over the LAPB link.
|
received over the LAPB link.
|
||||||
|
|
||||||
First Byte = 0x01
|
First Byte = 0x01 (X25_IFACE_CONNECT)
|
||||||
|
|
||||||
LAPB link has been established. The same message is used for both a LAPB
|
LAPB link has been established. The same message is used for both a LAPB
|
||||||
link connect_confirmation and a connect_indication.
|
link connect_confirmation and a connect_indication.
|
||||||
|
|
||||||
First Byte = 0x02
|
First Byte = 0x02 (X25_IFACE_DISCONNECT)
|
||||||
|
|
||||||
LAPB link has been terminated. This same message is used for both a LAPB
|
LAPB link has been terminated. This same message is used for both a LAPB
|
||||||
link disconnect_confirmation and a disconnect_indication.
|
link disconnect_confirmation and a disconnect_indication.
|
||||||
|
|
||||||
First Byte = 0x03
|
First Byte = 0x03 (X25_IFACE_PARAMS)
|
||||||
|
|
||||||
LAPB parameters. To be defined.
|
LAPB parameters. To be defined.
|
||||||
|
|
||||||
|
|||||||
107
Documentation/padata.txt
Normal file
107
Documentation/padata.txt
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
The padata parallel execution mechanism
|
||||||
|
Last updated for 2.6.34
|
||||||
|
|
||||||
|
Padata is a mechanism by which the kernel can farm work out to be done in
|
||||||
|
parallel on multiple CPUs while retaining the ordering of tasks. It was
|
||||||
|
developed for use with the IPsec code, which needs to be able to perform
|
||||||
|
encryption and decryption on large numbers of packets without reordering
|
||||||
|
those packets. The crypto developers made a point of writing padata in a
|
||||||
|
sufficiently general fashion that it could be put to other uses as well.
|
||||||
|
|
||||||
|
The first step in using padata is to set up a padata_instance structure for
|
||||||
|
overall control of how tasks are to be run:
|
||||||
|
|
||||||
|
#include <linux/padata.h>
|
||||||
|
|
||||||
|
struct padata_instance *padata_alloc(const struct cpumask *cpumask,
|
||||||
|
struct workqueue_struct *wq);
|
||||||
|
|
||||||
|
The cpumask describes which processors will be used to execute work
|
||||||
|
submitted to this instance. The workqueue wq is where the work will
|
||||||
|
actually be done; it should be a multithreaded queue, naturally.
|
||||||
|
|
||||||
|
There are functions for enabling and disabling the instance:
|
||||||
|
|
||||||
|
void padata_start(struct padata_instance *pinst);
|
||||||
|
void padata_stop(struct padata_instance *pinst);
|
||||||
|
|
||||||
|
These functions literally do nothing beyond setting or clearing the
|
||||||
|
"padata_start() was called" flag; if that flag is not set, other functions
|
||||||
|
will refuse to work.
|
||||||
|
|
||||||
|
The list of CPUs to be used can be adjusted with these functions:
|
||||||
|
|
||||||
|
int padata_set_cpumask(struct padata_instance *pinst,
|
||||||
|
cpumask_var_t cpumask);
|
||||||
|
int padata_add_cpu(struct padata_instance *pinst, int cpu);
|
||||||
|
int padata_remove_cpu(struct padata_instance *pinst, int cpu);
|
||||||
|
|
||||||
|
Changing the CPU mask has the look of an expensive operation, though, so it
|
||||||
|
probably should not be done with great frequency.
|
||||||
|
|
||||||
|
Actually submitting work to the padata instance requires the creation of a
|
||||||
|
padata_priv structure:
|
||||||
|
|
||||||
|
struct padata_priv {
|
||||||
|
/* Other stuff here... */
|
||||||
|
void (*parallel)(struct padata_priv *padata);
|
||||||
|
void (*serial)(struct padata_priv *padata);
|
||||||
|
};
|
||||||
|
|
||||||
|
This structure will almost certainly be embedded within some larger
|
||||||
|
structure specific to the work to be done. Most its fields are private to
|
||||||
|
padata, but the structure should be zeroed at initialization time, and the
|
||||||
|
parallel() and serial() functions should be provided. Those functions will
|
||||||
|
be called in the process of getting the work done as we will see
|
||||||
|
momentarily.
|
||||||
|
|
||||||
|
The submission of work is done with:
|
||||||
|
|
||||||
|
int padata_do_parallel(struct padata_instance *pinst,
|
||||||
|
struct padata_priv *padata, int cb_cpu);
|
||||||
|
|
||||||
|
The pinst and padata structures must be set up as described above; cb_cpu
|
||||||
|
specifies which CPU will be used for the final callback when the work is
|
||||||
|
done; it must be in the current instance's CPU mask. The return value from
|
||||||
|
padata_do_parallel() is a little strange; zero is an error return
|
||||||
|
indicating that the caller forgot the padata_start() formalities. -EBUSY
|
||||||
|
means that somebody, somewhere else is messing with the instance's CPU
|
||||||
|
mask, while -EINVAL is a complaint about cb_cpu not being in that CPU mask.
|
||||||
|
If all goes well, this function will return -EINPROGRESS, indicating that
|
||||||
|
the work is in progress.
|
||||||
|
|
||||||
|
Each task submitted to padata_do_parallel() will, in turn, be passed to
|
||||||
|
exactly one call to the above-mentioned parallel() function, on one CPU, so
|
||||||
|
true parallelism is achieved by submitting multiple tasks. Despite the
|
||||||
|
fact that the workqueue is used to make these calls, parallel() is run with
|
||||||
|
software interrupts disabled and thus cannot sleep. The parallel()
|
||||||
|
function gets the padata_priv structure pointer as its lone parameter;
|
||||||
|
information about the actual work to be done is probably obtained by using
|
||||||
|
container_of() to find the enclosing structure.
|
||||||
|
|
||||||
|
Note that parallel() has no return value; the padata subsystem assumes that
|
||||||
|
parallel() will take responsibility for the task from this point. The work
|
||||||
|
need not be completed during this call, but, if parallel() leaves work
|
||||||
|
outstanding, it should be prepared to be called again with a new job before
|
||||||
|
the previous one completes. When a task does complete, parallel() (or
|
||||||
|
whatever function actually finishes the job) should inform padata of the
|
||||||
|
fact with a call to:
|
||||||
|
|
||||||
|
void padata_do_serial(struct padata_priv *padata);
|
||||||
|
|
||||||
|
At some point in the future, padata_do_serial() will trigger a call to the
|
||||||
|
serial() function in the padata_priv structure. That call will happen on
|
||||||
|
the CPU requested in the initial call to padata_do_parallel(); it, too, is
|
||||||
|
done through the workqueue, but with local software interrupts disabled.
|
||||||
|
Note that this call may be deferred for a while since the padata code takes
|
||||||
|
pains to ensure that tasks are completed in the order in which they were
|
||||||
|
submitted.
|
||||||
|
|
||||||
|
The one remaining function in the padata API should be called to clean up
|
||||||
|
when a padata instance is no longer needed:
|
||||||
|
|
||||||
|
void padata_free(struct padata_instance *pinst);
|
||||||
|
|
||||||
|
This function will busy-wait while any remaining tasks are completed, so it
|
||||||
|
might be best not to call it while there is work outstanding. Shutting
|
||||||
|
down the workqueue, if necessary, should be done separately.
|
||||||
@@ -1,4 +1,17 @@
|
|||||||
This file details changes in 2.6 which affect PCMCIA card driver authors:
|
This file details changes in 2.6 which affect PCMCIA card driver authors:
|
||||||
|
* No dev_node_t (as of 2.6.35)
|
||||||
|
There is no more need to fill out a "dev_node_t" structure.
|
||||||
|
|
||||||
|
* New IRQ request rules (as of 2.6.35)
|
||||||
|
Instead of the old pcmcia_request_irq() interface, drivers may now
|
||||||
|
choose between:
|
||||||
|
- calling request_irq/free_irq directly. Use the IRQ from *p_dev->irq.
|
||||||
|
- use pcmcia_request_irq(p_dev, handler_t); the PCMCIA core will
|
||||||
|
clean up automatically on calls to pcmcia_disable_device() or
|
||||||
|
device ejection.
|
||||||
|
- drivers still not capable of IRQF_SHARED (or not telling us so) may
|
||||||
|
use the deprecated pcmcia_request_exclusive_irq() for the time
|
||||||
|
being; they might receive a shared IRQ nonetheless.
|
||||||
|
|
||||||
* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
|
* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
|
||||||
Instead of the cs_error() callback or the CS_CHECK() macro, please use
|
Instead of the cs_error() callback or the CS_CHECK() macro, please use
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
|
Device Power Management
|
||||||
|
|
||||||
|
Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
|
||||||
|
Copyright (c) 2010 Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
|
||||||
|
|
||||||
Most of the code in Linux is device drivers, so most of the Linux power
|
Most of the code in Linux is device drivers, so most of the Linux power
|
||||||
management code is also driver-specific. Most drivers will do very little;
|
management (PM) code is also driver-specific. Most drivers will do very
|
||||||
others, especially for platforms with small batteries (like cell phones),
|
little; others, especially for platforms with small batteries (like cell
|
||||||
will do a lot.
|
phones), will do a lot.
|
||||||
|
|
||||||
This writeup gives an overview of how drivers interact with system-wide
|
This writeup gives an overview of how drivers interact with system-wide
|
||||||
power management goals, emphasizing the models and interfaces that are
|
power management goals, emphasizing the models and interfaces that are
|
||||||
@@ -15,9 +21,10 @@ Drivers will use one or both of these models to put devices into low-power
|
|||||||
states:
|
states:
|
||||||
|
|
||||||
System Sleep model:
|
System Sleep model:
|
||||||
Drivers can enter low power states as part of entering system-wide
|
Drivers can enter low-power states as part of entering system-wide
|
||||||
low-power states like "suspend-to-ram", or (mostly for systems with
|
low-power states like "suspend" (also known as "suspend-to-RAM"), or
|
||||||
disks) "hibernate" (suspend-to-disk).
|
(mostly for systems with disks) "hibernation" (also known as
|
||||||
|
"suspend-to-disk").
|
||||||
|
|
||||||
This is something that device, bus, and class drivers collaborate on
|
This is something that device, bus, and class drivers collaborate on
|
||||||
by implementing various role-specific suspend and resume methods to
|
by implementing various role-specific suspend and resume methods to
|
||||||
@@ -25,33 +32,41 @@ states:
|
|||||||
them without loss of data.
|
them without loss of data.
|
||||||
|
|
||||||
Some drivers can manage hardware wakeup events, which make the system
|
Some drivers can manage hardware wakeup events, which make the system
|
||||||
leave that low-power state. This feature may be disabled using the
|
leave the low-power state. This feature may be enabled or disabled
|
||||||
relevant /sys/devices/.../power/wakeup file; enabling it may cost some
|
using the relevant /sys/devices/.../power/wakeup file (for Ethernet
|
||||||
power usage, but let the whole system enter low power states more often.
|
drivers the ioctl interface used by ethtool may also be used for this
|
||||||
|
purpose); enabling it may cost some power usage, but let the whole
|
||||||
|
system enter low-power states more often.
|
||||||
|
|
||||||
Runtime Power Management model:
|
Runtime Power Management model:
|
||||||
Drivers may also enter low power states while the system is running,
|
Devices may also be put into low-power states while the system is
|
||||||
independently of other power management activity. Upstream drivers
|
running, independently of other power management activity in principle.
|
||||||
will normally not know (or care) if the device is in some low power
|
However, devices are not generally independent of each other (for
|
||||||
state when issuing requests; the driver will auto-resume anything
|
example, a parent device cannot be suspended unless all of its child
|
||||||
that's needed when it gets a request.
|
devices have been suspended). Moreover, depending on the bus type the
|
||||||
|
device is on, it may be necessary to carry out some bus-specific
|
||||||
|
operations on the device for this purpose. Devices put into low power
|
||||||
|
states at run time may require special handling during system-wide power
|
||||||
|
transitions (suspend or hibernation).
|
||||||
|
|
||||||
This doesn't have, or need much infrastructure; it's just something you
|
For these reasons not only the device driver itself, but also the
|
||||||
should do when writing your drivers. For example, clk_disable() unused
|
appropriate subsystem (bus type, device type or device class) driver and
|
||||||
clocks as part of minimizing power drain for currently-unused hardware.
|
the PM core are involved in runtime power management. As in the system
|
||||||
Of course, sometimes clusters of drivers will collaborate with each
|
sleep power management case, they need to collaborate by implementing
|
||||||
other, which could involve task-specific power management.
|
various role-specific suspend and resume methods, so that the hardware
|
||||||
|
is cleanly powered down and reactivated without data or service loss.
|
||||||
|
|
||||||
There's not a lot to be said about those low power states except that they
|
There's not a lot to be said about those low-power states except that they are
|
||||||
are very system-specific, and often device-specific. Also, that if enough
|
very system-specific, and often device-specific. Also, that if enough devices
|
||||||
drivers put themselves into low power states (at "runtime"), the effect may be
|
have been put into low-power states (at runtime), the effect may be very similar
|
||||||
the same as entering some system-wide low-power state (system sleep) ... and
|
to entering some system-wide low-power state (system sleep) ... and that
|
||||||
that synergies exist, so that several drivers using runtime pm might put the
|
synergies exist, so that several drivers using runtime PM might put the system
|
||||||
system into a state where even deeper power saving options are available.
|
into a state where even deeper power saving options are available.
|
||||||
|
|
||||||
Most suspended devices will have quiesced all I/O: no more DMA or irqs, no
|
Most suspended devices will have quiesced all I/O: no more DMA or IRQs (except
|
||||||
more data read or written, and requests from upstream drivers are no longer
|
for wakeup events), no more data read or written, and requests from upstream
|
||||||
accepted. A given bus or platform may have different requirements though.
|
drivers are no longer accepted. A given bus or platform may have different
|
||||||
|
requirements though.
|
||||||
|
|
||||||
Examples of hardware wakeup events include an alarm from a real time clock,
|
Examples of hardware wakeup events include an alarm from a real time clock,
|
||||||
network wake-on-LAN packets, keyboard or mouse activity, and media insertion
|
network wake-on-LAN packets, keyboard or mouse activity, and media insertion
|
||||||
@@ -60,129 +75,152 @@ or removal (for PCMCIA, MMC/SD, USB, and so on).
|
|||||||
|
|
||||||
Interfaces for Entering System Sleep States
|
Interfaces for Entering System Sleep States
|
||||||
===========================================
|
===========================================
|
||||||
Most of the programming interfaces a device driver needs to know about
|
There are programming interfaces provided for subsystems (bus type, device type,
|
||||||
relate to that first model: entering a system-wide low power state,
|
device class) and device drivers to allow them to participate in the power
|
||||||
rather than just minimizing power consumption by one device.
|
management of devices they are concerned with. These interfaces cover both
|
||||||
|
system sleep and runtime power management.
|
||||||
|
|
||||||
|
|
||||||
Bus Driver Methods
|
Device Power Management Operations
|
||||||
------------------
|
----------------------------------
|
||||||
The core methods to suspend and resume devices reside in struct bus_type.
|
Device power management operations, at the subsystem level as well as at the
|
||||||
These are mostly of interest to people writing infrastructure for busses
|
device driver level, are implemented by defining and populating objects of type
|
||||||
like PCI or USB, or because they define the primitives that device drivers
|
struct dev_pm_ops:
|
||||||
may need to apply in domain-specific ways to their devices:
|
|
||||||
|
|
||||||
struct bus_type {
|
struct dev_pm_ops {
|
||||||
...
|
int (*prepare)(struct device *dev);
|
||||||
int (*suspend)(struct device *dev, pm_message_t state);
|
void (*complete)(struct device *dev);
|
||||||
|
int (*suspend)(struct device *dev);
|
||||||
int (*resume)(struct device *dev);
|
int (*resume)(struct device *dev);
|
||||||
|
int (*freeze)(struct device *dev);
|
||||||
|
int (*thaw)(struct device *dev);
|
||||||
|
int (*poweroff)(struct device *dev);
|
||||||
|
int (*restore)(struct device *dev);
|
||||||
|
int (*suspend_noirq)(struct device *dev);
|
||||||
|
int (*resume_noirq)(struct device *dev);
|
||||||
|
int (*freeze_noirq)(struct device *dev);
|
||||||
|
int (*thaw_noirq)(struct device *dev);
|
||||||
|
int (*poweroff_noirq)(struct device *dev);
|
||||||
|
int (*restore_noirq)(struct device *dev);
|
||||||
|
int (*runtime_suspend)(struct device *dev);
|
||||||
|
int (*runtime_resume)(struct device *dev);
|
||||||
|
int (*runtime_idle)(struct device *dev);
|
||||||
};
|
};
|
||||||
|
|
||||||
Bus drivers implement those methods as appropriate for the hardware and
|
This structure is defined in include/linux/pm.h and the methods included in it
|
||||||
the drivers using it; PCI works differently from USB, and so on. Not many
|
are also described in that file. Their roles will be explained in what follows.
|
||||||
people write bus drivers; most driver code is a "device driver" that
|
For now, it should be sufficient to remember that the last three methods are
|
||||||
builds on top of bus-specific framework code.
|
specific to runtime power management while the remaining ones are used during
|
||||||
|
system-wide power transitions.
|
||||||
|
|
||||||
|
There also is a deprecated "old" or "legacy" interface for power management
|
||||||
|
operations available at least for some subsystems. This approach does not use
|
||||||
|
struct dev_pm_ops objects and it is suitable only for implementing system sleep
|
||||||
|
power management methods. Therefore it is not described in this document, so
|
||||||
|
please refer directly to the source code for more information about it.
|
||||||
|
|
||||||
|
|
||||||
|
Subsystem-Level Methods
|
||||||
|
-----------------------
|
||||||
|
The core methods to suspend and resume devices reside in struct dev_pm_ops
|
||||||
|
pointed to by the pm member of struct bus_type, struct device_type and
|
||||||
|
struct class. They are mostly of interest to the people writing infrastructure
|
||||||
|
for buses, like PCI or USB, or device type and device class drivers.
|
||||||
|
|
||||||
|
Bus drivers implement these methods as appropriate for the hardware and the
|
||||||
|
drivers using it; PCI works differently from USB, and so on. Not many people
|
||||||
|
write subsystem-level drivers; most driver code is a "device driver" that builds
|
||||||
|
on top of bus-specific framework code.
|
||||||
|
|
||||||
For more information on these driver calls, see the description later;
|
For more information on these driver calls, see the description later;
|
||||||
they are called in phases for every device, respecting the parent-child
|
they are called in phases for every device, respecting the parent-child
|
||||||
sequencing in the driver model tree. Note that as this is being written,
|
sequencing in the driver model tree.
|
||||||
only the suspend() and resume() are widely available; not many bus drivers
|
|
||||||
leverage all of those phases, or pass them down to lower driver levels.
|
|
||||||
|
|
||||||
|
|
||||||
/sys/devices/.../power/wakeup files
|
/sys/devices/.../power/wakeup files
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
All devices in the driver model have two flags to control handling of
|
All devices in the driver model have two flags to control handling of wakeup
|
||||||
wakeup events, which are hardware signals that can force the device and/or
|
events (hardware signals that can force the device and/or system out of a low
|
||||||
system out of a low power state. These are initialized by bus or device
|
power state). These flags are initialized by bus or device driver code using
|
||||||
driver code using device_init_wakeup(dev,can_wakeup).
|
device_set_wakeup_capable() and device_set_wakeup_enable(), defined in
|
||||||
|
include/linux/pm_wakeup.h.
|
||||||
|
|
||||||
The "can_wakeup" flag just records whether the device (and its driver) can
|
The "can_wakeup" flag just records whether the device (and its driver) can
|
||||||
physically support wakeup events. When that flag is clear, the sysfs
|
physically support wakeup events. The device_set_wakeup_capable() routine
|
||||||
"wakeup" file is empty, and device_may_wakeup() returns false.
|
affects this flag. The "should_wakeup" flag controls whether the device should
|
||||||
|
try to use its wakeup mechanism. device_set_wakeup_enable() affects this flag;
|
||||||
|
for the most part drivers should not change its value. The initial value of
|
||||||
|
should_wakeup is supposed to be false for the majority of devices; the major
|
||||||
|
exceptions are power buttons, keyboards, and Ethernet adapters whose WoL
|
||||||
|
(wake-on-LAN) feature has been set up with ethtool.
|
||||||
|
|
||||||
For devices that can issue wakeup events, a separate flag controls whether
|
Whether or not a device is capable of issuing wakeup events is a hardware
|
||||||
that device should try to use its wakeup mechanism. The initial value of
|
matter, and the kernel is responsible for keeping track of it. By contrast,
|
||||||
device_may_wakeup() will be true, so that the device's "wakeup" file holds
|
whether or not a wakeup-capable device should issue wakeup events is a policy
|
||||||
the value "enabled". Userspace can change that to "disabled" so that
|
decision, and it is managed by user space through a sysfs attribute: the
|
||||||
device_may_wakeup() returns false; or change it back to "enabled" (so that
|
power/wakeup file. User space can write the strings "enabled" or "disabled" to
|
||||||
it returns true again).
|
set or clear the should_wakeup flag, respectively. Reads from the file will
|
||||||
|
return the corresponding string if can_wakeup is true, but if can_wakeup is
|
||||||
|
false then reads will return an empty string, to indicate that the device
|
||||||
|
doesn't support wakeup events. (But even though the file appears empty, writes
|
||||||
|
will still affect the should_wakeup flag.)
|
||||||
|
|
||||||
|
The device_may_wakeup() routine returns true only if both flags are set.
|
||||||
|
Drivers should check this routine when putting devices in a low-power state
|
||||||
|
during a system sleep transition, to see whether or not to enable the devices'
|
||||||
|
wakeup mechanisms. However for runtime power management, wakeup events should
|
||||||
|
be enabled whenever the device and driver both support them, regardless of the
|
||||||
|
should_wakeup flag.
|
||||||
|
|
||||||
|
|
||||||
EXAMPLE: PCI Device Driver Methods
|
/sys/devices/.../power/control files
|
||||||
-----------------------------------
|
------------------------------------
|
||||||
PCI framework software calls these methods when the PCI device driver bound
|
Each device in the driver model has a flag to control whether it is subject to
|
||||||
to a device device has provided them:
|
runtime power management. This flag, called runtime_auto, is initialized by the
|
||||||
|
bus type (or generally subsystem) code using pm_runtime_allow() or
|
||||||
|
pm_runtime_forbid(); the default is to allow runtime power management.
|
||||||
|
|
||||||
struct pci_driver {
|
The setting can be adjusted by user space by writing either "on" or "auto" to
|
||||||
...
|
the device's power/control sysfs file. Writing "auto" calls pm_runtime_allow(),
|
||||||
int (*suspend)(struct pci_device *pdev, pm_message_t state);
|
setting the flag and allowing the device to be runtime power-managed by its
|
||||||
int (*suspend_late)(struct pci_device *pdev, pm_message_t state);
|
driver. Writing "on" calls pm_runtime_forbid(), clearing the flag, returning
|
||||||
|
the device to full power if it was in a low-power state, and preventing the
|
||||||
|
device from being runtime power-managed. User space can check the current value
|
||||||
|
of the runtime_auto flag by reading the file.
|
||||||
|
|
||||||
int (*resume_early)(struct pci_device *pdev);
|
The device's runtime_auto flag has no effect on the handling of system-wide
|
||||||
int (*resume)(struct pci_device *pdev);
|
power transitions. In particular, the device can (and in the majority of cases
|
||||||
};
|
should and will) be put into a low-power state during a system-wide transition
|
||||||
|
to a sleep state even though its runtime_auto flag is clear.
|
||||||
|
|
||||||
Drivers will implement those methods, and call PCI-specific procedures
|
For more information about the runtime power management framework, refer to
|
||||||
like pci_set_power_state(), pci_enable_wake(), pci_save_state(), and
|
Documentation/power/runtime_pm.txt.
|
||||||
pci_restore_state() to manage PCI-specific mechanisms. (PCI config space
|
|
||||||
could be saved during driver probe, if it weren't for the fact that some
|
|
||||||
systems rely on userspace tweaking using setpci.) Devices are suspended
|
|
||||||
before their bridges enter low power states, and likewise bridges resume
|
|
||||||
before their devices.
|
|
||||||
|
|
||||||
|
|
||||||
Upper Layers of Driver Stacks
|
Calling Drivers to Enter and Leave System Sleep States
|
||||||
-----------------------------
|
======================================================
|
||||||
Device drivers generally have at least two interfaces, and the methods
|
When the system goes into a sleep state, each device's driver is asked to
|
||||||
sketched above are the ones which apply to the lower level (nearer PCI, USB,
|
suspend the device by putting it into a state compatible with the target
|
||||||
or other bus hardware). The network and block layers are examples of upper
|
|
||||||
level interfaces, as is a character device talking to userspace.
|
|
||||||
|
|
||||||
Power management requests normally need to flow through those upper levels,
|
|
||||||
which often use domain-oriented requests like "blank that screen". In
|
|
||||||
some cases those upper levels will have power management intelligence that
|
|
||||||
relates to end-user activity, or other devices that work in cooperation.
|
|
||||||
|
|
||||||
When those interfaces are structured using class interfaces, there is a
|
|
||||||
standard way to have the upper layer stop issuing requests to a given
|
|
||||||
class device (and restart later):
|
|
||||||
|
|
||||||
struct class {
|
|
||||||
...
|
|
||||||
int (*suspend)(struct device *dev, pm_message_t state);
|
|
||||||
int (*resume)(struct device *dev);
|
|
||||||
};
|
|
||||||
|
|
||||||
Those calls are issued in specific phases of the process by which the
|
|
||||||
system enters a low power "suspend" state, or resumes from it.
|
|
||||||
|
|
||||||
|
|
||||||
Calling Drivers to Enter System Sleep States
|
|
||||||
============================================
|
|
||||||
When the system enters a low power state, each device's driver is asked
|
|
||||||
to suspend the device by putting it into state compatible with the target
|
|
||||||
system state. That's usually some version of "off", but the details are
|
system state. That's usually some version of "off", but the details are
|
||||||
system-specific. Also, wakeup-enabled devices will usually stay partly
|
system-specific. Also, wakeup-enabled devices will usually stay partly
|
||||||
functional in order to wake the system.
|
functional in order to wake the system.
|
||||||
|
|
||||||
When the system leaves that low power state, the device's driver is asked
|
When the system leaves that low-power state, the device's driver is asked to
|
||||||
to resume it. The suspend and resume operations always go together, and
|
resume it by returning it to full power. The suspend and resume operations
|
||||||
both are multi-phase operations.
|
always go together, and both are multi-phase operations.
|
||||||
|
|
||||||
For simple drivers, suspend might quiesce the device using the class code
|
For simple drivers, suspend might quiesce the device using class code
|
||||||
and then turn its hardware as "off" as possible with late_suspend. The
|
and then turn its hardware as "off" as possible during suspend_noirq. The
|
||||||
matching resume calls would then completely reinitialize the hardware
|
matching resume calls would then completely reinitialize the hardware
|
||||||
before reactivating its class I/O queues.
|
before reactivating its class I/O queues.
|
||||||
|
|
||||||
More power-aware drivers drivers will use more than one device low power
|
More power-aware drivers might prepare the devices for triggering system wakeup
|
||||||
state, either at runtime or during system sleep states, and might trigger
|
events.
|
||||||
system wakeup events.
|
|
||||||
|
|
||||||
|
|
||||||
Call Sequence Guarantees
|
Call Sequence Guarantees
|
||||||
------------------------
|
------------------------
|
||||||
To ensure that bridges and similar links needed to talk to a device are
|
To ensure that bridges and similar links needing to talk to a device are
|
||||||
available when the device is suspended or resumed, the device tree is
|
available when the device is suspended or resumed, the device tree is
|
||||||
walked in a bottom-up order to suspend devices. A top-down order is
|
walked in a bottom-up order to suspend devices. A top-down order is
|
||||||
used to resume those devices.
|
used to resume those devices.
|
||||||
@@ -194,67 +232,310 @@ its parent; and can't be removed or suspended after that parent.
|
|||||||
The policy is that the device tree should match hardware bus topology.
|
The policy is that the device tree should match hardware bus topology.
|
||||||
(Or at least the control bus, for devices which use multiple busses.)
|
(Or at least the control bus, for devices which use multiple busses.)
|
||||||
In particular, this means that a device registration may fail if the parent of
|
In particular, this means that a device registration may fail if the parent of
|
||||||
the device is suspending (ie. has been chosen by the PM core as the next
|
the device is suspending (i.e. has been chosen by the PM core as the next
|
||||||
device to suspend) or has already suspended, as well as after all of the other
|
device to suspend) or has already suspended, as well as after all of the other
|
||||||
devices have been suspended. Device drivers must be prepared to cope with such
|
devices have been suspended. Device drivers must be prepared to cope with such
|
||||||
situations.
|
situations.
|
||||||
|
|
||||||
|
|
||||||
Suspending Devices
|
System Power Management Phases
|
||||||
------------------
|
------------------------------
|
||||||
Suspending a given device is done in several phases. Suspending the
|
Suspending or resuming the system is done in several phases. Different phases
|
||||||
system always includes every phase, executing calls for every device
|
are used for standby or memory sleep states ("suspend-to-RAM") and the
|
||||||
before the next phase begins. Not all busses or classes support all
|
hibernation state ("suspend-to-disk"). Each phase involves executing callbacks
|
||||||
these callbacks; and not all drivers use all the callbacks.
|
for every device before the next phase begins. Not all busses or classes
|
||||||
|
support all these callbacks and not all drivers use all the callbacks. The
|
||||||
|
various phases always run after tasks have been frozen and before they are
|
||||||
|
unfrozen. Furthermore, the *_noirq phases run at a time when IRQ handlers have
|
||||||
|
been disabled (except for those marked with the IRQ_WAKEUP flag).
|
||||||
|
|
||||||
The phases are seen by driver notifications issued in this order:
|
Most phases use bus, type, and class callbacks (that is, methods defined in
|
||||||
|
dev->bus->pm, dev->type->pm, and dev->class->pm). The prepare and complete
|
||||||
|
phases are exceptions; they use only bus callbacks. When multiple callbacks
|
||||||
|
are used in a phase, they are invoked in the order: <class, type, bus> during
|
||||||
|
power-down transitions and in the opposite order during power-up transitions.
|
||||||
|
For example, during the suspend phase the PM core invokes
|
||||||
|
|
||||||
1 class.suspend(dev, message) is called after tasks are frozen, for
|
dev->class->pm.suspend(dev);
|
||||||
devices associated with a class that has such a method. This
|
dev->type->pm.suspend(dev);
|
||||||
method may sleep.
|
dev->bus->pm.suspend(dev);
|
||||||
|
|
||||||
Since I/O activity usually comes from such higher layers, this is
|
before moving on to the next device, whereas during the resume phase the core
|
||||||
a good place to quiesce all drivers of a given type (and keep such
|
invokes
|
||||||
code out of those drivers).
|
|
||||||
|
|
||||||
2 bus.suspend(dev, message) is called next. This method may sleep,
|
dev->bus->pm.resume(dev);
|
||||||
and is often morphed into a device driver call with bus-specific
|
dev->type->pm.resume(dev);
|
||||||
parameters and/or rules.
|
dev->class->pm.resume(dev);
|
||||||
|
|
||||||
This call should handle parts of device suspend logic that require
|
These callbacks may in turn invoke device- or driver-specific methods stored in
|
||||||
sleeping. It probably does work to quiesce the device which hasn't
|
dev->driver->pm, but they don't have to.
|
||||||
been abstracted into class.suspend().
|
|
||||||
|
|
||||||
The pm_message_t parameter is currently used to refine those semantics
|
|
||||||
(described later).
|
|
||||||
|
|
||||||
At the end of those phases, drivers should normally have stopped all I/O
|
Entering System Suspend
|
||||||
transactions (DMA, IRQs), saved enough state that they can re-initialize
|
-----------------------
|
||||||
or restore previous state (as needed by the hardware), and placed the
|
When the system goes into the standby or memory sleep state, the phases are:
|
||||||
device into a low-power state. On many platforms they will also use
|
|
||||||
clk_disable() to gate off one or more clock sources; sometimes they will
|
|
||||||
also switch off power supplies, or reduce voltages. Drivers which have
|
|
||||||
runtime PM support may already have performed some or all of the steps
|
|
||||||
needed to prepare for the upcoming system sleep state.
|
|
||||||
|
|
||||||
When any driver sees that its device_can_wakeup(dev), it should make sure
|
prepare, suspend, suspend_noirq.
|
||||||
to use the relevant hardware signals to trigger a system wakeup event.
|
|
||||||
For example, enable_irq_wake() might identify GPIO signals hooked up to
|
|
||||||
a switch or other external hardware, and pci_enable_wake() does something
|
|
||||||
similar for PCI's PME# signal.
|
|
||||||
|
|
||||||
If a driver (or bus, or class) fails it suspend method, the system won't
|
1. The prepare phase is meant to prevent races by preventing new devices
|
||||||
enter the desired low power state; it will resume all the devices it's
|
from being registered; the PM core would never know that all the
|
||||||
suspended so far.
|
children of a device had been suspended if new children could be
|
||||||
|
registered at will. (By contrast, devices may be unregistered at any
|
||||||
|
time.) Unlike the other suspend-related phases, during the prepare
|
||||||
|
phase the device tree is traversed top-down.
|
||||||
|
|
||||||
Note that drivers may need to perform different actions based on the target
|
The prepare phase uses only a bus callback. After the callback method
|
||||||
system lowpower/sleep state. At this writing, there are only platform
|
returns, no new children may be registered below the device. The method
|
||||||
specific APIs through which drivers could determine those target states.
|
may also prepare the device or driver in some way for the upcoming
|
||||||
|
system power transition, but it should not put the device into a
|
||||||
|
low-power state.
|
||||||
|
|
||||||
|
2. The suspend methods should quiesce the device to stop it from performing
|
||||||
|
I/O. They also may save the device registers and put it into the
|
||||||
|
appropriate low-power state, depending on the bus type the device is on,
|
||||||
|
and they may enable wakeup events.
|
||||||
|
|
||||||
|
3. The suspend_noirq phase occurs after IRQ handlers have been disabled,
|
||||||
|
which means that the driver's interrupt handler will not be called while
|
||||||
|
the callback method is running. The methods should save the values of
|
||||||
|
the device's registers that weren't saved previously and finally put the
|
||||||
|
device into the appropriate low-power state.
|
||||||
|
|
||||||
|
The majority of subsystems and device drivers need not implement this
|
||||||
|
callback. However, bus types allowing devices to share interrupt
|
||||||
|
vectors, like PCI, generally need it; otherwise a driver might encounter
|
||||||
|
an error during the suspend phase by fielding a shared interrupt
|
||||||
|
generated by some other device after its own device had been set to low
|
||||||
|
power.
|
||||||
|
|
||||||
|
At the end of these phases, drivers should have stopped all I/O transactions
|
||||||
|
(DMA, IRQs), saved enough state that they can re-initialize or restore previous
|
||||||
|
state (as needed by the hardware), and placed the device into a low-power state.
|
||||||
|
On many platforms they will gate off one or more clock sources; sometimes they
|
||||||
|
will also switch off power supplies or reduce voltages. (Drivers supporting
|
||||||
|
runtime PM may already have performed some or all of these steps.)
|
||||||
|
|
||||||
|
If device_may_wakeup(dev) returns true, the device should be prepared for
|
||||||
|
generating hardware wakeup signals to trigger a system wakeup event when the
|
||||||
|
system is in the sleep state. For example, enable_irq_wake() might identify
|
||||||
|
GPIO signals hooked up to a switch or other external hardware, and
|
||||||
|
pci_enable_wake() does something similar for the PCI PME signal.
|
||||||
|
|
||||||
|
If any of these callbacks returns an error, the system won't enter the desired
|
||||||
|
low-power state. Instead the PM core will unwind its actions by resuming all
|
||||||
|
the devices that were suspended.
|
||||||
|
|
||||||
|
|
||||||
|
Leaving System Suspend
|
||||||
|
----------------------
|
||||||
|
When resuming from standby or memory sleep, the phases are:
|
||||||
|
|
||||||
|
resume_noirq, resume, complete.
|
||||||
|
|
||||||
|
1. The resume_noirq callback methods should perform any actions needed
|
||||||
|
before the driver's interrupt handlers are invoked. This generally
|
||||||
|
means undoing the actions of the suspend_noirq phase. If the bus type
|
||||||
|
permits devices to share interrupt vectors, like PCI, the method should
|
||||||
|
bring the device and its driver into a state in which the driver can
|
||||||
|
recognize if the device is the source of incoming interrupts, if any,
|
||||||
|
and handle them correctly.
|
||||||
|
|
||||||
|
For example, the PCI bus type's ->pm.resume_noirq() puts the device into
|
||||||
|
the full-power state (D0 in the PCI terminology) and restores the
|
||||||
|
standard configuration registers of the device. Then it calls the
|
||||||
|
device driver's ->pm.resume_noirq() method to perform device-specific
|
||||||
|
actions.
|
||||||
|
|
||||||
|
2. The resume methods should bring the the device back to its operating
|
||||||
|
state, so that it can perform normal I/O. This generally involves
|
||||||
|
undoing the actions of the suspend phase.
|
||||||
|
|
||||||
|
3. The complete phase uses only a bus callback. The method should undo the
|
||||||
|
actions of the prepare phase. Note, however, that new children may be
|
||||||
|
registered below the device as soon as the resume callbacks occur; it's
|
||||||
|
not necessary to wait until the complete phase.
|
||||||
|
|
||||||
|
At the end of these phases, drivers should be as functional as they were before
|
||||||
|
suspending: I/O can be performed using DMA and IRQs, and the relevant clocks are
|
||||||
|
gated on. Even if the device was in a low-power state before the system sleep
|
||||||
|
because of runtime power management, afterwards it should be back in its
|
||||||
|
full-power state. There are multiple reasons why it's best to do this; they are
|
||||||
|
discussed in more detail in Documentation/power/runtime_pm.txt.
|
||||||
|
|
||||||
|
However, the details here may again be platform-specific. For example,
|
||||||
|
some systems support multiple "run" states, and the mode in effect at
|
||||||
|
the end of resume might not be the one which preceded suspension.
|
||||||
|
That means availability of certain clocks or power supplies changed,
|
||||||
|
which could easily affect how a driver works.
|
||||||
|
|
||||||
|
Drivers need to be able to handle hardware which has been reset since the
|
||||||
|
suspend methods were called, for example by complete reinitialization.
|
||||||
|
This may be the hardest part, and the one most protected by NDA'd documents
|
||||||
|
and chip errata. It's simplest if the hardware state hasn't changed since
|
||||||
|
the suspend was carried out, but that can't be guaranteed (in fact, it ususally
|
||||||
|
is not the case).
|
||||||
|
|
||||||
|
Drivers must also be prepared to notice that the device has been removed
|
||||||
|
while the system was powered down, whenever that's physically possible.
|
||||||
|
PCMCIA, MMC, USB, Firewire, SCSI, and even IDE are common examples of busses
|
||||||
|
where common Linux platforms will see such removal. Details of how drivers
|
||||||
|
will notice and handle such removals are currently bus-specific, and often
|
||||||
|
involve a separate thread.
|
||||||
|
|
||||||
|
These callbacks may return an error value, but the PM core will ignore such
|
||||||
|
errors since there's nothing it can do about them other than printing them in
|
||||||
|
the system log.
|
||||||
|
|
||||||
|
|
||||||
|
Entering Hibernation
|
||||||
|
--------------------
|
||||||
|
Hibernating the system is more complicated than putting it into the standby or
|
||||||
|
memory sleep state, because it involves creating and saving a system image.
|
||||||
|
Therefore there are more phases for hibernation, with a different set of
|
||||||
|
callbacks. These phases always run after tasks have been frozen and memory has
|
||||||
|
been freed.
|
||||||
|
|
||||||
|
The general procedure for hibernation is to quiesce all devices (freeze), create
|
||||||
|
an image of the system memory while everything is stable, reactivate all
|
||||||
|
devices (thaw), write the image to permanent storage, and finally shut down the
|
||||||
|
system (poweroff). The phases used to accomplish this are:
|
||||||
|
|
||||||
|
prepare, freeze, freeze_noirq, thaw_noirq, thaw, complete,
|
||||||
|
prepare, poweroff, poweroff_noirq
|
||||||
|
|
||||||
|
1. The prepare phase is discussed in the "Entering System Suspend" section
|
||||||
|
above.
|
||||||
|
|
||||||
|
2. The freeze methods should quiesce the device so that it doesn't generate
|
||||||
|
IRQs or DMA, and they may need to save the values of device registers.
|
||||||
|
However the device does not have to be put in a low-power state, and to
|
||||||
|
save time it's best not to do so. Also, the device should not be
|
||||||
|
prepared to generate wakeup events.
|
||||||
|
|
||||||
|
3. The freeze_noirq phase is analogous to the suspend_noirq phase discussed
|
||||||
|
above, except again that the device should not be put in a low-power
|
||||||
|
state and should not be allowed to generate wakeup events.
|
||||||
|
|
||||||
|
At this point the system image is created. All devices should be inactive and
|
||||||
|
the contents of memory should remain undisturbed while this happens, so that the
|
||||||
|
image forms an atomic snapshot of the system state.
|
||||||
|
|
||||||
|
4. The thaw_noirq phase is analogous to the resume_noirq phase discussed
|
||||||
|
above. The main difference is that its methods can assume the device is
|
||||||
|
in the same state as at the end of the freeze_noirq phase.
|
||||||
|
|
||||||
|
5. The thaw phase is analogous to the resume phase discussed above. Its
|
||||||
|
methods should bring the device back to an operating state, so that it
|
||||||
|
can be used for saving the image if necessary.
|
||||||
|
|
||||||
|
6. The complete phase is discussed in the "Leaving System Suspend" section
|
||||||
|
above.
|
||||||
|
|
||||||
|
At this point the system image is saved, and the devices then need to be
|
||||||
|
prepared for the upcoming system shutdown. This is much like suspending them
|
||||||
|
before putting the system into the standby or memory sleep state, and the phases
|
||||||
|
are similar.
|
||||||
|
|
||||||
|
7. The prepare phase is discussed above.
|
||||||
|
|
||||||
|
8. The poweroff phase is analogous to the suspend phase.
|
||||||
|
|
||||||
|
9. The poweroff_noirq phase is analogous to the suspend_noirq phase.
|
||||||
|
|
||||||
|
The poweroff and poweroff_noirq callbacks should do essentially the same things
|
||||||
|
as the suspend and suspend_noirq callbacks. The only notable difference is that
|
||||||
|
they need not store the device register values, because the registers should
|
||||||
|
already have been stored during the freeze or freeze_noirq phases.
|
||||||
|
|
||||||
|
|
||||||
|
Leaving Hibernation
|
||||||
|
-------------------
|
||||||
|
Resuming from hibernation is, again, more complicated than resuming from a sleep
|
||||||
|
state in which the contents of main memory are preserved, because it requires
|
||||||
|
a system image to be loaded into memory and the pre-hibernation memory contents
|
||||||
|
to be restored before control can be passed back to the image kernel.
|
||||||
|
|
||||||
|
Although in principle, the image might be loaded into memory and the
|
||||||
|
pre-hibernation memory contents restored by the boot loader, in practice this
|
||||||
|
can't be done because boot loaders aren't smart enough and there is no
|
||||||
|
established protocol for passing the necessary information. So instead, the
|
||||||
|
boot loader loads a fresh instance of the kernel, called the boot kernel, into
|
||||||
|
memory and passes control to it in the usual way. Then the boot kernel reads
|
||||||
|
the system image, restores the pre-hibernation memory contents, and passes
|
||||||
|
control to the image kernel. Thus two different kernels are involved in
|
||||||
|
resuming from hibernation. In fact, the boot kernel may be completely different
|
||||||
|
from the image kernel: a different configuration and even a different version.
|
||||||
|
This has important consequences for device drivers and their subsystems.
|
||||||
|
|
||||||
|
To be able to load the system image into memory, the boot kernel needs to
|
||||||
|
include at least a subset of device drivers allowing it to access the storage
|
||||||
|
medium containing the image, although it doesn't need to include all of the
|
||||||
|
drivers present in the image kernel. After the image has been loaded, the
|
||||||
|
devices managed by the boot kernel need to be prepared for passing control back
|
||||||
|
to the image kernel. This is very similar to the initial steps involved in
|
||||||
|
creating a system image, and it is accomplished in the same way, using prepare,
|
||||||
|
freeze, and freeze_noirq phases. However the devices affected by these phases
|
||||||
|
are only those having drivers in the boot kernel; other devices will still be in
|
||||||
|
whatever state the boot loader left them.
|
||||||
|
|
||||||
|
Should the restoration of the pre-hibernation memory contents fail, the boot
|
||||||
|
kernel would go through the "thawing" procedure described above, using the
|
||||||
|
thaw_noirq, thaw, and complete phases, and then continue running normally. This
|
||||||
|
happens only rarely. Most often the pre-hibernation memory contents are
|
||||||
|
restored successfully and control is passed to the image kernel, which then
|
||||||
|
becomes responsible for bringing the system back to the working state.
|
||||||
|
|
||||||
|
To achieve this, the image kernel must restore the devices' pre-hibernation
|
||||||
|
functionality. The operation is much like waking up from the memory sleep
|
||||||
|
state, although it involves different phases:
|
||||||
|
|
||||||
|
restore_noirq, restore, complete
|
||||||
|
|
||||||
|
1. The restore_noirq phase is analogous to the resume_noirq phase.
|
||||||
|
|
||||||
|
2. The restore phase is analogous to the resume phase.
|
||||||
|
|
||||||
|
3. The complete phase is discussed above.
|
||||||
|
|
||||||
|
The main difference from resume[_noirq] is that restore[_noirq] must assume the
|
||||||
|
device has been accessed and reconfigured by the boot loader or the boot kernel.
|
||||||
|
Consequently the state of the device may be different from the state remembered
|
||||||
|
from the freeze and freeze_noirq phases. The device may even need to be reset
|
||||||
|
and completely re-initialized. In many cases this difference doesn't matter, so
|
||||||
|
the resume[_noirq] and restore[_norq] method pointers can be set to the same
|
||||||
|
routines. Nevertheless, different callback pointers are used in case there is a
|
||||||
|
situation where it actually matters.
|
||||||
|
|
||||||
|
|
||||||
|
System Devices
|
||||||
|
--------------
|
||||||
|
System devices (sysdevs) follow a slightly different API, which can be found in
|
||||||
|
|
||||||
|
include/linux/sysdev.h
|
||||||
|
drivers/base/sys.c
|
||||||
|
|
||||||
|
System devices will be suspended with interrupts disabled, and after all other
|
||||||
|
devices have been suspended. On resume, they will be resumed before any other
|
||||||
|
devices, and also with interrupts disabled. These things occur in special
|
||||||
|
"sysdev_driver" phases, which affect only system devices.
|
||||||
|
|
||||||
|
Thus, after the suspend_noirq (or freeze_noirq or poweroff_noirq) phase, when
|
||||||
|
the non-boot CPUs are all offline and IRQs are disabled on the remaining online
|
||||||
|
CPU, then a sysdev_driver.suspend phase is carried out, and the system enters a
|
||||||
|
sleep state (or a system image is created). During resume (or after the image
|
||||||
|
has been created or loaded) a sysdev_driver.resume phase is carried out, IRQs
|
||||||
|
are enabled on the only online CPU, the non-boot CPUs are enabled, and the
|
||||||
|
resume_noirq (or thaw_noirq or restore_noirq) phase begins.
|
||||||
|
|
||||||
|
Code to actually enter and exit the system-wide low power state sometimes
|
||||||
|
involves hardware details that are only known to the boot firmware, and
|
||||||
|
may leave a CPU running software (from SRAM or flash memory) that monitors
|
||||||
|
the system and manages its wakeup sequence.
|
||||||
|
|
||||||
|
|
||||||
Device Low Power (suspend) States
|
Device Low Power (suspend) States
|
||||||
---------------------------------
|
---------------------------------
|
||||||
Device low-power states aren't very standard. One device might only handle
|
Device low-power states aren't standard. One device might only handle
|
||||||
"on" and "off, while another might support a dozen different versions of
|
"on" and "off, while another might support a dozen different versions of
|
||||||
"on" (how many engines are active?), plus a state that gets back to "on"
|
"on" (how many engines are active?), plus a state that gets back to "on"
|
||||||
faster than from a full "off".
|
faster than from a full "off".
|
||||||
@@ -265,7 +546,7 @@ PCI device may not perform DMA or issue IRQs, and any wakeup events it
|
|||||||
issues would be issued through the PME# bus signal. Plus, there are
|
issues would be issued through the PME# bus signal. Plus, there are
|
||||||
several PCI-standard device states, some of which are optional.
|
several PCI-standard device states, some of which are optional.
|
||||||
|
|
||||||
In contrast, integrated system-on-chip processors often use irqs as the
|
In contrast, integrated system-on-chip processors often use IRQs as the
|
||||||
wakeup event sources (so drivers would call enable_irq_wake) and might
|
wakeup event sources (so drivers would call enable_irq_wake) and might
|
||||||
be able to treat DMA completion as a wakeup event (sometimes DMA can stay
|
be able to treat DMA completion as a wakeup event (sometimes DMA can stay
|
||||||
active too, it'd only be the CPU and some peripherals that sleep).
|
active too, it'd only be the CPU and some peripherals that sleep).
|
||||||
@@ -284,120 +565,17 @@ ways; the aforementioned LCD might be active in one product's "standby",
|
|||||||
but a different product using the same SOC might work differently.
|
but a different product using the same SOC might work differently.
|
||||||
|
|
||||||
|
|
||||||
Meaning of pm_message_t.event
|
Power Management Notifiers
|
||||||
-----------------------------
|
--------------------------
|
||||||
Parameters to suspend calls include the device affected and a message of
|
There are some operations that cannot be carried out by the power management
|
||||||
type pm_message_t, which has one field: the event. If driver does not
|
callbacks discussed above, because the callbacks occur too late or too early.
|
||||||
recognize the event code, suspend calls may abort the request and return
|
To handle these cases, subsystems and device drivers may register power
|
||||||
a negative errno. However, most drivers will be fine if they implement
|
management notifiers that are called before tasks are frozen and after they have
|
||||||
PM_EVENT_SUSPEND semantics for all messages.
|
been thawed. Generally speaking, the PM notifiers are suitable for performing
|
||||||
|
actions that either require user space to be available, or at least won't
|
||||||
|
interfere with user space.
|
||||||
|
|
||||||
The event codes are used to refine the goal of suspending the device, and
|
For details refer to Documentation/power/notifiers.txt.
|
||||||
mostly matter when creating or resuming system memory image snapshots, as
|
|
||||||
used with suspend-to-disk:
|
|
||||||
|
|
||||||
PM_EVENT_SUSPEND -- quiesce the driver and put hardware into a low-power
|
|
||||||
state. When used with system sleep states like "suspend-to-RAM" or
|
|
||||||
"standby", the upcoming resume() call will often be able to rely on
|
|
||||||
state kept in hardware, or issue system wakeup events.
|
|
||||||
|
|
||||||
PM_EVENT_HIBERNATE -- Put hardware into a low-power state and enable wakeup
|
|
||||||
events as appropriate. It is only used with hibernation
|
|
||||||
(suspend-to-disk) and few devices are able to wake up the system from
|
|
||||||
this state; most are completely powered off.
|
|
||||||
|
|
||||||
PM_EVENT_FREEZE -- quiesce the driver, but don't necessarily change into
|
|
||||||
any low power mode. A system snapshot is about to be taken, often
|
|
||||||
followed by a call to the driver's resume() method. Neither wakeup
|
|
||||||
events nor DMA are allowed.
|
|
||||||
|
|
||||||
PM_EVENT_PRETHAW -- quiesce the driver, knowing that the upcoming resume()
|
|
||||||
will restore a suspend-to-disk snapshot from a different kernel image.
|
|
||||||
Drivers that are smart enough to look at their hardware state during
|
|
||||||
resume() processing need that state to be correct ... a PRETHAW could
|
|
||||||
be used to invalidate that state (by resetting the device), like a
|
|
||||||
shutdown() invocation would before a kexec() or system halt. Other
|
|
||||||
drivers might handle this the same way as PM_EVENT_FREEZE. Neither
|
|
||||||
wakeup events nor DMA are allowed.
|
|
||||||
|
|
||||||
To enter "standby" (ACPI S1) or "Suspend to RAM" (STR, ACPI S3) states, or
|
|
||||||
the similarly named APM states, only PM_EVENT_SUSPEND is used; the other event
|
|
||||||
codes are used for hibernation ("Suspend to Disk", STD, ACPI S4).
|
|
||||||
|
|
||||||
There's also PM_EVENT_ON, a value which never appears as a suspend event
|
|
||||||
but is sometimes used to record the "not suspended" device state.
|
|
||||||
|
|
||||||
|
|
||||||
Resuming Devices
|
|
||||||
----------------
|
|
||||||
Resuming is done in multiple phases, much like suspending, with all
|
|
||||||
devices processing each phase's calls before the next phase begins.
|
|
||||||
|
|
||||||
The phases are seen by driver notifications issued in this order:
|
|
||||||
|
|
||||||
1 bus.resume(dev) reverses the effects of bus.suspend(). This may
|
|
||||||
be morphed into a device driver call with bus-specific parameters;
|
|
||||||
implementations may sleep.
|
|
||||||
|
|
||||||
2 class.resume(dev) is called for devices associated with a class
|
|
||||||
that has such a method. Implementations may sleep.
|
|
||||||
|
|
||||||
This reverses the effects of class.suspend(), and would usually
|
|
||||||
reactivate the device's I/O queue.
|
|
||||||
|
|
||||||
At the end of those phases, drivers should normally be as functional as
|
|
||||||
they were before suspending: I/O can be performed using DMA and IRQs, and
|
|
||||||
the relevant clocks are gated on. The device need not be "fully on"; it
|
|
||||||
might be in a runtime lowpower/suspend state that acts as if it were.
|
|
||||||
|
|
||||||
However, the details here may again be platform-specific. For example,
|
|
||||||
some systems support multiple "run" states, and the mode in effect at
|
|
||||||
the end of resume() might not be the one which preceded suspension.
|
|
||||||
That means availability of certain clocks or power supplies changed,
|
|
||||||
which could easily affect how a driver works.
|
|
||||||
|
|
||||||
|
|
||||||
Drivers need to be able to handle hardware which has been reset since the
|
|
||||||
suspend methods were called, for example by complete reinitialization.
|
|
||||||
This may be the hardest part, and the one most protected by NDA'd documents
|
|
||||||
and chip errata. It's simplest if the hardware state hasn't changed since
|
|
||||||
the suspend() was called, but that can't always be guaranteed.
|
|
||||||
|
|
||||||
Drivers must also be prepared to notice that the device has been removed
|
|
||||||
while the system was powered off, whenever that's physically possible.
|
|
||||||
PCMCIA, MMC, USB, Firewire, SCSI, and even IDE are common examples of busses
|
|
||||||
where common Linux platforms will see such removal. Details of how drivers
|
|
||||||
will notice and handle such removals are currently bus-specific, and often
|
|
||||||
involve a separate thread.
|
|
||||||
|
|
||||||
|
|
||||||
Note that the bus-specific runtime PM wakeup mechanism can exist, and might
|
|
||||||
be defined to share some of the same driver code as for system wakeup. For
|
|
||||||
example, a bus-specific device driver's resume() method might be used there,
|
|
||||||
so it wouldn't only be called from bus.resume() during system-wide wakeup.
|
|
||||||
See bus-specific information about how runtime wakeup events are handled.
|
|
||||||
|
|
||||||
|
|
||||||
System Devices
|
|
||||||
--------------
|
|
||||||
System devices follow a slightly different API, which can be found in
|
|
||||||
|
|
||||||
include/linux/sysdev.h
|
|
||||||
drivers/base/sys.c
|
|
||||||
|
|
||||||
System devices will only be suspended with interrupts disabled, and after
|
|
||||||
all other devices have been suspended. On resume, they will be resumed
|
|
||||||
before any other devices, and also with interrupts disabled.
|
|
||||||
|
|
||||||
That is, IRQs are disabled, the suspend_late() phase begins, then the
|
|
||||||
sysdev_driver.suspend() phase, and the system enters a sleep state. Then
|
|
||||||
the sysdev_driver.resume() phase begins, followed by the resume_early()
|
|
||||||
phase, after which IRQs are enabled.
|
|
||||||
|
|
||||||
Code to actually enter and exit the system-wide low power state sometimes
|
|
||||||
involves hardware details that are only known to the boot firmware, and
|
|
||||||
may leave a CPU running software (from SRAM or flash memory) that monitors
|
|
||||||
the system and manages its wakeup sequence.
|
|
||||||
|
|
||||||
|
|
||||||
Runtime Power Management
|
Runtime Power Management
|
||||||
@@ -407,82 +585,23 @@ running. This feature is useful for devices that are not being used, and
|
|||||||
can offer significant power savings on a running system. These devices
|
can offer significant power savings on a running system. These devices
|
||||||
often support a range of runtime power states, which might use names such
|
often support a range of runtime power states, which might use names such
|
||||||
as "off", "sleep", "idle", "active", and so on. Those states will in some
|
as "off", "sleep", "idle", "active", and so on. Those states will in some
|
||||||
cases (like PCI) be partially constrained by a bus the device uses, and will
|
cases (like PCI) be partially constrained by the bus the device uses, and will
|
||||||
usually include hardware states that are also used in system sleep states.
|
usually include hardware states that are also used in system sleep states.
|
||||||
|
|
||||||
However, note that if a driver puts a device into a runtime low power state
|
A system-wide power transition can be started while some devices are in low
|
||||||
and the system then goes into a system-wide sleep state, it normally ought
|
power states due to runtime power management. The system sleep PM callbacks
|
||||||
to resume into that runtime low power state rather than "full on". Such
|
should recognize such situations and react to them appropriately, but the
|
||||||
distinctions would be part of the driver-internal state machine for that
|
necessary actions are subsystem-specific.
|
||||||
hardware; the whole point of runtime power management is to be sure that
|
|
||||||
drivers are decoupled in that way from the state machine governing phases
|
|
||||||
of the system-wide power/sleep state transitions.
|
|
||||||
|
|
||||||
|
In some cases the decision may be made at the subsystem level while in other
|
||||||
|
cases the device driver may be left to decide. In some cases it may be
|
||||||
|
desirable to leave a suspended device in that state during a system-wide power
|
||||||
|
transition, but in other cases the device must be put back into the full-power
|
||||||
|
state temporarily, for example so that its system wakeup capability can be
|
||||||
|
disabled. This all depends on the hardware and the design of the subsystem and
|
||||||
|
device driver in question.
|
||||||
|
|
||||||
Power Saving Techniques
|
During system-wide resume from a sleep state it's best to put devices into the
|
||||||
-----------------------
|
full-power state, as explained in Documentation/power/runtime_pm.txt. Refer to
|
||||||
Normally runtime power management is handled by the drivers without specific
|
that document for more information regarding this particular issue as well as
|
||||||
userspace or kernel intervention, by device-aware use of techniques like:
|
for information on the device runtime power management framework in general.
|
||||||
|
|
||||||
Using information provided by other system layers
|
|
||||||
- stay deeply "off" except between open() and close()
|
|
||||||
- if transceiver/PHY indicates "nobody connected", stay "off"
|
|
||||||
- application protocols may include power commands or hints
|
|
||||||
|
|
||||||
Using fewer CPU cycles
|
|
||||||
- using DMA instead of PIO
|
|
||||||
- removing timers, or making them lower frequency
|
|
||||||
- shortening "hot" code paths
|
|
||||||
- eliminating cache misses
|
|
||||||
- (sometimes) offloading work to device firmware
|
|
||||||
|
|
||||||
Reducing other resource costs
|
|
||||||
- gating off unused clocks in software (or hardware)
|
|
||||||
- switching off unused power supplies
|
|
||||||
- eliminating (or delaying/merging) IRQs
|
|
||||||
- tuning DMA to use word and/or burst modes
|
|
||||||
|
|
||||||
Using device-specific low power states
|
|
||||||
- using lower voltages
|
|
||||||
- avoiding needless DMA transfers
|
|
||||||
|
|
||||||
Read your hardware documentation carefully to see the opportunities that
|
|
||||||
may be available. If you can, measure the actual power usage and check
|
|
||||||
it against the budget established for your project.
|
|
||||||
|
|
||||||
|
|
||||||
Examples: USB hosts, system timer, system CPU
|
|
||||||
----------------------------------------------
|
|
||||||
USB host controllers make interesting, if complex, examples. In many cases
|
|
||||||
these have no work to do: no USB devices are connected, or all of them are
|
|
||||||
in the USB "suspend" state. Linux host controller drivers can then disable
|
|
||||||
periodic DMA transfers that would otherwise be a constant power drain on the
|
|
||||||
memory subsystem, and enter a suspend state. In power-aware controllers,
|
|
||||||
entering that suspend state may disable the clock used with USB signaling,
|
|
||||||
saving a certain amount of power.
|
|
||||||
|
|
||||||
The controller will be woken from that state (with an IRQ) by changes to the
|
|
||||||
signal state on the data lines of a given port, for example by an existing
|
|
||||||
peripheral requesting "remote wakeup" or by plugging a new peripheral. The
|
|
||||||
same wakeup mechanism usually works from "standby" sleep states, and on some
|
|
||||||
systems also from "suspend to RAM" (or even "suspend to disk") states.
|
|
||||||
(Except that ACPI may be involved instead of normal IRQs, on some hardware.)
|
|
||||||
|
|
||||||
System devices like timers and CPUs may have special roles in the platform
|
|
||||||
power management scheme. For example, system timers using a "dynamic tick"
|
|
||||||
approach don't just save CPU cycles (by eliminating needless timer IRQs),
|
|
||||||
but they may also open the door to using lower power CPU "idle" states that
|
|
||||||
cost more than a jiffie to enter and exit. On x86 systems these are states
|
|
||||||
like "C3"; note that periodic DMA transfers from a USB host controller will
|
|
||||||
also prevent entry to a C3 state, much like a periodic timer IRQ.
|
|
||||||
|
|
||||||
That kind of runtime mechanism interaction is common. "System On Chip" (SOC)
|
|
||||||
processors often have low power idle modes that can't be entered unless
|
|
||||||
certain medium-speed clocks (often 12 or 48 MHz) are gated off. When the
|
|
||||||
drivers gate those clocks effectively, then the system idle task may be able
|
|
||||||
to use the lower power idle modes and thereby increase battery life.
|
|
||||||
|
|
||||||
If the CPU can have a "cpufreq" driver, there also may be opportunities
|
|
||||||
to shift to lower voltage settings and reduce the power cost of executing
|
|
||||||
a given number of instructions. (Without voltage adjustment, it's rare
|
|
||||||
for cpufreq to save much power; the cost-per-instruction must go down.)
|
|
||||||
|
|||||||
@@ -18,44 +18,46 @@ and pm_qos_params.h. This is done because having the available parameters
|
|||||||
being runtime configurable or changeable from a driver was seen as too easy to
|
being runtime configurable or changeable from a driver was seen as too easy to
|
||||||
abuse.
|
abuse.
|
||||||
|
|
||||||
For each parameter a list of performance requirements is maintained along with
|
For each parameter a list of performance requests is maintained along with
|
||||||
an aggregated target value. The aggregated target value is updated with
|
an aggregated target value. The aggregated target value is updated with
|
||||||
changes to the requirement list or elements of the list. Typically the
|
changes to the request list or elements of the list. Typically the
|
||||||
aggregated target value is simply the max or min of the requirement values held
|
aggregated target value is simply the max or min of the request values held
|
||||||
in the parameter list elements.
|
in the parameter list elements.
|
||||||
|
|
||||||
From kernel mode the use of this interface is simple:
|
From kernel mode the use of this interface is simple:
|
||||||
pm_qos_add_requirement(param_id, name, target_value):
|
|
||||||
Will insert a named element in the list for that identified PM_QOS parameter
|
|
||||||
with the target value. Upon change to this list the new target is recomputed
|
|
||||||
and any registered notifiers are called only if the target value is now
|
|
||||||
different.
|
|
||||||
|
|
||||||
pm_qos_update_requirement(param_id, name, new_target_value):
|
handle = pm_qos_add_request(param_class, target_value):
|
||||||
Will search the list identified by the param_id for the named list element and
|
Will insert an element into the list for that identified PM_QOS class with the
|
||||||
then update its target value, calling the notification tree if the aggregated
|
target value. Upon change to this list the new target is recomputed and any
|
||||||
target is changed. with that name is already registered.
|
registered notifiers are called only if the target value is now different.
|
||||||
|
Clients of pm_qos need to save the returned handle.
|
||||||
|
|
||||||
pm_qos_remove_requirement(param_id, name):
|
void pm_qos_update_request(handle, new_target_value):
|
||||||
Will search the identified list for the named element and remove it, after
|
Will update the list element pointed to by the handle with the new target value
|
||||||
removal it will update the aggregate target and call the notification tree if
|
and recompute the new aggregated target, calling the notification tree if the
|
||||||
the target was changed as a result of removing the named requirement.
|
target is changed.
|
||||||
|
|
||||||
|
void pm_qos_remove_request(handle):
|
||||||
|
Will remove the element. After removal it will update the aggregate target and
|
||||||
|
call the notification tree if the target was changed as a result of removing
|
||||||
|
the request.
|
||||||
|
|
||||||
|
|
||||||
From user mode:
|
From user mode:
|
||||||
Only processes can register a pm_qos requirement. To provide for automatic
|
Only processes can register a pm_qos request. To provide for automatic
|
||||||
cleanup for process the interface requires the process to register its
|
cleanup of a process, the interface requires the process to register its
|
||||||
parameter requirements in the following way:
|
parameter requests in the following way:
|
||||||
|
|
||||||
To register the default pm_qos target for the specific parameter, the process
|
To register the default pm_qos target for the specific parameter, the process
|
||||||
must open one of /dev/[cpu_dma_latency, network_latency, network_throughput]
|
must open one of /dev/[cpu_dma_latency, network_latency, network_throughput]
|
||||||
|
|
||||||
As long as the device node is held open that process has a registered
|
As long as the device node is held open that process has a registered
|
||||||
requirement on the parameter. The name of the requirement is "process_<PID>"
|
request on the parameter.
|
||||||
derived from the current->pid from within the open system call.
|
|
||||||
|
|
||||||
To change the requested target value the process needs to write a s32 value to
|
To change the requested target value the process needs to write an s32 value to
|
||||||
the open device node. This translates to a pm_qos_update_requirement call.
|
the open device node. Alternatively the user mode program could write a hex
|
||||||
|
string for the value using 10 char long format e.g. "0x12345678". This
|
||||||
|
translates to a pm_qos_update_request call.
|
||||||
|
|
||||||
To remove the user mode request for a target value simply close the device
|
To remove the user mode request for a target value simply close the device
|
||||||
node.
|
node.
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ Please see overview.txt for a description of the terms used in this text.
|
|||||||
1. Consumer Regulator Access (static & dynamic drivers)
|
1. Consumer Regulator Access (static & dynamic drivers)
|
||||||
=======================================================
|
=======================================================
|
||||||
|
|
||||||
A consumer driver can get access to it's supply regulator by calling :-
|
A consumer driver can get access to its supply regulator by calling :-
|
||||||
|
|
||||||
regulator = regulator_get(dev, "Vcc");
|
regulator = regulator_get(dev, "Vcc");
|
||||||
|
|
||||||
The consumer passes in it's struct device pointer and power supply ID. The core
|
The consumer passes in its struct device pointer and power supply ID. The core
|
||||||
then finds the correct regulator by consulting a machine specific lookup table.
|
then finds the correct regulator by consulting a machine specific lookup table.
|
||||||
If the lookup is successful then this call will return a pointer to the struct
|
If the lookup is successful then this call will return a pointer to the struct
|
||||||
regulator that supplies this consumer.
|
regulator that supplies this consumer.
|
||||||
@@ -34,7 +34,7 @@ usually be called in your device drivers probe() and remove() respectively.
|
|||||||
2. Regulator Output Enable & Disable (static & dynamic drivers)
|
2. Regulator Output Enable & Disable (static & dynamic drivers)
|
||||||
====================================================================
|
====================================================================
|
||||||
|
|
||||||
A consumer can enable it's power supply by calling:-
|
A consumer can enable its power supply by calling:-
|
||||||
|
|
||||||
int regulator_enable(regulator);
|
int regulator_enable(regulator);
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ int regulator_is_enabled(regulator);
|
|||||||
This will return > zero when the regulator is enabled.
|
This will return > zero when the regulator is enabled.
|
||||||
|
|
||||||
|
|
||||||
A consumer can disable it's supply when no longer needed by calling :-
|
A consumer can disable its supply when no longer needed by calling :-
|
||||||
|
|
||||||
int regulator_disable(regulator);
|
int regulator_disable(regulator);
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ by calling :-
|
|||||||
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
|
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
|
||||||
|
|
||||||
This will cause the core to recalculate the total load on the regulator (based
|
This will cause the core to recalculate the total load on the regulator (based
|
||||||
on all it's consumers) and change operating mode (if necessary and permitted)
|
on all its consumers) and change operating mode (if necessary and permitted)
|
||||||
to best match the current operating load.
|
to best match the current operating load.
|
||||||
|
|
||||||
The load_uA value can be determined from the consumers datasheet. e.g.most
|
The load_uA value can be determined from the consumers datasheet. e.g.most
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user