Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework

Conflicts:
	arch/sh/kernel/cpu/sh2/setup-sh7619.c
	arch/sh/kernel/cpu/sh2a/setup-mxg.c
	arch/sh/kernel/cpu/sh2a/setup-sh7201.c
	arch/sh/kernel/cpu/sh2a/setup-sh7203.c
	arch/sh/kernel/cpu/sh2a/setup-sh7206.c
	arch/sh/kernel/cpu/sh3/setup-sh7705.c
	arch/sh/kernel/cpu/sh3/setup-sh770x.c
	arch/sh/kernel/cpu/sh3/setup-sh7710.c
	arch/sh/kernel/cpu/sh3/setup-sh7720.c
	arch/sh/kernel/cpu/sh4/setup-sh4-202.c
	arch/sh/kernel/cpu/sh4/setup-sh7750.c
	arch/sh/kernel/cpu/sh4/setup-sh7760.c
	arch/sh/kernel/cpu/sh4a/setup-sh7343.c
	arch/sh/kernel/cpu/sh4a/setup-sh7366.c
	arch/sh/kernel/cpu/sh4a/setup-sh7722.c
	arch/sh/kernel/cpu/sh4a/setup-sh7723.c
	arch/sh/kernel/cpu/sh4a/setup-sh7724.c
	arch/sh/kernel/cpu/sh4a/setup-sh7763.c
	arch/sh/kernel/cpu/sh4a/setup-sh7770.c
	arch/sh/kernel/cpu/sh4a/setup-sh7780.c
	arch/sh/kernel/cpu/sh4a/setup-sh7785.c
	arch/sh/kernel/cpu/sh4a/setup-sh7786.c
	arch/sh/kernel/cpu/sh4a/setup-shx3.c
	arch/sh/kernel/cpu/sh5/setup-sh5.c
	drivers/serial/sh-sci.c
	drivers/serial/sh-sci.h
	include/linux/serial_sci.h
This commit is contained in:
Paul Mundt
2011-01-13 15:06:28 +09:00
26702 changed files with 4307403 additions and 2132644 deletions

28
.gitignore vendored
View File

@@ -22,35 +22,39 @@
*.lst
*.symtypes
*.order
modules.builtin
*.elf
*.bin
*.gz
*.bz2
*.lzma
*.lzo
*.patch
*.gcno
#
# Top-level generic files
#
tags
TAGS
vmlinux
System.map
Module.markers
Module.symvers
/tags
/TAGS
/linux
/vmlinux
/vmlinuz
/System.map
/Module.markers
/Module.symvers
#
# git files that we don't want to ignore even it they are dot-files
#
!.gitignore
!.mailmap
#
# Generated include files
#
include/asm
include/asm-*/asm-offsets.h
include/config
include/linux/autoconf.h
include/linux/compile.h
include/linux/version.h
include/linux/utsrelease.h
include/linux/bounds.h
include/generated
# stgit generated dirs

View File

@@ -105,3 +105,4 @@ Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
Uwe Kleine-König <ukl@pengutronix.de>
Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Takashi YOSHII <takashi.yoshii.zj@renesas.com>

20
CREDITS
View File

@@ -1856,7 +1856,7 @@ E: rfkoenig@immd4.informatik.uni-erlangen.de
D: The Linux Support Team Erlangen
N: Andreas Koensgen
E: ajk@iehk.rwth-aachen.de
E: ajk@comnets.uni-bremen.de
D: 6pack driver for AX.25
N: Harald Koerfgen
@@ -2006,6 +2006,9 @@ E: paul@laufernet.com
D: Soundblaster driver fixes, ISAPnP quirk
S: California, USA
N: Jonathan Layes
D: ARPD support
N: Tom Lees
E: tom@lpsg.demon.co.uk
W: http://www.lpsg.demon.co.uk/
@@ -2362,8 +2365,6 @@ E: acme@redhat.com
W: http://oops.ghostprotocols.net:81/blog/
P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01
D: IPX, LLC, DCCP, cyc2x, wl3501_cs, net/ hacks
S: R. Brasílio Itiberê, 4270/1010 - Água Verde
S: 80240-060 - Curitiba - Paraná
S: Brazil
N: Karsten Merker
@@ -2797,7 +2798,7 @@ D: Starter of Linux1394 effort
S: ask per mail for current address
N: Nicolas Pitre
E: nico@cam.org
E: nico@fluxnic.net
D: StrongARM SA1100 support integrator & hacker
D: Xscale PXA architecture
D: unified SMC 91C9x/91C11x ethernet driver (smc91x)
@@ -3551,12 +3552,12 @@ E: cvance@nai.com
D: portions of the Linux Security Module (LSM) framework and security modules
N: Petr Vandrovec
E: vandrove@vc.cvut.cz
E: petr@vandrovec.name
D: Small contributions to ncpfs
D: Matrox framebuffer driver
S: Chudenicka 8
S: 10200 Prague 10, Hostivar
S: Czech Republic
S: 21513 Conradia Ct
S: Cupertino, CA 95014
S: USA
N: Thibaut Varene
E: T-Bone@parisc-linux.org
@@ -3802,6 +3803,9 @@ S: van Bronckhorststraat 12
S: 2612 XV Delft
S: The Netherlands
N: Thomas Woller
D: CS461x Cirrus Logic sound driver
N: David Woodhouse
E: dwmw2@infradead.org
D: JFFS2 file system, Memory Technology Device subsystem,

7
Documentation/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
filesystems/dnotify_test
laptops/dslm
timers/hpet_example
vm/hugepage-mmap
vm/hugepage-shm
vm/map_hugetlb

View File

@@ -32,8 +32,6 @@ DocBook/
- directory with DocBook templates etc. for kernel documentation.
HOWTO
- the process and procedures of how to do Linux kernel development.
IO-mapping.txt
- how to access I/O mapped memory from within device drivers.
IPMI.txt
- info on Linux Intelligent Platform Management Interface (IPMI) Driver.
IRQ-affinity.txt
@@ -82,6 +80,10 @@ block/
- info on the Block I/O (BIO) layer.
blockdev/
- info on block devices & drivers
btmrvl.txt
- info on Marvell Bluetooth driver usage.
bus-virt-phys-mapping.txt
- how to access I/O mapped memory from within device drivers.
cachetlb.txt
- describes the cache/TLB flushing interfaces Linux uses.
cdrom/
@@ -128,8 +130,6 @@ edac.txt
- information on EDAC - Error Detection And Correction
eisa.txt
- info on EISA bus support.
exception.txt
- how Linux v2.2 handles exceptions without verify_area etc.
fault-injection/
- dir with docs about the fault injection capabilities infrastructure.
fb/
@@ -166,6 +166,8 @@ initrd.txt
- how to use the RAM disk as an initial/temporary root filesystem.
input/
- info on Linux input device support.
io-mapping.txt
- description of io_mapping functions in linux/io-mapping.h
io_ordering.txt
- info on ordering I/O writes to memory-mapped addresses.
ioctl/
@@ -230,6 +232,8 @@ memory.txt
- info on typical Linux memory problems.
mips/
- directory with info about Linux on MIPS architecture.
mmc/
- directory with info about the MMC subsystem
mono.txt
- how to execute Mono-based .NET binaries with the help of BINFMT_MISC.
mutex-design.txt
@@ -248,6 +252,8 @@ numastat.txt
- info on how to read Numa policy hit/miss statistics in sysfs.
oops-tracing.txt
- how to decode those nasty internal kernel error dump messages.
padata.txt
- An introduction to the "padata" parallel execution API
parisc/
- directory with info on using Linux on PA-RISC architecture.
parport.txt

View File

@@ -1,9 +0,0 @@
What: dv1394 (a.k.a. "OHCI-DV I/O support" for FireWire)
Contact: linux1394-devel@lists.sourceforge.net
Description:
New application development should use raw1394 + userspace libraries
instead, notably libiec61883 which is functionally equivalent.
Users:
ffmpeg/libavformat (used by a variety of media players)
dvgrab v1.x (replaced by dvgrab2 on top of raw1394 and resp. libraries)

View File

@@ -0,0 +1,22 @@
What: /proc/<pid>/oom_adj
When: August 2012
Why: /proc/<pid>/oom_adj allows userspace to influence the oom killer's
badness heuristic used to determine which task to kill when the kernel
is out of memory.
The badness heuristic has since been rewritten since the introduction of
this tunable such that its meaning is deprecated. The value was
implemented as a bitshift on a score generated by the badness()
function that did not have any precise units of measure. With the
rewrite, the score is given as a proportion of available memory to the
task allocating pages, so using a bitshift which grows the score
exponentially is, thus, impossible to tune with fine granularity.
A much more powerful interface, /proc/<pid>/oom_score_adj, was
introduced with the oom killer rewrite that allows users to increase or
decrease the badness() score linearly. This interface will replace
/proc/<pid>/oom_adj.
A warning will be emitted to the kernel log if an application uses this
deprecated interface. After it is printed once, future warnings will be
suppressed until the kernel is rebooted.

View 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.

View 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

View File

@@ -0,0 +1,14 @@
What: dv1394 (a.k.a. "OHCI-DV I/O support" for FireWire)
Date: May 2010 (scheduled), finally removed in kernel v2.6.37
Contact: linux1394-devel@lists.sourceforge.net
Description:
/dev/dv1394/* were character device files, one for each FireWire
controller and for NTSC and PAL respectively, from which DV data
could be received by read() or transmitted by write(). A few
ioctl()s allowed limited control.
This special-purpose interface has been superseded by libraw1394 +
libiec61883 which are functionally equivalent, support HDV, and
transparently work on top of the newer firewire kernel drivers.
Users:
ffmpeg/libavformat (if configured for DV1394)

View File

@@ -0,0 +1,15 @@
What: raw1394 (a.k.a. "Raw IEEE1394 I/O support" for FireWire)
Date: May 2010 (scheduled), finally removed in kernel v2.6.37
Contact: linux1394-devel@lists.sourceforge.net
Description:
/dev/raw1394 was a character device file that allowed low-level
access to FireWire buses. Its major drawbacks were its inability
to implement sensible device security policies, and its low level
of abstraction that required userspace clients do duplicate much
of the kernel's ieee1394 core functionality.
Replaced by /dev/fw*, i.e. the <linux/firewire-cdev.h> ABI of
firewire-core.
Users:
libraw1394 (works with firewire-cdev too, transparent to library ABI
users)

View File

@@ -1,16 +0,0 @@
What: legacy isochronous ABI of raw1394 (1st generation iso ABI)
Date: June 2007 (scheduled), removed in kernel v2.6.23
Contact: linux1394-devel@lists.sourceforge.net
Description:
The two request types RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN have
been deprecated for quite some time. They are very inefficient as they
come with high interrupt load and several layers of callbacks for each
packet. Because of these deficiencies, the video1394 and dv1394 drivers
and the 3rd-generation isochronous ABI in raw1394 (rawiso) were created.
Users:
libraw1394 users via the long deprecated API raw1394_iso_write,
raw1394_start_iso_write, raw1394_start_iso_rcv, raw1394_stop_iso_rcv
libdc1394, which optionally uses these old libraw1394 calls
alternatively to the more efficient video1394 ABI

View File

@@ -0,0 +1,16 @@
What: video1394 (a.k.a. "OHCI-1394 Video support" for FireWire)
Date: May 2010 (scheduled), finally removed in kernel v2.6.37
Contact: linux1394-devel@lists.sourceforge.net
Description:
/dev/video1394/* were character device files, one for each FireWire
controller, which were used for isochronous I/O. It was added as an
alternative to raw1394's isochronous I/O functionality which had
performance issues in its first generation. Any video1394 user had
to use raw1394 + libraw1394 too because video1394 did not provide
asynchronous I/O for device discovery and configuration.
Replaced by /dev/fw*, i.e. the <linux/firewire-cdev.h> ABI of
firewire-core.
Users:
libdc1394 (works with firewire-cdev too, transparent to library ABI
users)

View File

@@ -0,0 +1,36 @@
What: /sys/class/backlight/<backlight>/bl_power
Date: April 2005
KernelVersion: 2.6.12
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Control BACKLIGHT power, values are FB_BLANK_* from fb.h
- FB_BLANK_UNBLANK (0) : power on.
- FB_BLANK_POWERDOWN (4) : power off
Users: HAL
What: /sys/class/backlight/<backlight>/brightness
Date: April 2005
KernelVersion: 2.6.12
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Control the brightness for this <backlight>. Values
are between 0 and max_brightness. This file will also
show the brightness level stored in the driver, which
may not be the actual brightness (see actual_brightness).
Users: HAL
What: /sys/class/backlight/<backlight>/actual_brightness
Date: March 2006
KernelVersion: 2.6.17
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Show the actual brightness by querying the hardware.
Users: HAL
What: /sys/class/backlight/<backlight>/max_brightness
Date: April 2005
KernelVersion: 2.6.12
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Maximum brightness for <backlight>.
Users: HAL

View 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.

View File

@@ -0,0 +1,7 @@
What: /sys/devices/system/node/nodeX
Date: October 2002
Contact: Linux Memory Management list <linux-mm@kvack.org>
Description:
When CONFIG_NUMA is enabled, this is a directory containing
information on node X such as what CPUs are local to the
node.

View File

@@ -0,0 +1,8 @@
What: /sys/bus/pci/drivers/qla2xxx/.../devices/*
Date: September 2009
Contact: QLogic Linux Driver <linux-driver@qlogic.com>
Description: qla2xxx-udev.sh currently looks for uevent CHANGE events to
signal a firmware-dump has been generated by the driver and is
ready for retrieval.
Users: qla2xxx-udev.sh. Proposed changes should be mailed to
linux-driver@qlogic.com

View File

@@ -0,0 +1,20 @@
What: /sys/kernel/debug/ec/*/{gpe,use_global_lock,io}
Date: July 2010
Contact: Thomas Renninger <trenn@suse.de>
Description:
General information like which GPE is assigned to the EC and whether
the global lock should get used.
Knowing the EC GPE one can watch the amount of HW events related to
the EC here (XY -> GPE number from /sys/kernel/debug/ec/*/gpe):
/sys/firmware/acpi/interrupts/gpeXY
The io file is binary and a userspace tool located here:
ftp://ftp.suse.com/pub/people/trenn/sources/ec/
should get used to read out the 256 Embedded Controller registers
or writing to them.
CAUTION: Do not write to the Embedded Controller if you don't know
what you are doing! Rebooting afterwards also is a good idea.
This can influence the way your machine is cooled and fans may
not get switched on again after you did a wrong write.

View File

@@ -1,71 +0,0 @@
What: /sys/kernel/debug/kmemtrace/
Date: July 2008
Contact: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Description:
In kmemtrace-enabled kernels, the following files are created:
/sys/kernel/debug/kmemtrace/
cpu<n> (0400) Per-CPU tracing data, see below. (binary)
total_overruns (0400) Total number of bytes which were dropped from
cpu<n> files because of full buffer condition,
non-binary. (text)
abi_version (0400) Kernel's kmemtrace ABI version. (text)
Each per-CPU file should be read according to the relay interface. That is,
the reader should set affinity to that specific CPU and, as currently done by
the userspace application (though there are other methods), use poll() with
an infinite timeout before every read(). Otherwise, erroneous data may be
read. The binary data has the following _core_ format:
Event ID (1 byte) Unsigned integer, one of:
0 - represents an allocation (KMEMTRACE_EVENT_ALLOC)
1 - represents a freeing of previously allocated memory
(KMEMTRACE_EVENT_FREE)
Type ID (1 byte) Unsigned integer, one of:
0 - this is a kmalloc() / kfree()
1 - this is a kmem_cache_alloc() / kmem_cache_free()
2 - this is a __get_free_pages() et al.
Event size (2 bytes) Unsigned integer representing the
size of this event. Used to extend
kmemtrace. Discard the bytes you
don't know about.
Sequence number (4 bytes) Signed integer used to reorder data
logged on SMP machines. Wraparound
must be taken into account, although
it is unlikely.
Caller address (8 bytes) Return address to the caller.
Pointer to mem (8 bytes) Pointer to target memory area. Can be
NULL, but not all such calls might be
recorded.
In case of KMEMTRACE_EVENT_ALLOC events, the next fields follow:
Requested bytes (8 bytes) Total number of requested bytes,
unsigned, must not be zero.
Allocated bytes (8 bytes) Total number of actually allocated
bytes, unsigned, must not be lower
than requested bytes.
Requested flags (4 bytes) GFP flags supplied by the caller.
Target CPU (4 bytes) Signed integer, valid for event id 1.
If equal to -1, target CPU is the same
as origin CPU, but the reverse might
not be true.
The data is made available in the same endianness the machine has.
Other event ids and type ids may be defined and added. Other fields may be
added by increasing event size, but see below for details.
Every modification to the ABI, including new id definitions, are followed
by bumping the ABI version by one.
Adding new data to the packet (features) is done at the end of the mandatory
data:
Feature size (2 byte)
Feature ID (1 byte)
Feature data (Feature size - 3 bytes)
Users:
kmemtrace-user - git://repo.or.cz/kmemtrace-user.git

View File

@@ -20,7 +20,7 @@ Description:
lsm: [[subj_user=] [subj_role=] [subj_type=]
[obj_user=] [obj_role=] [obj_type=]]
base: func:= [BPRM_CHECK][FILE_MMAP][INODE_PERMISSION]
base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK]
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
fsmagic:= hex value
uid:= decimal value
@@ -40,11 +40,11 @@ Description:
measure func=BPRM_CHECK
measure func=FILE_MMAP mask=MAY_EXEC
measure func=INODE_PERM mask=MAY_READ uid=0
measure func=FILE_CHECK mask=MAY_READ uid=0
The default policy measures all executables in bprm_check,
all files mmapped executable in file_mmap, and all files
open for read by root in inode_permission.
open for read by root in do_filp_open.
Examples of LSM specific definitions:
@@ -54,8 +54,8 @@ Description:
dont_measure obj_type=var_log_t
dont_measure obj_type=auditd_log_t
measure subj_user=system_u func=INODE_PERM mask=MAY_READ
measure subj_role=system_r func=INODE_PERM mask=MAY_READ
measure subj_user=system_u func=FILE_CHECK mask=MAY_READ
measure subj_role=system_r func=FILE_CHECK mask=MAY_READ
Smack:
measure subj_user=_ func=INODE_PERM mask=MAY_READ
measure subj_user=_ func=FILE_CHECK mask=MAY_READ

View File

@@ -8,7 +8,7 @@ Description:
1 - major number
2 - minor mumber
3 - device name
4 - reads completed succesfully
4 - reads completed successfully
5 - reads merged
6 - sectors read
7 - time spent reading (ms)

View File

@@ -0,0 +1,99 @@
What: /sys/class/ata_...
Date: August 2008
Contact: Gwendal Grignou<gwendal@google.com>
Description:
Provide a place in sysfs for storing the ATA topology of the system. This allows
retrieving various information about ATA objects.
Files under /sys/class/ata_port
-------------------------------
For each port, a directory ataX is created where X is the ata_port_id of
the port. The device parent is the ata host device.
idle_irq (read)
Number of IRQ received by the port while idle [some ata HBA only].
nr_pmp_links (read)
If a SATA Port Multiplier (PM) is connected, number of link behind it.
Files under /sys/class/ata_link
-------------------------------
Behind each port, there is a ata_link. If there is a SATA PM in the
topology, 15 ata_link objects are created.
If a link is behind a port, the directory name is linkX, where X is
ata_port_id of the port.
If a link is behind a PM, its name is linkX.Y where X is ata_port_id
of the parent port and Y the PM port.
hw_sata_spd_limit
Maximum speed supported by the connected SATA device.
sata_spd_limit
Maximum speed imposed by libata.
sata_spd
Current speed of the link [1.5, 3Gps,...].
Files under /sys/class/ata_device
---------------------------------
Behind each link, up to two ata device are created.
The name of the directory is devX[.Y].Z where:
- X is ata_port_id of the port where the device is connected,
- Y the port of the PM if any, and
- Z the device id: for PATA, there is usually 2 devices [0,1],
only 1 for SATA.
class
Device class. Can be "ata" for disk, "atapi" for packet device,
"pmp" for PM, or "none" if no device was found behind the link.
dma_mode
Transfer modes supported by the device when in DMA mode.
Mostly used by PATA device.
pio_mode
Transfer modes supported by the device when in PIO mode.
Mostly used by PATA device.
xfer_mode
Current transfer mode.
id
Cached result of IDENTIFY command, as described in ATA8 7.16 and 7.17.
Only valid if the device is not a PM.
gscr
Cached result of the dump of PM GSCR register.
Valid registers are:
0: SATA_PMP_GSCR_PROD_ID,
1: SATA_PMP_GSCR_REV,
2: SATA_PMP_GSCR_PORT_INFO,
32: SATA_PMP_GSCR_ERROR,
33: SATA_PMP_GSCR_ERROR_EN,
64: SATA_PMP_GSCR_FEAT,
96: SATA_PMP_GSCR_FEAT_EN,
130: SATA_PMP_GSCR_SII_GPIO
Only valid if the device is a PM.
spdn_cnt
Number of time libata decided to lower the speed of link due to errors.
ering
Formatted output of the error ring of the device.

View File

@@ -4,7 +4,7 @@ Contact: Jerome Marchand <jmarchan@redhat.com>
Description:
The /sys/block/<disk>/stat files displays the I/O
statistics of disk <disk>. They contain 11 fields:
1 - reads completed succesfully
1 - reads completed successfully
2 - reads merged
3 - sectors read
4 - time spent reading (ms)
@@ -94,28 +94,51 @@ What: /sys/block/<disk>/queue/physical_block_size
Date: May 2009
Contact: Martin K. Petersen <martin.petersen@oracle.com>
Description:
This is the smallest unit the storage device can write
without resorting to read-modify-write operation. It is
usually the same as the logical block size but may be
bigger. One example is SATA drives with 4KB sectors
that expose a 512-byte logical block size to the
operating system.
This is the smallest unit a physical storage device can
write atomically. It is usually the same as the logical
block size but may be bigger. One example is SATA
drives with 4KB sectors that expose a 512-byte logical
block size to the operating system. For stacked block
devices the physical_block_size variable contains the
maximum physical_block_size of the component devices.
What: /sys/block/<disk>/queue/minimum_io_size
Date: April 2009
Contact: Martin K. Petersen <martin.petersen@oracle.com>
Description:
Storage devices may report a preferred minimum I/O size,
which is the smallest request the device can perform
without incurring a read-modify-write penalty. For disk
drives this is often the physical block size. For RAID
arrays it is often the stripe chunk size.
Storage devices may report a granularity or preferred
minimum I/O size which is the smallest request the
device can perform without incurring a performance
penalty. For disk drives this is often the physical
block size. For RAID arrays it is often the stripe
chunk size. A properly aligned multiple of
minimum_io_size is the preferred request size for
workloads where a high number of I/O operations is
desired.
What: /sys/block/<disk>/queue/optimal_io_size
Date: April 2009
Contact: Martin K. Petersen <martin.petersen@oracle.com>
Description:
Storage devices may report an optimal I/O size, which is
the device's preferred unit of receiving I/O. This is
rarely reported for disk drives. For RAID devices it is
usually the stripe width or the internal block size.
the device's preferred unit for sustained I/O. This is
rarely reported for disk drives. For RAID arrays it is
usually the stripe width or the internal track size. A
properly aligned multiple of optimal_io_size is the
preferred request size for workloads where sustained
throughput is desired. If no optimal I/O size is
reported this file contains 0.
What: /sys/block/<disk>/queue/nomerges
Date: January 2010
Contact:
Description:
Standard I/O elevator operations include attempts to
merge contiguous I/Os. For known random I/O loads these
attempts will always fail and result in extra cycles
being spent in the kernel. This allows one to turn off
this behavior on one of two ways: When set to 1, complex
merge checks are disabled, but the simple one-shot merges
with the previous I/O request are enabled. When set to 2,
all merge tries are disabled. The default value is 0 -
which enables all types of merge tries.

View File

@@ -0,0 +1,99 @@
What: /sys/block/zram<id>/disksize
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The disksize file is read-write and specifies the disk size
which represents the limit on the *uncompressed* worth of data
that can be stored in this disk.
What: /sys/block/zram<id>/initstate
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The disksize file is read-only and shows the initialization
state of the device.
What: /sys/block/zram<id>/reset
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The disksize file is write-only and allows resetting the
device. The reset operation frees all the memory assocaited
with this device.
What: /sys/block/zram<id>/num_reads
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The num_reads file is read-only and specifies the number of
reads (failed or successful) done on this device.
What: /sys/block/zram<id>/num_writes
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The num_writes file is read-only and specifies the number of
writes (failed or successful) done on this device.
What: /sys/block/zram<id>/invalid_io
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The invalid_io file is read-only and specifies the number of
non-page-size-aligned I/O requests issued to this device.
What: /sys/block/zram<id>/notify_free
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The notify_free file is read-only and specifies the number of
swap slot free notifications received by this device. These
notifications are send to a swap block device when a swap slot
is freed. This statistic is applicable only when this disk is
being used as a swap disk.
What: /sys/block/zram<id>/discard
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The discard file is read-only and specifies the number of
discard requests received by this device. These requests
provide information to block device regarding blocks which are
no longer used by filesystem.
What: /sys/block/zram<id>/zero_pages
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The zero_pages file is read-only and specifies number of zero
filled pages written to this disk. No memory is allocated for
such pages.
What: /sys/block/zram<id>/orig_data_size
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The orig_data_size file is read-only and specifies uncompressed
size of data stored in this disk. This excludes zero-filled
pages (zero_pages) since no memory is allocated for them.
Unit: bytes
What: /sys/block/zram<id>/compr_data_size
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The compr_data_size file is read-only and specifies compressed
size of data stored in this disk. So, compression ratio can be
calculated using orig_data_size and this statistic.
Unit: bytes
What: /sys/block/zram<id>/mem_used_total
Date: August 2010
Contact: Nitin Gupta <ngupta@vflare.org>
Description:
The mem_used_total file is read-only and specifies the amount
of memory, including allocator fragmentation and metadata
overhead, allocated for this disk. So, allocator space
efficiency can be calculated using compr_data_size and this
statistic.
Unit: bytes

View File

@@ -0,0 +1,21 @@
Where: /sys/bus/i2c/devices/.../heading0_input
Date: April 2010
Kernel Version: 2.6.36?
Contact: alan.cox@intel.com
Description: Reports the current heading from the compass as a floating
point value in degrees.
Where: /sys/bus/i2c/devices/.../power_state
Date: April 2010
Kernel Version: 2.6.36?
Contact: alan.cox@intel.com
Description: Sets the power state of the device. 0 sets the device into
sleep mode, 1 wakes it up.
Where: /sys/bus/i2c/devices/.../calibration
Date: April 2010
Kernel Version: 2.6.36?
Contact: alan.cox@intel.com
Description: Sets the calibration on or off (1 = on, 0 = off). See the
chip data sheet.

View File

@@ -84,6 +84,16 @@ Description:
from this part of the device tree.
Depends on CONFIG_HOTPLUG.
What: /sys/bus/pci/devices/.../reset
Date: July 2009
Contact: Michael S. Tsirkin <mst@redhat.com>
Description:
Some devices allow an individual function to be reset
without affecting other functions in the same device.
For devices that have this support, a file named reset
will be present in sysfs. Writing 1 to this file
will perform reset.
What: /sys/bus/pci/devices/.../vpd
Date: February 2008
Contact: Ben Hutchings <bhutchings@solarflare.com>
@@ -129,3 +139,30 @@ Contact: linux-pci@vger.kernel.org
Description:
This symbolic link points to the PCI hotplug controller driver
module that manages the hotplug slot.
What: /sys/bus/pci/devices/.../label
Date: July 2010
Contact: Narendra K <narendra_k@dell.com>, linux-bugs@dell.com
Description:
Reading this attribute will provide the firmware
given name(SMBIOS type 41 string) of the PCI device.
The attribute will be created only if the firmware
has given a name to the PCI device.
Users:
Userspace applications interested in knowing the
firmware assigned name of the PCI device.
What: /sys/bus/pci/devices/.../index
Date: July 2010
Contact: Narendra K <narendra_k@dell.com>, linux-bugs@dell.com
Description:
Reading this attribute will provide the firmware
given instance(SMBIOS type 41 device type instance)
of the PCI device. The attribute will be created
only if the firmware has given a device type instance
to the PCI device.
Users:
Userspace applications interested in knowing the
firmware assigned device type instance of the PCI
device that can help in understanding the firmware
intended order of the PCI device.

View File

@@ -31,3 +31,31 @@ Date: March 2009
Kernel Version: 2.6.30
Contact: iss_storagedev@hp.com
Description: A symbolic link to /sys/block/cciss!cXdY
Where: /sys/bus/pci/devices/<dev>/ccissX/rescan
Date: August 2009
Kernel Version: 2.6.31
Contact: iss_storagedev@hp.com
Description: Kicks of a rescan of the controller to discover logical
drive topology changes.
Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/lunid
Date: August 2009
Kernel Version: 2.6.31
Contact: iss_storagedev@hp.com
Description: Displays the 8-byte LUN ID used to address logical
drive Y of controller X.
Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/raid_level
Date: August 2009
Kernel Version: 2.6.31
Contact: iss_storagedev@hp.com
Description: Displays the RAID level of logical drive Y of
controller X.
Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/usage_count
Date: August 2009
Kernel Version: 2.6.31
Contact: iss_storagedev@hp.com
Description: Displays the usage count (number of opens) of logical drive Y
of controller X.

View File

@@ -0,0 +1,83 @@
What: /sys/bus/rbd/
Date: November 2010
Contact: Yehuda Sadeh <yehuda@hq.newdream.net>,
Sage Weil <sage@newdream.net>
Description:
Being used for adding and removing rbd block devices.
Usage: <mon ip addr> <options> <pool name> <rbd image name> [snap name]
$ echo "192.168.0.1 name=admin rbd foo" > /sys/bus/rbd/add
The snapshot name can be "-" or omitted to map the image read/write. A <dev-id>
will be assigned for any registered block device. If snapshot is used, it will
be mapped read-only.
Removal of a device:
$ echo <dev-id> > /sys/bus/rbd/remove
Entries under /sys/bus/rbd/devices/<dev-id>/
--------------------------------------------
client_id
The ceph unique client id that was assigned for this specific session.
major
The block device major number.
name
The name of the rbd image.
pool
The pool where this rbd image resides. The pool-name pair is unique
per rados system.
size
The size (in bytes) of the mapped block device.
refresh
Writing to this file will reread the image header data and set
all relevant datastructures accordingly.
current_snap
The current snapshot for which the device is mapped.
create_snap
Create a snapshot:
$ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_create
rollback_snap
Rolls back data to the specified snapshot. This goes over the entire
list of rados blocks and sends a rollback command to each.
$ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_rollback
snap_*
A directory per each snapshot
Entries under /sys/bus/rbd/devices/<dev-id>/snap_<snap-name>
-------------------------------------------------------------
id
The rados internal snapshot id assigned for this snapshot
size
The size of the image when this snapshot was taken.

View File

@@ -14,32 +14,6 @@ Description:
The autosuspend delay for newly-created devices is set to
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, one of "on", "auto", or "suspend".
"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. "suspend" means the device
is forced into a suspended state and it will not autoresume
in response to I/O requests. However remote-wakeup requests
from the device may still be enabled (the remote-wakeup
setting is controlled separately by the power/wakeup
attribute).
During normal use, devices should be left in the "auto"
level. The other levels are 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.
What: /sys/bus/usb/devices/.../power/persist
Date: May 2007
KernelVersion: 2.6.23
@@ -144,3 +118,27 @@ Description:
Write a 1 to force the device to disconnect
(equivalent to unplugging a wired USB device).
What: /sys/bus/usb/drivers/.../remove_id
Date: November 2009
Contact: CHENG Renquan <rqcheng@smu.edu.sg>
Description:
Writing a device ID to this file will remove an ID
that was dynamically added via the new_id sysfs entry.
The format for the device ID is:
idVendor idProduct. After successfully
removing an ID, the driver will no longer support the
device. This is useful to ensure auto probing won't
match the driver to the device. For example:
# echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id
What: /sys/bus/usb/device/.../avoid_reset_quirk
Date: December 2009
Contact: Oliver Neukum <oliver@neukum.org>
Description:
Writing 1 to this file tells the kernel that this
device will morph into another mode when it is reset.
Drivers will not use reset for error handling for
such devices.
Users:
usb_modeswitch

View File

@@ -0,0 +1,23 @@
What: /sys/class/lcd/<lcd>/lcd_power
Date: April 2005
KernelVersion: 2.6.12
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Control LCD power, values are FB_BLANK_* from fb.h
- FB_BLANK_UNBLANK (0) : power on.
- FB_BLANK_POWERDOWN (4) : power off
What: /sys/class/lcd/<lcd>/contrast
Date: April 2005
KernelVersion: 2.6.12
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Current contrast of this LCD device. Value is between 0 and
/sys/class/lcd/<lcd>/max_contrast.
What: /sys/class/lcd/<lcd>/max_contrast
Date: April 2005
KernelVersion: 2.6.12
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Maximum contrast for this LCD device.

View File

@@ -0,0 +1,28 @@
What: /sys/class/leds/<led>/brightness
Date: March 2006
KernelVersion: 2.6.17
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Set the brightness of the LED. Most LEDs don't
have hardware brightness support so will just be turned on for
non-zero brightness settings. The value is between 0 and
/sys/class/leds/<led>/max_brightness.
What: /sys/class/leds/<led>/max_brightness
Date: March 2006
KernelVersion: 2.6.17
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Maximum brightness level for this led, default is 255 (LED_FULL).
What: /sys/class/leds/<led>/trigger
Date: March 2006
KernelVersion: 2.6.17
Contact: Richard Purdie <rpurdie@rpsys.net>
Description:
Set the trigger for this LED. A trigger is a kernel based source
of led events.
You can change triggers in a similar manner to the way an IO
scheduler is chosen. Trigger specific parameters can appear in
/sys/class/leds/<led> once a given trigger is selected.

View File

@@ -0,0 +1,14 @@
What: /sys/class/net/<iface>/batman-adv/mesh_iface
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
The /sys/class/net/<iface>/batman-adv/mesh_iface file
displays the batman mesh interface this <iface>
currently is associated with.
What: /sys/class/net/<iface>/batman-adv/iface_status
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Indicates the status of <iface> as it is seen by batman.

View File

@@ -0,0 +1,69 @@
What: /sys/class/net/<mesh_iface>/mesh/aggregated_ogms
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Indicates whether the batman protocol messages of the
mesh <mesh_iface> shall be aggregated or not.
What: /sys/class/net/<mesh_iface>/mesh/bonding
Date: June 2010
Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Description:
Indicates whether the data traffic going through the
mesh will be sent using multiple interfaces at the
same time (if available).
What: /sys/class/net/<mesh_iface>/mesh/fragmentation
Date: October 2010
Contact: Andreas Langer <an.langer@gmx.de>
Description:
Indicates whether the data traffic going through the
mesh will be fragmented or silently discarded if the
packet size exceeds the outgoing interface MTU.
What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
Date: October 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Defines the bandwidth which is propagated by this
node if gw_mode was set to 'server'.
What: /sys/class/net/<mesh_iface>/mesh/gw_mode
Date: October 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Defines the state of the gateway features. Can be
either 'off', 'client' or 'server'.
What: /sys/class/net/<mesh_iface>/mesh/gw_sel_class
Date: October 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Defines the selection criteria this node will use
to choose a gateway if gw_mode was set to 'client'.
What: /sys/class/net/<mesh_iface>/mesh/orig_interval
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Defines the interval in milliseconds in which batman
sends its protocol messages.
What: /sys/class/net/<mesh_iface>/mesh/hop_penalty
Date: Oct 2010
Contact: Linus Lüssing <linus.luessing@web.de>
Description:
Defines the penalty which will be applied to an
originator message's tq-field on every hop.
What: /sys/class/net/<mesh_iface>/mesh/vis_mode
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Each batman node only maintains information about its
own local neighborhood, therefore generating graphs
showing the topology of the entire mesh is not easily
feasible without having a central instance to collect
the local topologies from all nodes. This file allows
to activate the collecting (server) mode.

View File

@@ -0,0 +1,20 @@
What: /sys/class/power/ds2760-battery.*/charge_now
Date: May 2010
KernelVersion: 2.6.35
Contact: Daniel Mack <daniel@caiaq.de>
Description:
This file is writeable and can be used to set the current
coloumb counter value inside the battery monitor chip. This
is needed for unavoidable corrections of aging batteries.
A userspace daemon can monitor the battery charging logic
and once the counter drops out of considerable bounds, take
appropriate action.
What: /sys/class/power/ds2760-battery.*/charge_full
Date: May 2010
KernelVersion: 2.6.35
Contact: Daniel Mack <daniel@caiaq.de>
Description:
This file is writeable and can be used to set the assumed
battery 'full level'. As batteries age, this value has to be
amended over time.

View File

@@ -1,25 +0,0 @@
What: /sys/class/usb_host/usb_hostN/wusb_chid
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Write the CHID (16 space-separated hex octets) for this host controller.
This starts the host controller, allowing it to accept connection from
WUSB devices.
Set an all zero CHID to stop the host controller.
What: /sys/class/usb_host/usb_hostN/wusb_trust_timeout
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Devices that haven't sent a WUSB packet to the host
within 'wusb_trust_timeout' ms are considered to have
disconnected and are removed. The default value of
4000 ms is the value required by the WUSB
specification.
Since this relates to security (specifically, the
lifetime of PTKs and GTKs) it should not be changed
from the default.

View File

@@ -0,0 +1,38 @@
What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_chid
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Write the CHID (16 space-separated hex octets) for this host controller.
This starts the host controller, allowing it to accept connection from
WUSB devices.
Set an all zero CHID to stop the host controller.
What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_trust_timeout
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Devices that haven't sent a WUSB packet to the host
within 'wusb_trust_timeout' ms are considered to have
disconnected and are removed. The default value of
4000 ms is the value required by the WUSB
specification.
Since this relates to security (specifically, the
lifetime of PTKs and GTKs) it should not be changed
from the default.
What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_phy_rate
Date: August 2009
KernelVersion: 2.6.32
Contact: David Vrabel <david.vrabel@csr.com>
Description:
The maximum PHY rate to use for all connected devices.
This is only of limited use for testing and
development as the hardware's automatic rate
adaptation is better then this simple control.
Refer to [ECMA-368] section 10.3.1.1 for the value to
use.

View File

@@ -1,18 +0,0 @@
What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
Date: August 2008
KernelVersion: 2.6.27
Contact: mark.langsdorf@amd.com
Description: These files exist in every cpu's cache index directories.
There are currently 2 cache_disable_# files in each
directory. Reading from these files on a supported
processor will return that cache disable index value
for that processor and node. Writing to one of these
files will cause the specificed cache index to be disabled.
Currently, only AMD Family 10h Processors support cache index
disable, and only for their L3 caches. See the BIOS and
Kernel Developer's Guide at
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
for formatting information and other details on the
cache index disable.
Users: joachim.deguara@amd.com

View File

@@ -7,7 +7,7 @@ Description:
added or removed dynamically to represent hot-add/remove
operations.
Users: hotplug memory add/remove tools
https://w3.opensource.ibm.com/projects/powerpc-utils/
http://www.ibm.com/developerworks/wikis/display/LinuxP/powerpc-utils
What: /sys/devices/system/memory/memoryX/removable
Date: June 2008
@@ -19,7 +19,7 @@ Description:
identify removable sections of the memory before attempting
potentially expensive hot-remove memory operation
Users: hotplug memory remove tools
https://w3.opensource.ibm.com/projects/powerpc-utils/
http://www.ibm.com/developerworks/wikis/display/LinuxP/powerpc-utils
What: /sys/devices/system/memory/memoryX/phys_device
Date: September 2008
@@ -43,7 +43,7 @@ Date: September 2008
Contact: Badari Pulavarty <pbadari@us.ibm.com>
Description:
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,
root can toggle the the online/offline state of a removable
memory section (see removable file description above)
@@ -58,7 +58,20 @@ Description:
by root to offline that section.
# echo offline > /sys/devices/system/memory/memory22/state
Users: hotplug memory remove tools
https://w3.opensource.ibm.com/projects/powerpc-utils/
http://www.ibm.com/developerworks/wikis/display/LinuxP/powerpc-utils
What: /sys/devices/system/memoryX/nodeY
Date: October 2009
Contact: Linux Memory Management list <linux-mm@kvack.org>
Description:
When CONFIG_NUMA is enabled, a symbolic link that
points to the corresponding NUMA node directory.
For example, the following symbolic link is created for
memory section 9 on node0:
/sys/devices/system/memory/memory9/node0 -> ../../node/node0
What: /sys/devices/system/node/nodeX/memoryY
Date: September 2008
@@ -70,4 +83,3 @@ Description:
memory section directory. For example, the following symbolic
link is created for memory section 9 on node0.
/sys/devices/system/node/node0/memory9 -> ../../memory/memory9

View File

@@ -0,0 +1,7 @@
What: /sys/devices/system/node/nodeX/compact
Date: February 2010
Contact: Mel Gorman <mel@csn.ul.ie>
Description:
When this file is written to, all memory within that node
will be compacted. When it completes, memory will be freed
into blocks which have as many contiguous pages as possible

View File

@@ -0,0 +1,21 @@
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)
What: /sys/devices/platform/_UDC_/gadget/gadget-lunX/nofua
Date: July 2010
Contact: Andy Shevchenko <andy.shevchenko@gmail.com>
Description:
Show or set the reaction on the FUA (Force Unit Access) bit in
the SCSI WRITE(10,12) commands when a gadget in USB Mass
Storage mode.
Possible values are:
1 -> ignore the FUA flag
0 -> obey the FUA flag

View File

@@ -0,0 +1,167 @@
What: /sys/devices/.../power/
Date: January 2009
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../power directory contains attributes
allowing the user space to check and modify some power
management related properties of given device.
What: /sys/devices/.../power/wakeup
Date: January 2009
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../power/wakeup attribute allows the user
space to check if the device is enabled to wake up the system
from sleep states, such as the memory sleep state (suspend to
RAM) and hibernation (suspend to disk), and to enable or disable
it to do that as desired.
Some devices support "wakeup" events, which are hardware signals
used to activate the system from a sleep state. Such devices
have one of the following two values for the sysfs power/wakeup
file:
+ "enabled\n" to issue the events;
+ "disabled\n" not to do so;
In that cases the user space can change the setting represented
by the contents of this file by writing either "enabled", or
"disabled" to it.
For the devices that are not capable of generating system wakeup
events this file contains "\n". In that cases the user space
cannot modify the contents of this file and the device cannot be
enabled to wake up the system.
What: /sys/devices/.../power/control
Date: January 2009
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../power/control attribute allows the user
space to control the run-time power management of the device.
All devices have one of the following two values for the
power/control file:
+ "auto\n" to allow the device to be power managed at run time;
+ "on\n" to prevent the device from being power managed;
The default for all devices is "auto", which means that they may
be subject to automatic power management, depending on their
drivers. Changing this attribute to "on" prevents the driver
from power managing the device at run time. Doing that while
the device is suspended causes it to be woken up.
What: /sys/devices/.../power/async
Date: January 2009
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../async attribute allows the user space to
enable or diasble the device's suspend and resume callbacks to
be executed asynchronously (ie. in separate threads, in parallel
with the main suspend/resume thread) during system-wide power
transitions (eg. suspend to RAM, hibernation).
All devices have one of the following two values for the
power/async file:
+ "enabled\n" to permit the asynchronous suspend/resume;
+ "disabled\n" to forbid it;
The value of this attribute may be changed by writing either
"enabled", or "disabled" to it.
It generally is unsafe to permit the asynchronous suspend/resume
of a device unless it is certain that all of the PM dependencies
of the device are known to the PM core. However, for some
devices this attribute is set to "enabled" by bus type code or
device drivers and in that cases it should be safe to leave the
default value.
What: /sys/devices/.../power/wakeup_count
Date: September 2010
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../wakeup_count attribute contains the number
of signaled wakeup events associated with the device. This
attribute is read-only. If the device is not enabled to wake up
the system from sleep states, this attribute is empty.
What: /sys/devices/.../power/wakeup_active_count
Date: September 2010
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../wakeup_active_count attribute contains the
number of times the processing of wakeup events associated with
the device was completed (at the kernel level). This attribute
is read-only. If the device is not enabled to wake up the
system from sleep states, this attribute is empty.
What: /sys/devices/.../power/wakeup_hit_count
Date: September 2010
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../wakeup_hit_count attribute contains the
number of times the processing of a wakeup event associated with
the device might prevent the system from entering a sleep state.
This attribute is read-only. If the device is not enabled to
wake up the system from sleep states, this attribute is empty.
What: /sys/devices/.../power/wakeup_active
Date: September 2010
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../wakeup_active attribute contains either 1,
or 0, depending on whether or not a wakeup event associated with
the device is being processed (1). This attribute is read-only.
If the device is not enabled to wake up the system from sleep
states, this attribute is empty.
What: /sys/devices/.../power/wakeup_total_time_ms
Date: September 2010
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../wakeup_total_time_ms attribute contains
the total time of processing wakeup events associated with the
device, in milliseconds. This attribute is read-only. If the
device is not enabled to wake up the system from sleep states,
this attribute is empty.
What: /sys/devices/.../power/wakeup_max_time_ms
Date: September 2010
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../wakeup_max_time_ms attribute contains
the maximum time of processing a single wakeup event associated
with the device, in milliseconds. This attribute is read-only.
If the device is not enabled to wake up the system from sleep
states, this attribute is empty.
What: /sys/devices/.../power/wakeup_last_time_ms
Date: September 2010
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/devices/.../wakeup_last_time_ms attribute contains
the value of the monotonic clock corresponding to the time of
signaling the last wakeup event associated with the device, in
milliseconds. This attribute is read-only. If the device is
not enabled to wake up the system from sleep states, this
attribute is empty.
What: /sys/devices/.../power/autosuspend_delay_ms
Date: September 2010
Contact: Alan Stern <stern@rowland.harvard.edu>
Description:
The /sys/devices/.../power/autosuspend_delay_ms attribute
contains the autosuspend delay value (in milliseconds). Some
drivers do not want their device to suspend as soon as it
becomes idle at run time; they want the device to remain
inactive for a certain minimum period of time first. That
period is called the autosuspend delay. Negative values will
prevent the device from being suspended at run time (similar
to writing "on" to the power/control attribute). Values >=
1000 will cause the autosuspend timer expiration to be rounded
up to the nearest second.
Not all drivers support this attribute. If it isn't supported,
attempts to read or write it will yield I/O errors.

View File

@@ -0,0 +1,203 @@
What: /sys/devices/system/cpu/
Date: pre-git history
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description:
A collection of both global and individual CPU attributes
Individual CPU attributes are contained in subdirectories
named by the kernel's logical CPU number, e.g.:
/sys/devices/system/cpu/cpu#/
What: /sys/devices/system/cpu/sched_mc_power_savings
/sys/devices/system/cpu/sched_smt_power_savings
Date: June 2006
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: Discover and adjust the kernel's multi-core scheduler support.
Possible values are:
0 - No power saving load balance (default value)
1 - Fill one thread/core/package first for long running threads
2 - Also bias task wakeups to semi-idle cpu package for power
savings
sched_mc_power_savings is dependent upon SCHED_MC, which is
itself architecture dependent.
sched_smt_power_savings is dependent upon SCHED_SMT, which
is itself architecture dependent.
The two files are independent of each other. It is possible
that one file may be present without the other.
Introduced by git commit 5c45bf27.
What: /sys/devices/system/cpu/kernel_max
/sys/devices/system/cpu/offline
/sys/devices/system/cpu/online
/sys/devices/system/cpu/possible
/sys/devices/system/cpu/present
Date: December 2008
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: CPU topology files that describe kernel limits related to
hotplug. Briefly:
kernel_max: the maximum cpu index allowed by the kernel
configuration.
offline: cpus that are not online because they have been
HOTPLUGGED off or exceed the limit of cpus allowed by the
kernel configuration (kernel_max above).
online: cpus that are online and being scheduled.
possible: cpus that have been allocated resources and can be
brought online if they are present.
present: cpus that have been identified as being present in
the system.
See Documentation/cputopology.txt for more information.
What: /sys/devices/system/cpu/probe
/sys/devices/system/cpu/release
Date: November 2009
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: Dynamic addition and removal of CPU's. This is not hotplug
removal, this is meant complete removal/addition of the CPU
from the system.
probe: writes to this file will dynamically add a CPU to the
system. Information written to the file to add CPU's is
architecture specific.
release: writes to this file dynamically remove a CPU from
the system. Information writtento the file to remove CPU's
is architecture specific.
What: /sys/devices/system/cpu/cpu#/node
Date: October 2009
Contact: Linux memory management mailing list <linux-mm@kvack.org>
Description: Discover NUMA node a CPU belongs to
When CONFIG_NUMA is enabled, a symbolic link that points
to the corresponding NUMA node directory.
For example, the following symlink is created for cpu42
in NUMA node 2:
/sys/devices/system/cpu/cpu42/node2 -> ../../node/node2
What: /sys/devices/system/cpu/cpu#/node
Date: October 2009
Contact: Linux memory management mailing list <linux-mm@kvack.org>
Description: Discover NUMA node a CPU belongs to
When CONFIG_NUMA is enabled, a symbolic link that points
to the corresponding NUMA node directory.
For example, the following symlink is created for cpu42
in NUMA node 2:
/sys/devices/system/cpu/cpu42/node2 -> ../../node/node2
What: /sys/devices/system/cpu/cpu#/topology/core_id
/sys/devices/system/cpu/cpu#/topology/core_siblings
/sys/devices/system/cpu/cpu#/topology/core_siblings_list
/sys/devices/system/cpu/cpu#/topology/physical_package_id
/sys/devices/system/cpu/cpu#/topology/thread_siblings
/sys/devices/system/cpu/cpu#/topology/thread_siblings_list
Date: December 2008
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: CPU topology files that describe a logical CPU's relationship
to other cores and threads in the same physical package.
One cpu# directory is created per logical CPU in the system,
e.g. /sys/devices/system/cpu/cpu42/.
Briefly, the files above are:
core_id: the CPU core ID of cpu#. Typically it is the
hardware platform's identifier (rather than the kernel's).
The actual value is architecture and platform dependent.
core_siblings: internal kernel map of cpu#'s hardware threads
within the same physical_package_id.
core_siblings_list: human-readable list of the logical CPU
numbers within the same physical_package_id as cpu#.
physical_package_id: physical package id of cpu#. Typically
corresponds to a physical socket number, but the actual value
is architecture and platform dependent.
thread_siblings: internel kernel map of cpu#'s hardware
threads within the same core as cpu#
thread_siblings_list: human-readable list of cpu#'s hardware
threads within the same core as cpu#
See Documentation/cputopology.txt for more information.
What: /sys/devices/system/cpu/cpuidle/current_driver
/sys/devices/system/cpu/cpuidle/current_governer_ro
Date: September 2007
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: Discover cpuidle policy and mechanism
Various CPUs today support multiple idle levels that are
differentiated by varying exit latencies and power
consumption during idle.
Idle policy (governor) is differentiated from idle mechanism
(driver)
current_driver: displays current idle mechanism
current_governor_ro: displays current idle policy
See files in Documentation/cpuidle/ for more information.
What: /sys/devices/system/cpu/cpu#/cpufreq/*
Date: pre-git history
Contact: cpufreq@vger.kernel.org
Description: Discover and change clock speed of CPUs
Clock scaling allows you to change the clock speed of the
CPUs on the fly. This is a nice method to save battery
power, because the lower the clock speed, the less power
the CPU consumes.
There are many knobs to tweak in this directory.
See files in Documentation/cpu-freq/ for more information.
In particular, read Documentation/cpu-freq/user-guide.txt
to learn how to control the knobs.
What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
Date: August 2008
KernelVersion: 2.6.27
Contact: mark.langsdorf@amd.com
Description: These files exist in every cpu's cache index directories.
There are currently 2 cache_disable_# files in each
directory. Reading from these files on a supported
processor will return that cache disable index value
for that processor and node. Writing to one of these
files will cause the specificed cache index to be disabled.
Currently, only AMD Family 10h Processors support cache index
disable, and only for their L3 caches. See the BIOS and
Kernel Developer's Guide at
http://support.amd.com/us/Embedded_TechDocs/31116-Public-GH-BKDG_3-28_5-28-09.pdf
for formatting information and other details on the
cache index disable.
Users: joachim.deguara@amd.com

View File

@@ -0,0 +1,22 @@
What: state
Date: Sep 2010
KernelVersion: 2.6.37
Contact: Vernon Mauery <vernux@us.ibm.com>
Description: The state file allows a means by which to change in and
out of Premium Real-Time Mode (PRTM), as well as the
ability to query the current state.
0 => PRTM off
1 => PRTM enabled
Users: The ibm-prtm userspace daemon uses this interface.
What: version
Date: Sep 2010
KernelVersion: 2.6.37
Contact: Vernon Mauery <vernux@us.ibm.com>
Description: The version file provides a means by which to query
the RTL table version that lives in the Extended
BIOS Data Area (EBDA).
Users: The ibm-prtm userspace daemon uses this interface.

View 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.

View 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

View File

@@ -0,0 +1,98 @@
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/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>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/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>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/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>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/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>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/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>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/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>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/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>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/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.

View File

@@ -0,0 +1,108 @@
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile
Date: October 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read, this file returns the number of the actual profile in
range 0-4.
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version
Date: October 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 121 means 1.21
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro
Date: October 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse can store a macro with max 500 key/button strokes
internally.
When written, this file lets one set the sequence for a specific
button for a specific profile. Button and profile numbers are
included in written data. The data has to be 2082 bytes long.
This file is writeonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_buttons
Date: August 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 is split in settings and buttons.
profile_buttons holds informations about button layout.
When written, this file lets one write the respective profile
buttons back to the mouse. The data has to be 77 bytes long.
The mouse will reject invalid data.
Which profile to write is determined by the profile number
contained in the data.
This file is writeonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons
Date: August 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 is split in settings and buttons.
profile_buttons holds informations about button layout.
When read, these files return the respective profile buttons.
The returned data is 77 bytes in size.
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings
Date: October 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 is split in settings and buttons.
profile_settings holds informations like resolution, sensitivity
and light effects.
When written, this file lets one write the respective profile
settings back to the mouse. The data has to be 43 bytes long.
The mouse will reject invalid data.
Which profile to write is determined by the profile number
contained in the data.
This file is writeonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings
Date: August 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 is split in settings and buttons.
profile_settings holds informations like resolution, sensitivity
and light effects.
When read, these files return the respective profile settings.
The returned data is 43 bytes in size.
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor
Date: October 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The mouse has a tracking- and a distance-control-unit. These
can be activated/deactivated and the lift-off distance can be
set. The data has to be 6 bytes long.
This file is writeonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile
Date: October 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The integer value of this attribute ranges from 0-4.
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>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu
Date: October 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When written a calibration process for the tracking control unit
can be initiated/cancelled.
The data has to be 3 bytes long.
This file is writeonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image
Date: October 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read the mouse returns a 30x30 pixel image of the
sampled underground. This works only in the course of a
calibration process initiated with tcu.
The returned data is 1028 bytes in size.
This file is readonly.

View File

@@ -0,0 +1,98 @@
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_cpi
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: It is possible to switch the cpi setting of the mouse with the
press of a button.
When read, this file returns the raw number of the actual cpi
setting reported by the mouse. This number has to be further
processed to receive the real dpi value.
VALUE DPI
1 400
2 800
4 1600
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_profile
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: When read, this file returns the number of the actual profile in
range 0-4.
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/firmware_version
Date: August 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>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_settings
Date: August 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 is split in settings and buttons.
profile_settings holds informations like resolution, sensitivity
and light effects.
When written, this file lets one write the respective profile
settings back to the mouse. The data has to be 13 bytes long.
The mouse will reject invalid data.
Which profile to write is determined by the profile number
contained in the data.
This file is writeonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings
Date: August 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 is split in settings and buttons.
profile_settings holds informations like resolution, sensitivity
and light effects.
When read, these files return the respective profile settings.
The returned data is 13 bytes in size.
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons
Date: August 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 is split in settings and buttons.
profile_buttons holds informations about button layout.
When written, this file lets one write the respective profile
buttons back to the mouse. The data has to be 19 bytes long.
The mouse will reject invalid data.
Which profile to write is determined by the profile number
contained in the data.
This file is writeonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons
Date: August 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 is split in settings and buttons.
profile_buttons holds informations about button layout.
When read, these files return the respective profile buttons.
The returned data is 19 bytes in size.
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile
Date: August 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
Description: The integer value of this attribute ranges from 0-4.
When read, this attribute returns the number of the profile
that's active when the mouse is powered on.
This file is readonly.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings
Date: August 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 3 bytes and holds information on the
startup_profile.
When written, this file lets write settings back to the mouse.
The data has to be 3 bytes long. The mouse will reject invalid
data.

View File

@@ -0,0 +1,15 @@
What: /sys/firmware/sfi/tables/
Date: May 2010
Contact: Len Brown <lenb@kernel.org>
Description:
SFI defines a number of small static memory tables
so the kernel can get platform information from firmware.
The tables are defined in the latest SFI specification:
http://simplefirmware.org/documentation
While the tables are used by the kernel, user-space
can observe them this way:
# cd /sys/firmware/sfi/tables
# cat $TABLENAME > $TABLENAME.bin

View File

@@ -19,6 +19,7 @@ Description:
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique

View File

@@ -0,0 +1,31 @@
What: /sys/bus/i2c/devices/<busnum>-<devaddr>/pressure0_input
Date: June 2010
Contact: Christoph Mair <christoph.mair@gmail.com>
Description: Start a pressure measurement and read the result. Values
represent the ambient air pressure in pascal (0.01 millibar).
Reading: returns the current air pressure.
What: /sys/bus/i2c/devices/<busnum>-<devaddr>/temp0_input
Date: June 2010
Contact: Christoph Mair <christoph.mair@gmail.com>
Description: Measure the ambient temperature. The returned value represents
the ambient temperature in units of 0.1 degree celsius.
Reading: returns the current temperature.
What: /sys/bus/i2c/devices/<busnum>-<devaddr>/oversampling
Date: June 2010
Contact: Christoph Mair <christoph.mair@gmail.com>
Description: Tell the bmp085 to use more samples to calculate a pressure
value. When writing to this file the chip will use 2^x samples
to calculate the next pressure value with x being the value
written. Using this feature will decrease RMS noise and
increase the measurement time.
Reading: returns the current oversampling setting.
Writing: sets a new oversampling setting.
Accepted values: 0..3.

View File

@@ -45,8 +45,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The alloc_fastpath file is read-only and specifies how many
objects have been allocated using the fast path.
The alloc_fastpath file shows how many objects have been
allocated using the fast path. It can be written to clear the
current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/alloc_from_partial
@@ -55,9 +56,10 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The alloc_from_partial file is read-only and specifies how
many times a cpu slab has been full and it has been refilled
by using a slab from the list of partially used slabs.
The alloc_from_partial file shows how many times a cpu slab has
been full and it has been refilled by using a slab from the list
of partially used slabs. It can be written to clear the current
count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/alloc_refill
@@ -66,9 +68,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The alloc_refill file is read-only and specifies how many
times the per-cpu freelist was empty but there were objects
available as the result of remote cpu frees.
The alloc_refill file shows how many times the per-cpu freelist
was empty but there were objects available as the result of
remote cpu frees. It can be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/alloc_slab
@@ -77,8 +79,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The alloc_slab file is read-only and specifies how many times
a new slab had to be allocated from the page allocator.
The alloc_slab file is shows how many times a new slab had to
be allocated from the page allocator. It can be written to
clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/alloc_slowpath
@@ -87,9 +90,10 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The alloc_slowpath file is read-only and specifies how many
objects have been allocated using the slow path because of a
refill or allocation from a partial or new slab.
The alloc_slowpath file shows how many objects have been
allocated using the slow path because of a refill or
allocation from a partial or new slab. It can be written to
clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/cache_dma
@@ -117,10 +121,11 @@ KernelVersion: 2.6.31
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file cpuslab_flush is read-only and specifies how many
times a cache's cpu slabs have been flushed as the result of
destroying or shrinking a cache, a cpu going offline, or as
the result of forcing an allocation from a certain node.
The file cpuslab_flush shows how many times a cache's cpu slabs
have been flushed as the result of destroying or shrinking a
cache, a cpu going offline, or as the result of forcing an
allocation from a certain node. It can be written to clear the
current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/ctor
@@ -139,8 +144,8 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file deactivate_empty is read-only and specifies how many
times an empty cpu slab was deactivated.
The deactivate_empty file shows how many times an empty cpu slab
was deactivated. It can be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/deactivate_full
@@ -149,8 +154,8 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file deactivate_full is read-only and specifies how many
times a full cpu slab was deactivated.
The deactivate_full file shows how many times a full cpu slab
was deactivated. It can be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/deactivate_remote_frees
@@ -159,9 +164,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file deactivate_remote_frees is read-only and specifies how
many times a cpu slab has been deactivated and contained free
objects that were freed remotely.
The deactivate_remote_frees file shows how many times a cpu slab
has been deactivated and contained free objects that were freed
remotely. It can be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/deactivate_to_head
@@ -170,9 +175,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file deactivate_to_head is read-only and specifies how
many times a partial cpu slab was deactivated and added to the
head of its node's partial list.
The deactivate_to_head file shows how many times a partial cpu
slab was deactivated and added to the head of its node's partial
list. It can be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/deactivate_to_tail
@@ -181,9 +186,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file deactivate_to_tail is read-only and specifies how
many times a partial cpu slab was deactivated and added to the
tail of its node's partial list.
The deactivate_to_tail file shows how many times a partial cpu
slab was deactivated and added to the tail of its node's partial
list. It can be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/destroy_by_rcu
@@ -201,9 +206,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file free_add_partial is read-only and specifies how many
times an object has been freed in a full slab so that it had to
added to its node's partial list.
The free_add_partial file shows how many times an object has
been freed in a full slab so that it had to added to its node's
partial list. It can be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/free_calls
@@ -222,9 +227,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The free_fastpath file is read-only and specifies how many
objects have been freed using the fast path because it was an
object from the cpu slab.
The free_fastpath file shows how many objects have been freed
using the fast path because it was an object from the cpu slab.
It can be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/free_frozen
@@ -233,9 +238,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The free_frozen file is read-only and specifies how many
objects have been freed to a frozen slab (i.e. a remote cpu
slab).
The free_frozen file shows how many objects have been freed to
a frozen slab (i.e. a remote cpu slab). It can be written to
clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/free_remove_partial
@@ -244,9 +249,10 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file free_remove_partial is read-only and specifies how
many times an object has been freed to a now-empty slab so
that it had to be removed from its node's partial list.
The free_remove_partial file shows how many times an object has
been freed to a now-empty slab so that it had to be removed from
its node's partial list. It can be written to clear the current
count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/free_slab
@@ -255,8 +261,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The free_slab file is read-only and specifies how many times an
empty slab has been freed back to the page allocator.
The free_slab file shows how many times an empty slab has been
freed back to the page allocator. It can be written to clear
the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/free_slowpath
@@ -265,9 +272,9 @@ KernelVersion: 2.6.25
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The free_slowpath file is read-only and specifies how many
objects have been freed using the slow path (i.e. to a full or
partial slab).
The free_slowpath file shows how many objects have been freed
using the slow path (i.e. to a full or partial slab). It can
be written to clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/hwcache_align
@@ -346,10 +353,10 @@ KernelVersion: 2.6.26
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
Christoph Lameter <cl@linux-foundation.org>
Description:
The file order_fallback is read-only and specifies how many
times an allocation of a new slab has not been possible at the
cache's order and instead fallen back to its minimum possible
order.
The order_fallback file shows how many times an allocation of a
new slab has not been possible at the cache's order and instead
fallen back to its minimum possible order. It can be written to
clear the current count.
Available when CONFIG_SLUB_STATS is enabled.
What: /sys/kernel/slab/cache/partial

View File

@@ -0,0 +1,44 @@
What: /sys/devices/system/memory/soft_offline_page
Date: Sep 2009
KernelVersion: 2.6.33
Contact: andi@firstfloor.org
Description:
Soft-offline the memory page containing the physical address
written into this file. Input is a hex number specifying the
physical address of the page. The kernel will then attempt
to soft-offline it, by moving the contents elsewhere or
dropping it if possible. The kernel will then be placed
on the bad page list and never be reused.
The offlining is done in kernel specific granuality.
Normally it's the base page size of the kernel, but
this might change.
The page must be still accessible, not poisoned. The
kernel will never kill anything for this, but rather
fail the offline. Return value is the size of the
number, or a error when the offlining failed. Reading
the file is not allowed.
What: /sys/devices/system/memory/hard_offline_page
Date: Sep 2009
KernelVersion: 2.6.33
Contact: andi@firstfloor.org
Description:
Hard-offline the memory page containing the physical
address written into this file. Input is a hex number
specifying the physical address of the page. The
kernel will then attempt to hard-offline the page, by
trying to drop the page or killing any owner or
triggering IO errors if needed. Note this may kill
any processes owning the page. The kernel will avoid
to access this page assuming it's poisoned by the
hardware.
The offlining is done in kernel specific granuality.
Normally it's the base page size of the kernel, but
this might change.
Return value is the size of the number, or a error when
the offlining failed.
Reading the file is not allowed.

View File

@@ -0,0 +1,12 @@
What: /sys/module/pch_phub/drivers/.../pch_mac
Date: August 2010
KernelVersion: 2.6.35
Contact: masa-korg@dsn.okisemi.com
Description: Write/read GbE MAC address.
What: /sys/module/pch_phub/drivers/.../pch_firmware
Date: August 2010
KernelVersion: 2.6.35
Contact: masa-korg@dsn.okisemi.com
Description: Write/read Option ROM data.

View File

@@ -0,0 +1,66 @@
What: /sys/devices/platform/asus_laptop/display
Date: January 2007
KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
This file allows display switching. The value
is composed by 4 bits and defined as follow:
4321
|||`- LCD
||`-- CRT
|`--- TV
`---- DVI
Ex: - 0 (0000b) means no display
- 3 (0011b) CRT+LCD.
What: /sys/devices/platform/asus_laptop/gps
Date: January 2007
KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Control the gps device. 1 means on, 0 means off.
Users: Lapsus
What: /sys/devices/platform/asus_laptop/ledd
Date: January 2007
KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Some models like the W1N have a LED display that can be
used to display several informations.
To control the LED display, use the following :
echo 0x0T000DDD > /sys/devices/platform/asus_laptop/
where T control the 3 letters display, and DDD the 3 digits display.
The DDD table can be found in Documentation/laptops/asus-laptop.txt
What: /sys/devices/platform/asus_laptop/bluetooth
Date: January 2007
KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Control the bluetooth device. 1 means on, 0 means off.
This may control the led, the device or both.
Users: Lapsus
What: /sys/devices/platform/asus_laptop/wlan
Date: January 2007
KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Control the wlan device. 1 means on, 0 means off.
This may control the led, the device or both.
Users: Lapsus
What: /sys/devices/platform/asus_laptop/wimax
Date: October 2010
KernelVersion: 2.6.37
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Control the wimax device. 1 means on, 0 means off.
What: /sys/devices/platform/asus_laptop/wwan
Date: October 2010
KernelVersion: 2.6.37
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Control the wwan (3G) device. 1 means on, 0 means off.

View File

@@ -0,0 +1,50 @@
What: /sys/devices/platform/eeepc/disp
Date: May 2008
KernelVersion: 2.6.26
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
This file allows display switching.
- 1 = LCD
- 2 = CRT
- 3 = LCD+CRT
If you run X11, you should use xrandr instead.
What: /sys/devices/platform/eeepc/camera
Date: May 2008
KernelVersion: 2.6.26
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Control the camera. 1 means on, 0 means off.
What: /sys/devices/platform/eeepc/cardr
Date: May 2008
KernelVersion: 2.6.26
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Control the card reader. 1 means on, 0 means off.
What: /sys/devices/platform/eeepc/cpufv
Date: Jun 2009
KernelVersion: 2.6.31
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Change CPU clock configuration.
On the Eee PC 1000H there are three available clock configuration:
* 0 -> Super Performance Mode
* 1 -> High Performance Mode
* 2 -> Power Saving Mode
On Eee PC 701 there is only 2 available clock configurations.
Available configuration are listed in available_cpufv file.
Reading this file will show the raw hexadecimal value which
is defined as follow:
| 8 bit | 8 bit |
| `---- Current mode
`------------ Availables modes
For example, 0x301 means: mode 1 selected, 3 available modes.
What: /sys/devices/platform/eeepc/available_cpufv
Date: Jun 2009
KernelVersion: 2.6.31
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
List available cpufv modes.

View File

@@ -0,0 +1,10 @@
What: /sys/devices/platform/eeepc-wmi/cpufv
Date: Oct 2010
KernelVersion: 2.6.37
Contact: "Corentin Chary" <corentincj@iksaif.net>
Description:
Change CPU clock configuration (write-only).
There are three available clock configuration:
* 0 -> Super Performance Mode
* 1 -> High Performance Mode
* 2 -> Power Saving Mode

View File

@@ -0,0 +1,6 @@
What: /sys/devices/platform/ideapad/camera_power
Date: Dec 2010
KernelVersion: 2.6.37
Contact: "Ike Panhc <ike.pan@canonical.com>"
Description:
Control the power of camera module. 1 means on, 0 means off.

View File

@@ -99,5 +99,62 @@ Description:
dmesg -s 1000000 | grep 'hash matches'
If you do not get any matches (or they appear to be false
positives), it is possible that the last PM event point
referred to a device created by a loadable kernel module. In
this case cat /sys/power/pm_trace_dev_match (see below) after
your system is started up and the kernel modules are loaded.
CAUTION: Using it will cause your machine's real-time (CMOS)
clock to be set to a random invalid time after a resume.
What; /sys/power/pm_trace_dev_match
Date: October 2010
Contact: James Hogan <james@albanarts.com>
Description:
The /sys/power/pm_trace_dev_match file contains the name of the
device associated with the last PM event point saved in the RTC
across reboots when pm_trace has been used. More precisely it
contains the list of current devices (including those
registered by loadable kernel modules since boot) which match
the device hash in the RTC at boot, with a newline after each
one.
The advantage of this file over the hash matches printed to the
kernel log (see /sys/power/pm_trace), is that it includes
devices created after boot by loadable kernel modules.
Due to the small hash size necessary to fit in the RTC, it is
possible that more than one device matches the hash, in which
case further investigation is required to determine which
device is causing the problem. Note that genuine RTC clock
values (such as when pm_trace has not been used), can still
match a device and output it's name here.
What: /sys/power/pm_async
Date: January 2009
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/power/pm_async file controls the switch allowing the
user space to enable or disable asynchronous suspend and resume
of devices. If enabled, this feature will cause some device
drivers' suspend and resume callbacks to be executed in parallel
with each other and with the main suspend thread. It is enabled
if this file contains "1", which is the default. It may be
disabled by writing "0" to this file, in which case all devices
will be suspended and resumed synchronously.
What: /sys/power/wakeup_count
Date: July 2010
Contact: Rafael J. Wysocki <rjw@sisk.pl>
Description:
The /sys/power/wakeup_count file allows user space to put the
system into a sleep state while taking into account the
concurrent arrival of wakeup events. Reading from it returns
the current number of registered wakeup events and it blocks if
some wakeup events are being processed at the time the file is
read from. Writing to it will only succeed if the current
number of wakeup events is equal to the written value and, if
successful, will make the kernel abort a subsequent transition
to a sleep state if any wakeup events are reported after the
write has returned.

View File

@@ -0,0 +1,19 @@
What: /sys/class/tty/console/active
Date: Nov 2010
Contact: Kay Sievers <kay.sievers@vrfy.org>
Description:
Shows the list of currently configured
console devices, like 'tty1 ttyS0'.
The last entry in the file is the active
device connected to /dev/console.
The file supports poll() to detect virtual
console switches.
What: /sys/class/tty/tty0/active
Date: Nov 2010
Contact: Kay Sievers <kay.sievers@vrfy.org>
Description:
Shows the currently active virtual console
device, like 'tty1'.
The file supports poll() to detect virtual
console switches.

View 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.

View File

@@ -49,6 +49,8 @@ o oprofile 0.9 # oprofiled --version
o udev 081 # udevinfo -V
o grub 0.93 # grub --version
o mcelog 0.6
o iptables 1.4.2 # iptables -V
Kernel compilation
==================
@@ -329,7 +331,7 @@ o <ftp://ftp.kernel.org/pub/linux/kernel/people/rusty/modules/>
Mkinitrd
--------
o <ftp://rawhide.redhat.com/pub/rawhide/SRPMS/SRPMS/>
o <https://code.launchpad.net/initrd-tools/main>
E2fsprogs
---------
@@ -341,11 +343,11 @@ o <http://jfs.sourceforge.net/>
Reiserfsprogs
-------------
o <http://www.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.6.3.tar.gz>
o <http://www.kernel.org/pub/linux/utils/fs/reiserfs/>
Xfsprogs
--------
o <ftp://oss.sgi.com/projects/xfs/download/>
o <ftp://oss.sgi.com/projects/xfs/>
Pcmciautils
-----------
@@ -385,18 +387,18 @@ o <http://sourceforge.net/projects/fuse>
mcelog
------
o <ftp://ftp.kernel.org/pub/linux/utils/cpu/mce/mcelog/>
o <ftp://ftp.kernel.org/pub/linux/utils/cpu/mce/>
Networking
**********
PPP
---
o <ftp://ftp.samba.org/pub/ppp/ppp-2.4.0.tar.gz>
o <ftp://ftp.samba.org/pub/ppp/>
Isdn4k-utils
------------
o <ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/isdn4k-utils.v3.1pre1.tar.gz>
o <ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/>
NFS-utils
---------

View File

@@ -0,0 +1,781 @@
Dynamic DMA mapping Guide
=========================
David S. Miller <davem@redhat.com>
Richard Henderson <rth@cygnus.com>
Jakub Jelinek <jakub@redhat.com>
This is a guide to device driver writers on how to use the DMA API
with example pseudo-code. For a concise description of the API, see
DMA-API.txt.
Most of the 64bit platforms have special hardware that translates bus
addresses (DMA addresses) into physical addresses. This is similar to
how page tables and/or a TLB translates virtual addresses to physical
addresses on a CPU. This is needed so that e.g. PCI devices can
access with a Single Address Cycle (32bit DMA address) any page in the
64bit physical address space. Previously in Linux those 64bit
platforms had to set artificial limits on the maximum RAM size in the
system, so that the virt_to_bus() static scheme works (the DMA address
translation tables were simply filled on bootup to map each bus
address to the physical page __pa(bus_to_virt())).
So that Linux can use the dynamic DMA mapping, it needs some help from the
drivers, namely it has to take into account that DMA addresses should be
mapped only for the time they are actually used and unmapped after the DMA
transfer.
The following API will work of course even on platforms where no such
hardware exists.
Note that the DMA API works with any bus independent of the underlying
microprocessor architecture. You should use the DMA API rather than
the bus specific DMA API (e.g. pci_dma_*).
First of all, you should make sure
#include <linux/dma-mapping.h>
is in your driver. This file will obtain for you the definition of the
dma_addr_t (which can hold any valid DMA address for the platform)
type which should be used everywhere you hold a DMA (bus) address
returned from the DMA mapping functions.
What memory is DMA'able?
The first piece of information you must know is what kernel memory can
be used with the DMA mapping facilities. There has been an unwritten
set of rules regarding this, and this text is an attempt to finally
write them down.
If you acquired your memory via the page allocator
(i.e. __get_free_page*()) or the generic memory allocators
(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
that memory using the addresses returned from those routines.
This means specifically that you may _not_ use the memory/addresses
returned from vmalloc() for DMA. It is possible to DMA to the
_underlying_ memory mapped into a vmalloc() area, but this requires
walking page tables to get the physical addresses, and then
translating each of those pages back to a kernel address using
something like __va(). [ EDIT: Update this when we integrate
Gerd Knorr's generic code which does this. ]
This rule also means that you may use neither kernel image addresses
(items in data/text/bss segments), nor module image addresses, nor
stack addresses for DMA. These could all be mapped somewhere entirely
different than the rest of physical memory. Even if those classes of
memory could physically work with DMA, you'd need to ensure the I/O
buffers were cacheline-aligned. Without that, you'd see cacheline
sharing problems (data corruption) on CPUs with DMA-incoherent caches.
(The CPU could write to one word, DMA would write to a different one
in the same cache line, and one of them could be overwritten.)
Also, this means that you cannot take the return of a kmap()
call and DMA to/from that. This is similar to vmalloc().
What about block I/O and networking buffers? The block I/O and
networking subsystems make sure that the buffers they use are valid
for you to DMA from/to.
DMA addressing limitations
Does your device have any DMA addressing limitations? For example, is
your device only capable of driving the low order 24-bits of address?
If so, you need to inform the kernel of this fact.
By default, the kernel assumes that your device can address the full
32-bits. For a 64-bit capable device, this needs to be increased.
And for a device with limitations, as discussed in the previous
paragraph, it needs to be decreased.
Special note about PCI: PCI-X specification requires PCI-X devices to
support 64-bit addressing (DAC) for all transactions. And at least
one platform (SGI SN2) requires 64-bit consistent allocations to
operate correctly when the IO bus is in PCI-X mode.
For correct operation, you must interrogate the kernel in your device
probe routine to see if the DMA controller on the machine can properly
support the DMA addressing limitation your device has. It is good
style to do this even if your device holds the default setting,
because this shows that you did think about these issues wrt. your
device.
The query is performed via a call to dma_set_mask():
int dma_set_mask(struct device *dev, u64 mask);
The query for consistent allocations is performed via a call to
dma_set_coherent_mask():
int dma_set_coherent_mask(struct device *dev, u64 mask);
Here, dev is a pointer to the device struct of your device, and mask
is a bit mask describing which bits of an address your device
supports. It returns zero if your card can perform DMA properly on
the machine given the address mask you provided. In general, the
device struct of your device is embedded in the bus specific device
struct of your device. For example, a pointer to the device struct of
your PCI device is pdev->dev (pdev is a pointer to the PCI device
struct of your device).
If it returns non-zero, your device cannot perform DMA properly on
this platform, and attempting to do so will result in undefined
behavior. You must either use a different mask, or not use DMA.
This means that in the failure case, you have three options:
1) Use another DMA mask, if possible (see below).
2) Use some non-DMA mode for data transfer, if possible.
3) Ignore this device and do not initialize it.
It is recommended that your driver print a kernel KERN_WARNING message
when you end up performing either #2 or #3. In this manner, if a user
of your driver reports that performance is bad or that the device is not
even detected, you can ask them for the kernel messages to find out
exactly why.
The standard 32-bit addressing device would do something like this:
if (dma_set_mask(dev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING
"mydev: No suitable DMA available.\n");
goto ignore_this_device;
}
Another common scenario is a 64-bit capable device. The approach here
is to try for 64-bit addressing, but back down to a 32-bit mask that
should not fail. The kernel may fail the 64-bit mask not because the
platform is not capable of 64-bit addressing. Rather, it may fail in
this case simply because 32-bit addressing is done more efficiently
than 64-bit addressing. For example, Sparc64 PCI SAC addressing is
more efficient than DAC addressing.
Here is how you would handle a 64-bit capable device which can drive
all 64-bits when accessing streaming DMA:
int using_dac;
if (!dma_set_mask(dev, DMA_BIT_MASK(64))) {
using_dac = 1;
} else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) {
using_dac = 0;
} else {
printk(KERN_WARNING
"mydev: No suitable DMA available.\n");
goto ignore_this_device;
}
If a card is capable of using 64-bit consistent allocations as well,
the case would look like this:
int using_dac, consistent_using_dac;
if (!dma_set_mask(dev, DMA_BIT_MASK(64))) {
using_dac = 1;
consistent_using_dac = 1;
dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
} else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) {
using_dac = 0;
consistent_using_dac = 0;
dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
} else {
printk(KERN_WARNING
"mydev: No suitable DMA available.\n");
goto ignore_this_device;
}
dma_set_coherent_mask() will always be able to set the same or a
smaller mask as dma_set_mask(). However for the rare case that a
device driver only uses consistent allocations, one would have to
check the return value from dma_set_coherent_mask().
Finally, if your device can only drive the low 24-bits of
address you might do something like:
if (dma_set_mask(dev, DMA_BIT_MASK(24))) {
printk(KERN_WARNING
"mydev: 24-bit DMA addressing not available.\n");
goto ignore_this_device;
}
When dma_set_mask() is successful, and returns zero, the kernel saves
away this mask you have provided. The kernel will use this
information later when you make DMA mappings.
There is a case which we are aware of at this time, which is worth
mentioning in this documentation. If your device supports multiple
functions (for example a sound card provides playback and record
functions) and the various different functions have _different_
DMA addressing limitations, you may wish to probe each mask and
only provide the functionality which the machine can handle. It
is important that the last call to dma_set_mask() be for the
most specific mask.
Here is pseudo-code showing how this might be done:
#define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32)
#define RECORD_ADDRESS_BITS DMA_BIT_MASK(24)
struct my_sound_card *card;
struct device *dev;
...
if (!dma_set_mask(dev, PLAYBACK_ADDRESS_BITS)) {
card->playback_enabled = 1;
} else {
card->playback_enabled = 0;
printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n",
card->name);
}
if (!dma_set_mask(dev, RECORD_ADDRESS_BITS)) {
card->record_enabled = 1;
} else {
card->record_enabled = 0;
printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n",
card->name);
}
A sound card was used as an example here because this genre of PCI
devices seems to be littered with ISA chips given a PCI front end,
and thus retaining the 16MB DMA addressing limitations of ISA.
Types of DMA mappings
There are two types of DMA mappings:
- Consistent DMA mappings which are usually mapped at driver
initialization, unmapped at the end and for which the hardware should
guarantee that the device and the CPU can access the data
in parallel and will see updates made by each other without any
explicit software flushing.
Think of "consistent" as "synchronous" or "coherent".
The current default is to return consistent memory in the low 32
bits of the bus space. However, for future compatibility you should
set the consistent mask even if this default is fine for your
driver.
Good examples of what to use consistent mappings for are:
- Network card DMA ring descriptors.
- SCSI adapter mailbox command data structures.
- Device firmware microcode executed out of
main memory.
The invariant these examples all require is that any CPU store
to memory is immediately visible to the device, and vice
versa. Consistent mappings guarantee this.
IMPORTANT: Consistent DMA memory does not preclude the usage of
proper memory barriers. The CPU may reorder stores to
consistent memory just as it may normal memory. Example:
if it is important for the device to see the first word
of a descriptor updated before the second, you must do
something like:
desc->word0 = address;
wmb();
desc->word1 = DESC_VALID;
in order to get correct behavior on all platforms.
Also, on some platforms your driver may need to flush CPU write
buffers in much the same way as it needs to flush write buffers
found in PCI bridges (such as by reading a register's value
after writing it).
- Streaming DMA mappings which are usually mapped for one DMA
transfer, unmapped right after it (unless you use dma_sync_* below)
and for which hardware can optimize for sequential accesses.
This of "streaming" as "asynchronous" or "outside the coherency
domain".
Good examples of what to use streaming mappings for are:
- Networking buffers transmitted/received by a device.
- Filesystem buffers written/read by a SCSI device.
The interfaces for using this type of mapping were designed in
such a way that an implementation can make whatever performance
optimizations the hardware allows. To this end, when using
such mappings you must be explicit about what you want to happen.
Neither type of DMA mapping has alignment restrictions that come from
the underlying bus, although some devices may have such restrictions.
Also, systems with caches that aren't DMA-coherent will work better
when the underlying buffers don't share cache lines with other data.
Using Consistent DMA mappings.
To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
you should do:
dma_addr_t dma_handle;
cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, gfp);
where device is a struct device *. This may be called in interrupt
context with the GFP_ATOMIC flag.
Size is the length of the region you want to allocate, in bytes.
This routine will allocate RAM for that region, so it acts similarly to
__get_free_pages (but takes size instead of a page order). If your
driver needs regions sized smaller than a page, you may prefer using
the dma_pool interface, described below.
The consistent DMA mapping interfaces, for non-NULL dev, will by
default return a DMA address which is 32-bit addressable. Even if the
device indicates (via DMA mask) that it may address the upper 32-bits,
consistent allocation will only return > 32-bit addresses for DMA if
the consistent DMA mask has been explicitly changed via
dma_set_coherent_mask(). This is true of the dma_pool interface as
well.
dma_alloc_coherent returns two values: the virtual address which you
can use to access it from the CPU and dma_handle which you pass to the
card.
The cpu return address and the DMA bus master address are both
guaranteed to be aligned to the smallest PAGE_SIZE order which
is greater than or equal to the requested size. This invariant
exists (for example) to guarantee that if you allocate a chunk
which is smaller than or equal to 64 kilobytes, the extent of the
buffer you receive will not cross a 64K boundary.
To unmap and free such a DMA region, you call:
dma_free_coherent(dev, size, cpu_addr, dma_handle);
where dev, size are the same as in the above call and cpu_addr and
dma_handle are the values dma_alloc_coherent returned to you.
This function may not be called in interrupt context.
If your driver needs lots of smaller memory regions, you can write
custom code to subdivide pages returned by dma_alloc_coherent,
or you can use the dma_pool API to do that. A dma_pool is like
a kmem_cache, but it uses dma_alloc_coherent not __get_free_pages.
Also, it understands common hardware constraints for alignment,
like queue heads needing to be aligned on N byte boundaries.
Create a dma_pool like this:
struct dma_pool *pool;
pool = dma_pool_create(name, dev, size, align, alloc);
The "name" is for diagnostics (like a kmem_cache name); dev and size
are as above. The device's hardware alignment requirement for this
type of data is "align" (which is expressed in bytes, and must be a
power of two). If your device has no boundary crossing restrictions,
pass 0 for alloc; passing 4096 says memory allocated from this pool
must not cross 4KByte boundaries (but at that time it may be better to
go for dma_alloc_coherent directly instead).
Allocate memory from a dma pool like this:
cpu_addr = dma_pool_alloc(pool, flags, &dma_handle);
flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
holding SMP locks), SLAB_ATOMIC otherwise. Like dma_alloc_coherent,
this returns two values, cpu_addr and dma_handle.
Free memory that was allocated from a dma_pool like this:
dma_pool_free(pool, cpu_addr, dma_handle);
where pool is what you passed to dma_pool_alloc, and cpu_addr and
dma_handle are the values dma_pool_alloc returned. This function
may be called in interrupt context.
Destroy a dma_pool by calling:
dma_pool_destroy(pool);
Make sure you've called dma_pool_free for all memory allocated
from a pool before you destroy the pool. This function may not
be called in interrupt context.
DMA Direction
The interfaces described in subsequent portions of this document
take a DMA direction argument, which is an integer and takes on
one of the following values:
DMA_BIDIRECTIONAL
DMA_TO_DEVICE
DMA_FROM_DEVICE
DMA_NONE
One should provide the exact DMA direction if you know it.
DMA_TO_DEVICE means "from main memory to the device"
DMA_FROM_DEVICE means "from the device to main memory"
It is the direction in which the data moves during the DMA
transfer.
You are _strongly_ encouraged to specify this as precisely
as you possibly can.
If you absolutely cannot know the direction of the DMA transfer,
specify DMA_BIDIRECTIONAL. It means that the DMA can go in
either direction. The platform guarantees that you may legally
specify this, and that it will work, but this may be at the
cost of performance for example.
The value DMA_NONE is to be used for debugging. One can
hold this in a data structure before you come to know the
precise direction, and this will help catch cases where your
direction tracking logic has failed to set things up properly.
Another advantage of specifying this value precisely (outside of
potential platform-specific optimizations of such) is for debugging.
Some platforms actually have a write permission boolean which DMA
mappings can be marked with, much like page protections in the user
program address space. Such platforms can and do report errors in the
kernel logs when the DMA controller hardware detects violation of the
permission setting.
Only streaming mappings specify a direction, consistent mappings
implicitly have a direction attribute setting of
DMA_BIDIRECTIONAL.
The SCSI subsystem tells you the direction to use in the
'sc_data_direction' member of the SCSI command your driver is
working on.
For Networking drivers, it's a rather simple affair. For transmit
packets, map/unmap them with the DMA_TO_DEVICE direction
specifier. For receive packets, just the opposite, map/unmap them
with the DMA_FROM_DEVICE direction specifier.
Using Streaming DMA mappings
The streaming DMA mapping routines can be called from interrupt
context. There are two versions of each map/unmap, one which will
map/unmap a single memory region, and one which will map/unmap a
scatterlist.
To map a single region, you do:
struct device *dev = &my_dev->dev;
dma_addr_t dma_handle;
void *addr = buffer->ptr;
size_t size = buffer->len;
dma_handle = dma_map_single(dev, addr, size, direction);
and to unmap it:
dma_unmap_single(dev, dma_handle, size, direction);
You should call dma_unmap_single when the DMA activity is finished, e.g.
from the interrupt which told you that the DMA transfer is done.
Using cpu pointers like this for single mappings has a disadvantage,
you cannot reference HIGHMEM memory in this way. Thus, there is a
map/unmap interface pair akin to dma_{map,unmap}_single. These
interfaces deal with page/offset pairs instead of cpu pointers.
Specifically:
struct device *dev = &my_dev->dev;
dma_addr_t dma_handle;
struct page *page = buffer->page;
unsigned long offset = buffer->offset;
size_t size = buffer->len;
dma_handle = dma_map_page(dev, page, offset, size, direction);
...
dma_unmap_page(dev, dma_handle, size, direction);
Here, "offset" means byte offset within the given page.
With scatterlists, you map a region gathered from several regions by:
int i, count = dma_map_sg(dev, sglist, nents, direction);
struct scatterlist *sg;
for_each_sg(sglist, sg, count, i) {
hw_address[i] = sg_dma_address(sg);
hw_len[i] = sg_dma_len(sg);
}
where nents is the number of entries in the sglist.
The implementation is free to merge several consecutive sglist entries
into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
consecutive sglist entries can be merged into one provided the first one
ends and the second one starts on a page boundary - in fact this is a huge
advantage for cards which either cannot do scatter-gather or have very
limited number of scatter-gather entries) and returns the actual number
of sg entries it mapped them to. On failure 0 is returned.
Then you should loop count times (note: this can be less than nents times)
and use sg_dma_address() and sg_dma_len() macros where you previously
accessed sg->address and sg->length as shown above.
To unmap a scatterlist, just call:
dma_unmap_sg(dev, sglist, nents, direction);
Again, make sure DMA activity has already finished.
PLEASE NOTE: The 'nents' argument to the dma_unmap_sg call must be
the _same_ one you passed into the dma_map_sg call,
it should _NOT_ be the 'count' value _returned_ from the
dma_map_sg call.
Every dma_map_{single,sg} call should have its dma_unmap_{single,sg}
counterpart, because the bus address space is a shared resource (although
in some ports the mapping is per each BUS so less devices contend for the
same bus address space) and you could render the machine unusable by eating
all bus addresses.
If you need to use the same streaming DMA region multiple times and touch
the data in between the DMA transfers, the buffer needs to be synced
properly in order for the cpu and device to see the most uptodate and
correct copy of the DMA buffer.
So, firstly, just map it with dma_map_{single,sg}, and after each DMA
transfer call either:
dma_sync_single_for_cpu(dev, dma_handle, size, direction);
or:
dma_sync_sg_for_cpu(dev, sglist, nents, direction);
as appropriate.
Then, if you wish to let the device get at the DMA area again,
finish accessing the data with the cpu, and then before actually
giving the buffer to the hardware call either:
dma_sync_single_for_device(dev, dma_handle, size, direction);
or:
dma_sync_sg_for_device(dev, sglist, nents, direction);
as appropriate.
After the last DMA transfer call one of the DMA unmap routines
dma_unmap_{single,sg}. If you don't touch the data from the first dma_map_*
call till dma_unmap_*, then you don't have to call the dma_sync_*
routines at all.
Here is pseudo code which shows a situation in which you would need
to use the dma_sync_*() interfaces.
my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
{
dma_addr_t mapping;
mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE);
cp->rx_buf = buffer;
cp->rx_len = len;
cp->rx_dma = mapping;
give_rx_buf_to_card(cp);
}
...
my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs)
{
struct my_card *cp = devid;
...
if (read_card_status(cp) == RX_BUF_TRANSFERRED) {
struct my_card_header *hp;
/* Examine the header to see if we wish
* to accept the data. But synchronize
* the DMA transfer with the CPU first
* so that we see updated contents.
*/
dma_sync_single_for_cpu(&cp->dev, cp->rx_dma,
cp->rx_len,
DMA_FROM_DEVICE);
/* Now it is safe to examine the buffer. */
hp = (struct my_card_header *) cp->rx_buf;
if (header_is_ok(hp)) {
dma_unmap_single(&cp->dev, cp->rx_dma, cp->rx_len,
DMA_FROM_DEVICE);
pass_to_upper_layers(cp->rx_buf);
make_and_setup_new_rx_buf(cp);
} else {
/* Just sync the buffer and give it back
* to the card.
*/
dma_sync_single_for_device(&cp->dev,
cp->rx_dma,
cp->rx_len,
DMA_FROM_DEVICE);
give_rx_buf_to_card(cp);
}
}
}
Drivers converted fully to this interface should not use virt_to_bus any
longer, nor should they use bus_to_virt. Some drivers have to be changed a
little bit, because there is no longer an equivalent to bus_to_virt in the
dynamic DMA mapping scheme - you have to always store the DMA addresses
returned by the dma_alloc_coherent, dma_pool_alloc, and dma_map_single
calls (dma_map_sg stores them in the scatterlist itself if the platform
supports dynamic DMA mapping in hardware) in your driver structures and/or
in the card registers.
All drivers should be using these interfaces with no exceptions. It
is planned to completely remove virt_to_bus() and bus_to_virt() as
they are entirely deprecated. Some ports already do not provide these
as it is impossible to correctly support them.
Handling Errors
DMA address space is limited on some architectures and an allocation
failure can be determined by:
- checking if dma_alloc_coherent returns NULL or dma_map_sg returns 0
- checking the returned dma_addr_t of dma_map_single and dma_map_page
by using dma_mapping_error():
dma_addr_t dma_handle;
dma_handle = dma_map_single(dev, addr, size, direction);
if (dma_mapping_error(dev, dma_handle)) {
/*
* reduce current DMA mapping usage,
* delay and try again later or
* reset driver.
*/
}
Networking drivers must call dev_kfree_skb to free the socket buffer
and return NETDEV_TX_OK if the DMA mapping fails on the transmit hook
(ndo_start_xmit). This means that the socket buffer is just dropped in
the failure case.
SCSI drivers must return SCSI_MLQUEUE_HOST_BUSY if the DMA mapping
fails in the queuecommand hook. This means that the SCSI subsystem
passes the command to the driver again later.
Optimizing Unmap State Space Consumption
On many platforms, dma_unmap_{single,page}() is simply a nop.
Therefore, keeping track of the mapping address and length is a waste
of space. Instead of filling your drivers up with ifdefs and the like
to "work around" this (which would defeat the whole purpose of a
portable API) the following facilities are provided.
Actually, instead of describing the macros one by one, we'll
transform some example code.
1) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures.
Example, before:
struct ring_state {
struct sk_buff *skb;
dma_addr_t mapping;
__u32 len;
};
after:
struct ring_state {
struct sk_buff *skb;
DEFINE_DMA_UNMAP_ADDR(mapping);
DEFINE_DMA_UNMAP_LEN(len);
};
2) Use dma_unmap_{addr,len}_set to set these values.
Example, before:
ringp->mapping = FOO;
ringp->len = BAR;
after:
dma_unmap_addr_set(ringp, mapping, FOO);
dma_unmap_len_set(ringp, len, BAR);
3) Use dma_unmap_{addr,len} to access these values.
Example, before:
dma_unmap_single(dev, ringp->mapping, ringp->len,
DMA_FROM_DEVICE);
after:
dma_unmap_single(dev,
dma_unmap_addr(ringp, mapping),
dma_unmap_len(ringp, len),
DMA_FROM_DEVICE);
It really should be self-explanatory. We treat the ADDR and LEN
separately, because it is possible for an implementation to only
need the address in order to perform the unmap operation.
Platform Issues
If you are just writing drivers for Linux and do not maintain
an architecture port for the kernel, you can safely skip down
to "Closing".
1) Struct scatterlist requirements.
Don't invent the architecture specific struct scatterlist; just use
<asm-generic/scatterlist.h>. You need to enable
CONFIG_NEED_SG_DMA_LENGTH if the architecture supports IOMMUs
(including software IOMMU).
2) ARCH_DMA_MINALIGN
Architectures must ensure that kmalloc'ed buffer is
DMA-safe. Drivers and subsystems depend on it. If an architecture
isn't fully DMA-coherent (i.e. hardware doesn't ensure that data in
the CPU cache is identical to data in main memory),
ARCH_DMA_MINALIGN must be set so that the memory allocator
makes sure that kmalloc'ed buffer doesn't share a cache line with
the others. See arch/arm/include/asm/cache.h as an example.
Note that ARCH_DMA_MINALIGN is about DMA memory alignment
constraints. You don't need to worry about the architecture data
alignment constraints (e.g. the alignment constraints about 64-bit
objects).
3) Supporting multiple types of IOMMUs
If your architecture needs to support multiple types of IOMMUs, you
can use include/linux/asm-generic/dma-mapping-common.h. It's a
library to support the DMA API with multiple types of IOMMUs. Lots
of architectures (x86, powerpc, sh, alpha, ia64, microblaze and
sparc) use it. Choose one to see how it can be used. If you need to
support multiple types of IOMMUs in a single system, the example of
x86 or powerpc helps.
Closing
This document, and the API itself, would not be in its current
form without the feedback and suggestions from numerous individuals.
We would like to specifically mention, in no particular order, the
following people:
Russell King <rmk@arm.linux.org.uk>
Leo Dagum <dagum@barrel.engr.sgi.com>
Ralf Baechle <ralf@oss.sgi.com>
Grant Grundler <grundler@cup.hp.com>
Jay Estabrook <Jay.Estabrook@compaq.com>
Thomas Sailer <sailer@ife.ee.ethz.ch>
Andrea Arcangeli <andrea@suse.de>
Jens Axboe <jens.axboe@oracle.com>
David Mosberger-Tang <davidm@hpl.hp.com>

View File

@@ -4,20 +4,18 @@
James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
This document describes the DMA API. For a more gentle introduction
phrased in terms of the pci_ equivalents (and actual examples) see
Documentation/PCI/PCI-DMA-mapping.txt.
of the API (and actual examples) see
Documentation/DMA-API-HOWTO.txt.
This API is split into two pieces. Part I describes the API and the
corresponding pci_ API. Part II describes the extensions to the API
for supporting non-consistent memory machines. Unless you know that
your driver absolutely has to support non-consistent platforms (this
is usually only legacy platforms) you should only use the API
described in part I.
This API is split into two pieces. Part I describes the API. Part II
describes the extensions to the API for supporting non-consistent
memory machines. Unless you know that your driver absolutely has to
support non-consistent platforms (this is usually only legacy
platforms) you should only use the API described in part I.
Part I - pci_ and dma_ Equivalent API
Part I - dma_ API
-------------------------------------
To get the pci_ API, you must #include <linux/pci.h>
To get the dma_ API, you must #include <linux/dma-mapping.h>
@@ -27,9 +25,6 @@ Part Ia - Using large dma-coherent buffers
void *
dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
void *
pci_alloc_consistent(struct pci_dev *dev, size_t size,
dma_addr_t *dma_handle)
Consistent memory is memory for which a write by either the device or
the processor can immediately be read by the processor or device
@@ -53,15 +48,11 @@ The simplest way to do that is to use the dma_pool calls (see below).
The flag parameter (dma_alloc_coherent only) allows the caller to
specify the GFP_ flags (see kmalloc) for the allocation (the
implementation may choose to ignore flags that affect the location of
the returned memory, like GFP_DMA). For pci_alloc_consistent, you
must assume GFP_ATOMIC behaviour.
the returned memory, like GFP_DMA).
void
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_handle)
void
pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr,
dma_addr_t dma_handle)
Free the region of consistent memory you previously allocated. dev,
size and dma_handle must all be the same as those passed into the
@@ -89,10 +80,6 @@ for alignment, like queue heads needing to be aligned on N-byte boundaries.
dma_pool_create(const char *name, struct device *dev,
size_t size, size_t align, size_t alloc);
struct pci_pool *
pci_pool_create(const char *name, struct pci_device *dev,
size_t size, size_t align, size_t alloc);
The pool create() routines initialize a pool of dma-coherent buffers
for use with a given device. It must be called in a context which
can sleep.
@@ -108,9 +95,6 @@ from this pool must not cross 4KByte boundaries.
void *dma_pool_alloc(struct dma_pool *pool, gfp_t gfp_flags,
dma_addr_t *dma_handle);
void *pci_pool_alloc(struct pci_pool *pool, gfp_t gfp_flags,
dma_addr_t *dma_handle);
This allocates memory from the pool; the returned memory will meet the size
and alignment requirements specified at creation time. Pass GFP_ATOMIC to
prevent blocking, or if it's permitted (not in_interrupt, not holding SMP locks),
@@ -122,9 +106,6 @@ pool's device.
void dma_pool_free(struct dma_pool *pool, void *vaddr,
dma_addr_t addr);
void pci_pool_free(struct pci_pool *pool, void *vaddr,
dma_addr_t addr);
This puts memory back into the pool. The pool is what was passed to
the pool allocation routine; the cpu (vaddr) and dma addresses are what
were returned when that routine allocated the memory being freed.
@@ -132,8 +113,6 @@ were returned when that routine allocated the memory being freed.
void dma_pool_destroy(struct dma_pool *pool);
void pci_pool_destroy(struct pci_pool *pool);
The pool destroy() routines free the resources of the pool. They must be
called in a context which can sleep. Make sure you've freed all allocated
memory back to the pool before you destroy it.
@@ -144,8 +123,6 @@ Part Ic - DMA addressing limitations
int
dma_supported(struct device *dev, u64 mask)
int
pci_dma_supported(struct pci_dev *hwdev, u64 mask)
Checks to see if the device can support DMA to the memory described by
mask.
@@ -159,8 +136,14 @@ driver writers.
int
dma_set_mask(struct device *dev, u64 mask)
Checks to see if the mask is possible and updates the device
parameters if it is.
Returns: 0 if successful and a negative error if not.
int
pci_set_dma_mask(struct pci_device *dev, u64 mask)
dma_set_coherent_mask(struct device *dev, u64 mask)
Checks to see if the mask is possible and updates the device
parameters if it is.
@@ -187,9 +170,6 @@ Part Id - Streaming DMA mappings
dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
dma_addr_t
pci_map_single(struct pci_dev *hwdev, void *cpu_addr, size_t size,
int direction)
Maps a piece of processor virtual memory so it can be accessed by the
device and returns the physical handle of the memory.
@@ -198,14 +178,10 @@ The direction for both api's may be converted freely by casting.
However the dma_ API uses a strongly typed enumerator for its
direction:
DMA_NONE = PCI_DMA_NONE no direction (used for
debugging)
DMA_TO_DEVICE = PCI_DMA_TODEVICE data is going from the
memory to the device
DMA_FROM_DEVICE = PCI_DMA_FROMDEVICE data is coming from
the device to the
memory
DMA_BIDIRECTIONAL = PCI_DMA_BIDIRECTIONAL direction isn't known
DMA_NONE no direction (used for debugging)
DMA_TO_DEVICE data is going from the memory to the device
DMA_FROM_DEVICE data is coming from the device to the memory
DMA_BIDIRECTIONAL direction isn't known
Notes: Not all memory regions in a machine can be mapped by this
API. Further, regions that appear to be physically contiguous in
@@ -268,9 +244,6 @@ cache lines are updated with data that the device may have changed).
void
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
void
pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
size_t size, int direction)
Unmaps the region previously mapped. All the parameters passed in
must be identical to those passed in (and returned) by the mapping
@@ -280,15 +253,9 @@ dma_addr_t
dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction direction)
dma_addr_t
pci_map_page(struct pci_dev *hwdev, struct page *page,
unsigned long offset, size_t size, int direction)
void
dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
enum dma_data_direction direction)
void
pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
size_t size, int direction)
API for mapping and unmapping for pages. All the notes and warnings
for the other mapping APIs apply here. Also, although the <offset>
@@ -299,9 +266,6 @@ cache width is.
int
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
int
pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr)
In some circumstances dma_map_single and dma_map_page will fail to create
a mapping. A driver can check for these errors by testing the returned
dma address with dma_mapping_error(). A non-zero return value means the mapping
@@ -311,9 +275,6 @@ reduce current DMA mapping usage or delay and try again later).
int
dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction direction)
int
pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
Returns: the number of physical segments mapped (this may be shorter
than <nents> passed in if some elements of the scatter/gather list are
@@ -353,9 +314,6 @@ accessed sg->address and sg->length as shown above.
void
dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction direction)
void
pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
Unmap the previously mapped scatter/gather list. All the parameters
must be the same as those and passed in to the scatter/gather mapping
@@ -365,21 +323,23 @@ Note: <nents> must be the number you passed in, *not* the number of
physical entries returned.
void
dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
void
pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle,
size_t size, int direction)
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
void
dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
enum dma_data_direction direction)
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
enum dma_data_direction direction)
void
pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nelems, int direction)
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
enum dma_data_direction direction)
Synchronise a single contiguous or scatter/gather mapping. All the
parameters must be the same as those passed into the single mapping
API.
Synchronise a single contiguous or scatter/gather mapping for the cpu
and device. With the sync_sg API, all the parameters must be the same
as those passed into the single mapping API. With the sync_single API,
you can use dma_handle and size parameters that aren't identical to
those passed into the single mapping API to do a partial sync.
Notes: You must do this:
@@ -461,9 +421,9 @@ void whizco_dma_map_sg_attrs(struct device *dev, dma_addr_t dma_addr,
Part II - Advanced dma_ usage
-----------------------------
Warning: These pieces of the DMA API have no PCI equivalent. They
should also not be used in the majority of cases, since they cater for
unlikely corner cases that don't belong in usual drivers.
Warning: These pieces of the DMA API should not be used in the
majority of cases, since they cater for unlikely corner cases that
don't belong in usual drivers.
If you don't understand how cache line coherency works between a
processor and an I/O device, you should not be using this part of the
@@ -495,12 +455,6 @@ Free memory allocated by the nonconsistent API. All parameters must
be identical to those passed in (and returned by
dma_alloc_noncoherent()).
int
dma_is_consistent(struct device *dev, dma_addr_t dma_handle)
Returns true if the device dev is performing consistent DMA on the memory
area pointed to by the dma_handle.
int
dma_get_cache_alignment(void)
@@ -513,16 +467,6 @@ line, but it will guarantee that one or more cache lines fit exactly
into the width returned by this call. It will also always be a power
of two for easy alignment.
void
dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
unsigned long offset, size_t size,
enum dma_data_direction direction)
Does a partial sync, starting at offset and continuing for size. You
must be careful to observe the cache alignment and width when doing
anything like this. You must also be extra careful about accessing
memory you intend to sync partially.
void
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)

View File

@@ -1,766 +0,0 @@
Dynamic DMA mapping
===================
David S. Miller <davem@redhat.com>
Richard Henderson <rth@cygnus.com>
Jakub Jelinek <jakub@redhat.com>
This document describes the DMA mapping system in terms of the pci_
API. For a similar API that works for generic devices, see
DMA-API.txt.
Most of the 64bit platforms have special hardware that translates bus
addresses (DMA addresses) into physical addresses. This is similar to
how page tables and/or a TLB translates virtual addresses to physical
addresses on a CPU. This is needed so that e.g. PCI devices can
access with a Single Address Cycle (32bit DMA address) any page in the
64bit physical address space. Previously in Linux those 64bit
platforms had to set artificial limits on the maximum RAM size in the
system, so that the virt_to_bus() static scheme works (the DMA address
translation tables were simply filled on bootup to map each bus
address to the physical page __pa(bus_to_virt())).
So that Linux can use the dynamic DMA mapping, it needs some help from the
drivers, namely it has to take into account that DMA addresses should be
mapped only for the time they are actually used and unmapped after the DMA
transfer.
The following API will work of course even on platforms where no such
hardware exists, see e.g. arch/x86/include/asm/pci.h for how it is implemented on
top of the virt_to_bus interface.
First of all, you should make sure
#include <linux/pci.h>
is in your driver. This file will obtain for you the definition of the
dma_addr_t (which can hold any valid DMA address for the platform)
type which should be used everywhere you hold a DMA (bus) address
returned from the DMA mapping functions.
What memory is DMA'able?
The first piece of information you must know is what kernel memory can
be used with the DMA mapping facilities. There has been an unwritten
set of rules regarding this, and this text is an attempt to finally
write them down.
If you acquired your memory via the page allocator
(i.e. __get_free_page*()) or the generic memory allocators
(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
that memory using the addresses returned from those routines.
This means specifically that you may _not_ use the memory/addresses
returned from vmalloc() for DMA. It is possible to DMA to the
_underlying_ memory mapped into a vmalloc() area, but this requires
walking page tables to get the physical addresses, and then
translating each of those pages back to a kernel address using
something like __va(). [ EDIT: Update this when we integrate
Gerd Knorr's generic code which does this. ]
This rule also means that you may use neither kernel image addresses
(items in data/text/bss segments), nor module image addresses, nor
stack addresses for DMA. These could all be mapped somewhere entirely
different than the rest of physical memory. Even if those classes of
memory could physically work with DMA, you'd need to ensure the I/O
buffers were cacheline-aligned. Without that, you'd see cacheline
sharing problems (data corruption) on CPUs with DMA-incoherent caches.
(The CPU could write to one word, DMA would write to a different one
in the same cache line, and one of them could be overwritten.)
Also, this means that you cannot take the return of a kmap()
call and DMA to/from that. This is similar to vmalloc().
What about block I/O and networking buffers? The block I/O and
networking subsystems make sure that the buffers they use are valid
for you to DMA from/to.
DMA addressing limitations
Does your device have any DMA addressing limitations? For example, is
your device only capable of driving the low order 24-bits of address
on the PCI bus for SAC DMA transfers? If so, you need to inform the
PCI layer of this fact.
By default, the kernel assumes that your device can address the full
32-bits in a SAC cycle. For a 64-bit DAC capable device, this needs
to be increased. And for a device with limitations, as discussed in
the previous paragraph, it needs to be decreased.
pci_alloc_consistent() by default will return 32-bit DMA addresses.
PCI-X specification requires PCI-X devices to support 64-bit
addressing (DAC) for all transactions. And at least one platform (SGI
SN2) requires 64-bit consistent allocations to operate correctly when
the IO bus is in PCI-X mode. Therefore, like with pci_set_dma_mask(),
it's good practice to call pci_set_consistent_dma_mask() to set the
appropriate mask even if your device only supports 32-bit DMA
(default) and especially if it's a PCI-X device.
For correct operation, you must interrogate the PCI layer in your
device probe routine to see if the PCI controller on the machine can
properly support the DMA addressing limitation your device has. It is
good style to do this even if your device holds the default setting,
because this shows that you did think about these issues wrt. your
device.
The query is performed via a call to pci_set_dma_mask():
int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask);
The query for consistent allocations is performed via a call to
pci_set_consistent_dma_mask():
int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask);
Here, pdev is a pointer to the PCI device struct of your device, and
device_mask is a bit mask describing which bits of a PCI address your
device supports. It returns zero if your card can perform DMA
properly on the machine given the address mask you provided.
If it returns non-zero, your device cannot perform DMA properly on
this platform, and attempting to do so will result in undefined
behavior. You must either use a different mask, or not use DMA.
This means that in the failure case, you have three options:
1) Use another DMA mask, if possible (see below).
2) Use some non-DMA mode for data transfer, if possible.
3) Ignore this device and do not initialize it.
It is recommended that your driver print a kernel KERN_WARNING message
when you end up performing either #2 or #3. In this manner, if a user
of your driver reports that performance is bad or that the device is not
even detected, you can ask them for the kernel messages to find out
exactly why.
The standard 32-bit addressing PCI device would do something like
this:
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING
"mydev: No suitable DMA available.\n");
goto ignore_this_device;
}
Another common scenario is a 64-bit capable device. The approach
here is to try for 64-bit DAC addressing, but back down to a
32-bit mask should that fail. The PCI platform code may fail the
64-bit mask not because the platform is not capable of 64-bit
addressing. Rather, it may fail in this case simply because
32-bit SAC addressing is done more efficiently than DAC addressing.
Sparc64 is one platform which behaves in this way.
Here is how you would handle a 64-bit capable device which can drive
all 64-bits when accessing streaming DMA:
int using_dac;
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
using_dac = 1;
} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
using_dac = 0;
} else {
printk(KERN_WARNING
"mydev: No suitable DMA available.\n");
goto ignore_this_device;
}
If a card is capable of using 64-bit consistent allocations as well,
the case would look like this:
int using_dac, consistent_using_dac;
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
using_dac = 1;
consistent_using_dac = 1;
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
using_dac = 0;
consistent_using_dac = 0;
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
} else {
printk(KERN_WARNING
"mydev: No suitable DMA available.\n");
goto ignore_this_device;
}
pci_set_consistent_dma_mask() will always be able to set the same or a
smaller mask as pci_set_dma_mask(). However for the rare case that a
device driver only uses consistent allocations, one would have to
check the return value from pci_set_consistent_dma_mask().
Finally, if your device can only drive the low 24-bits of
address during PCI bus mastering you might do something like:
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(24))) {
printk(KERN_WARNING
"mydev: 24-bit DMA addressing not available.\n");
goto ignore_this_device;
}
When pci_set_dma_mask() is successful, and returns zero, the PCI layer
saves away this mask you have provided. The PCI layer will use this
information later when you make DMA mappings.
There is a case which we are aware of at this time, which is worth
mentioning in this documentation. If your device supports multiple
functions (for example a sound card provides playback and record
functions) and the various different functions have _different_
DMA addressing limitations, you may wish to probe each mask and
only provide the functionality which the machine can handle. It
is important that the last call to pci_set_dma_mask() be for the
most specific mask.
Here is pseudo-code showing how this might be done:
#define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32)
#define RECORD_ADDRESS_BITS 0x00ffffff
struct my_sound_card *card;
struct pci_dev *pdev;
...
if (!pci_set_dma_mask(pdev, PLAYBACK_ADDRESS_BITS)) {
card->playback_enabled = 1;
} else {
card->playback_enabled = 0;
printk(KERN_WARN "%s: Playback disabled due to DMA limitations.\n",
card->name);
}
if (!pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) {
card->record_enabled = 1;
} else {
card->record_enabled = 0;
printk(KERN_WARN "%s: Record disabled due to DMA limitations.\n",
card->name);
}
A sound card was used as an example here because this genre of PCI
devices seems to be littered with ISA chips given a PCI front end,
and thus retaining the 16MB DMA addressing limitations of ISA.
Types of DMA mappings
There are two types of DMA mappings:
- Consistent DMA mappings which are usually mapped at driver
initialization, unmapped at the end and for which the hardware should
guarantee that the device and the CPU can access the data
in parallel and will see updates made by each other without any
explicit software flushing.
Think of "consistent" as "synchronous" or "coherent".
The current default is to return consistent memory in the low 32
bits of the PCI bus space. However, for future compatibility you
should set the consistent mask even if this default is fine for your
driver.
Good examples of what to use consistent mappings for are:
- Network card DMA ring descriptors.
- SCSI adapter mailbox command data structures.
- Device firmware microcode executed out of
main memory.
The invariant these examples all require is that any CPU store
to memory is immediately visible to the device, and vice
versa. Consistent mappings guarantee this.
IMPORTANT: Consistent DMA memory does not preclude the usage of
proper memory barriers. The CPU may reorder stores to
consistent memory just as it may normal memory. Example:
if it is important for the device to see the first word
of a descriptor updated before the second, you must do
something like:
desc->word0 = address;
wmb();
desc->word1 = DESC_VALID;
in order to get correct behavior on all platforms.
Also, on some platforms your driver may need to flush CPU write
buffers in much the same way as it needs to flush write buffers
found in PCI bridges (such as by reading a register's value
after writing it).
- Streaming DMA mappings which are usually mapped for one DMA transfer,
unmapped right after it (unless you use pci_dma_sync_* below) and for which
hardware can optimize for sequential accesses.
This of "streaming" as "asynchronous" or "outside the coherency
domain".
Good examples of what to use streaming mappings for are:
- Networking buffers transmitted/received by a device.
- Filesystem buffers written/read by a SCSI device.
The interfaces for using this type of mapping were designed in
such a way that an implementation can make whatever performance
optimizations the hardware allows. To this end, when using
such mappings you must be explicit about what you want to happen.
Neither type of DMA mapping has alignment restrictions that come
from PCI, although some devices may have such restrictions.
Also, systems with caches that aren't DMA-coherent will work better
when the underlying buffers don't share cache lines with other data.
Using Consistent DMA mappings.
To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
you should do:
dma_addr_t dma_handle;
cpu_addr = pci_alloc_consistent(pdev, size, &dma_handle);
where pdev is a struct pci_dev *. This may be called in interrupt context.
You should use dma_alloc_coherent (see DMA-API.txt) for buses
where devices don't have struct pci_dev (like ISA, EISA).
This argument is needed because the DMA translations may be bus
specific (and often is private to the bus which the device is attached
to).
Size is the length of the region you want to allocate, in bytes.
This routine will allocate RAM for that region, so it acts similarly to
__get_free_pages (but takes size instead of a page order). If your
driver needs regions sized smaller than a page, you may prefer using
the pci_pool interface, described below.
The consistent DMA mapping interfaces, for non-NULL pdev, will by
default return a DMA address which is SAC (Single Address Cycle)
addressable. Even if the device indicates (via PCI dma mask) that it
may address the upper 32-bits and thus perform DAC cycles, consistent
allocation will only return > 32-bit PCI addresses for DMA if the
consistent dma mask has been explicitly changed via
pci_set_consistent_dma_mask(). This is true of the pci_pool interface
as well.
pci_alloc_consistent returns two values: the virtual address which you
can use to access it from the CPU and dma_handle which you pass to the
card.
The cpu return address and the DMA bus master address are both
guaranteed to be aligned to the smallest PAGE_SIZE order which
is greater than or equal to the requested size. This invariant
exists (for example) to guarantee that if you allocate a chunk
which is smaller than or equal to 64 kilobytes, the extent of the
buffer you receive will not cross a 64K boundary.
To unmap and free such a DMA region, you call:
pci_free_consistent(pdev, size, cpu_addr, dma_handle);
where pdev, size are the same as in the above call and cpu_addr and
dma_handle are the values pci_alloc_consistent returned to you.
This function may not be called in interrupt context.
If your driver needs lots of smaller memory regions, you can write
custom code to subdivide pages returned by pci_alloc_consistent,
or you can use the pci_pool API to do that. A pci_pool is like
a kmem_cache, but it uses pci_alloc_consistent not __get_free_pages.
Also, it understands common hardware constraints for alignment,
like queue heads needing to be aligned on N byte boundaries.
Create a pci_pool like this:
struct pci_pool *pool;
pool = pci_pool_create(name, pdev, size, align, alloc);
The "name" is for diagnostics (like a kmem_cache name); pdev and size
are as above. The device's hardware alignment requirement for this
type of data is "align" (which is expressed in bytes, and must be a
power of two). If your device has no boundary crossing restrictions,
pass 0 for alloc; passing 4096 says memory allocated from this pool
must not cross 4KByte boundaries (but at that time it may be better to
go for pci_alloc_consistent directly instead).
Allocate memory from a pci pool like this:
cpu_addr = pci_pool_alloc(pool, flags, &dma_handle);
flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
holding SMP locks), SLAB_ATOMIC otherwise. Like pci_alloc_consistent,
this returns two values, cpu_addr and dma_handle.
Free memory that was allocated from a pci_pool like this:
pci_pool_free(pool, cpu_addr, dma_handle);
where pool is what you passed to pci_pool_alloc, and cpu_addr and
dma_handle are the values pci_pool_alloc returned. This function
may be called in interrupt context.
Destroy a pci_pool by calling:
pci_pool_destroy(pool);
Make sure you've called pci_pool_free for all memory allocated
from a pool before you destroy the pool. This function may not
be called in interrupt context.
DMA Direction
The interfaces described in subsequent portions of this document
take a DMA direction argument, which is an integer and takes on
one of the following values:
PCI_DMA_BIDIRECTIONAL
PCI_DMA_TODEVICE
PCI_DMA_FROMDEVICE
PCI_DMA_NONE
One should provide the exact DMA direction if you know it.
PCI_DMA_TODEVICE means "from main memory to the PCI device"
PCI_DMA_FROMDEVICE means "from the PCI device to main memory"
It is the direction in which the data moves during the DMA
transfer.
You are _strongly_ encouraged to specify this as precisely
as you possibly can.
If you absolutely cannot know the direction of the DMA transfer,
specify PCI_DMA_BIDIRECTIONAL. It means that the DMA can go in
either direction. The platform guarantees that you may legally
specify this, and that it will work, but this may be at the
cost of performance for example.
The value PCI_DMA_NONE is to be used for debugging. One can
hold this in a data structure before you come to know the
precise direction, and this will help catch cases where your
direction tracking logic has failed to set things up properly.
Another advantage of specifying this value precisely (outside of
potential platform-specific optimizations of such) is for debugging.
Some platforms actually have a write permission boolean which DMA
mappings can be marked with, much like page protections in the user
program address space. Such platforms can and do report errors in the
kernel logs when the PCI controller hardware detects violation of the
permission setting.
Only streaming mappings specify a direction, consistent mappings
implicitly have a direction attribute setting of
PCI_DMA_BIDIRECTIONAL.
The SCSI subsystem tells you the direction to use in the
'sc_data_direction' member of the SCSI command your driver is
working on.
For Networking drivers, it's a rather simple affair. For transmit
packets, map/unmap them with the PCI_DMA_TODEVICE direction
specifier. For receive packets, just the opposite, map/unmap them
with the PCI_DMA_FROMDEVICE direction specifier.
Using Streaming DMA mappings
The streaming DMA mapping routines can be called from interrupt
context. There are two versions of each map/unmap, one which will
map/unmap a single memory region, and one which will map/unmap a
scatterlist.
To map a single region, you do:
struct pci_dev *pdev = mydev->pdev;
dma_addr_t dma_handle;
void *addr = buffer->ptr;
size_t size = buffer->len;
dma_handle = pci_map_single(pdev, addr, size, direction);
and to unmap it:
pci_unmap_single(pdev, dma_handle, size, direction);
You should call pci_unmap_single when the DMA activity is finished, e.g.
from the interrupt which told you that the DMA transfer is done.
Using cpu pointers like this for single mappings has a disadvantage,
you cannot reference HIGHMEM memory in this way. Thus, there is a
map/unmap interface pair akin to pci_{map,unmap}_single. These
interfaces deal with page/offset pairs instead of cpu pointers.
Specifically:
struct pci_dev *pdev = mydev->pdev;
dma_addr_t dma_handle;
struct page *page = buffer->page;
unsigned long offset = buffer->offset;
size_t size = buffer->len;
dma_handle = pci_map_page(pdev, page, offset, size, direction);
...
pci_unmap_page(pdev, dma_handle, size, direction);
Here, "offset" means byte offset within the given page.
With scatterlists, you map a region gathered from several regions by:
int i, count = pci_map_sg(pdev, sglist, nents, direction);
struct scatterlist *sg;
for_each_sg(sglist, sg, count, i) {
hw_address[i] = sg_dma_address(sg);
hw_len[i] = sg_dma_len(sg);
}
where nents is the number of entries in the sglist.
The implementation is free to merge several consecutive sglist entries
into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
consecutive sglist entries can be merged into one provided the first one
ends and the second one starts on a page boundary - in fact this is a huge
advantage for cards which either cannot do scatter-gather or have very
limited number of scatter-gather entries) and returns the actual number
of sg entries it mapped them to. On failure 0 is returned.
Then you should loop count times (note: this can be less than nents times)
and use sg_dma_address() and sg_dma_len() macros where you previously
accessed sg->address and sg->length as shown above.
To unmap a scatterlist, just call:
pci_unmap_sg(pdev, sglist, nents, direction);
Again, make sure DMA activity has already finished.
PLEASE NOTE: The 'nents' argument to the pci_unmap_sg call must be
the _same_ one you passed into the pci_map_sg call,
it should _NOT_ be the 'count' value _returned_ from the
pci_map_sg call.
Every pci_map_{single,sg} call should have its pci_unmap_{single,sg}
counterpart, because the bus address space is a shared resource (although
in some ports the mapping is per each BUS so less devices contend for the
same bus address space) and you could render the machine unusable by eating
all bus addresses.
If you need to use the same streaming DMA region multiple times and touch
the data in between the DMA transfers, the buffer needs to be synced
properly in order for the cpu and device to see the most uptodate and
correct copy of the DMA buffer.
So, firstly, just map it with pci_map_{single,sg}, and after each DMA
transfer call either:
pci_dma_sync_single_for_cpu(pdev, dma_handle, size, direction);
or:
pci_dma_sync_sg_for_cpu(pdev, sglist, nents, direction);
as appropriate.
Then, if you wish to let the device get at the DMA area again,
finish accessing the data with the cpu, and then before actually
giving the buffer to the hardware call either:
pci_dma_sync_single_for_device(pdev, dma_handle, size, direction);
or:
pci_dma_sync_sg_for_device(dev, sglist, nents, direction);
as appropriate.
After the last DMA transfer call one of the DMA unmap routines
pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_*
call till pci_unmap_*, then you don't have to call the pci_dma_sync_*
routines at all.
Here is pseudo code which shows a situation in which you would need
to use the pci_dma_sync_*() interfaces.
my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
{
dma_addr_t mapping;
mapping = pci_map_single(cp->pdev, buffer, len, PCI_DMA_FROMDEVICE);
cp->rx_buf = buffer;
cp->rx_len = len;
cp->rx_dma = mapping;
give_rx_buf_to_card(cp);
}
...
my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs)
{
struct my_card *cp = devid;
...
if (read_card_status(cp) == RX_BUF_TRANSFERRED) {
struct my_card_header *hp;
/* Examine the header to see if we wish
* to accept the data. But synchronize
* the DMA transfer with the CPU first
* so that we see updated contents.
*/
pci_dma_sync_single_for_cpu(cp->pdev, cp->rx_dma,
cp->rx_len,
PCI_DMA_FROMDEVICE);
/* Now it is safe to examine the buffer. */
hp = (struct my_card_header *) cp->rx_buf;
if (header_is_ok(hp)) {
pci_unmap_single(cp->pdev, cp->rx_dma, cp->rx_len,
PCI_DMA_FROMDEVICE);
pass_to_upper_layers(cp->rx_buf);
make_and_setup_new_rx_buf(cp);
} else {
/* Just sync the buffer and give it back
* to the card.
*/
pci_dma_sync_single_for_device(cp->pdev,
cp->rx_dma,
cp->rx_len,
PCI_DMA_FROMDEVICE);
give_rx_buf_to_card(cp);
}
}
}
Drivers converted fully to this interface should not use virt_to_bus any
longer, nor should they use bus_to_virt. Some drivers have to be changed a
little bit, because there is no longer an equivalent to bus_to_virt in the
dynamic DMA mapping scheme - you have to always store the DMA addresses
returned by the pci_alloc_consistent, pci_pool_alloc, and pci_map_single
calls (pci_map_sg stores them in the scatterlist itself if the platform
supports dynamic DMA mapping in hardware) in your driver structures and/or
in the card registers.
All PCI drivers should be using these interfaces with no exceptions.
It is planned to completely remove virt_to_bus() and bus_to_virt() as
they are entirely deprecated. Some ports already do not provide these
as it is impossible to correctly support them.
Optimizing Unmap State Space Consumption
On many platforms, pci_unmap_{single,page}() is simply a nop.
Therefore, keeping track of the mapping address and length is a waste
of space. Instead of filling your drivers up with ifdefs and the like
to "work around" this (which would defeat the whole purpose of a
portable API) the following facilities are provided.
Actually, instead of describing the macros one by one, we'll
transform some example code.
1) Use DECLARE_PCI_UNMAP_{ADDR,LEN} in state saving structures.
Example, before:
struct ring_state {
struct sk_buff *skb;
dma_addr_t mapping;
__u32 len;
};
after:
struct ring_state {
struct sk_buff *skb;
DECLARE_PCI_UNMAP_ADDR(mapping)
DECLARE_PCI_UNMAP_LEN(len)
};
NOTE: DO NOT put a semicolon at the end of the DECLARE_*()
macro.
2) Use pci_unmap_{addr,len}_set to set these values.
Example, before:
ringp->mapping = FOO;
ringp->len = BAR;
after:
pci_unmap_addr_set(ringp, mapping, FOO);
pci_unmap_len_set(ringp, len, BAR);
3) Use pci_unmap_{addr,len} to access these values.
Example, before:
pci_unmap_single(pdev, ringp->mapping, ringp->len,
PCI_DMA_FROMDEVICE);
after:
pci_unmap_single(pdev,
pci_unmap_addr(ringp, mapping),
pci_unmap_len(ringp, len),
PCI_DMA_FROMDEVICE);
It really should be self-explanatory. We treat the ADDR and LEN
separately, because it is possible for an implementation to only
need the address in order to perform the unmap operation.
Platform Issues
If you are just writing drivers for Linux and do not maintain
an architecture port for the kernel, you can safely skip down
to "Closing".
1) Struct scatterlist requirements.
Struct scatterlist must contain, at a minimum, the following
members:
struct page *page;
unsigned int offset;
unsigned int length;
The base address is specified by a "page+offset" pair.
Previous versions of struct scatterlist contained a "void *address"
field that was sometimes used instead of page+offset. As of Linux
2.5., page+offset is always used, and the "address" field has been
deleted.
2) More to come...
Handling Errors
DMA address space is limited on some architectures and an allocation
failure can be determined by:
- checking if pci_alloc_consistent returns NULL or pci_map_sg returns 0
- checking the returned dma_addr_t of pci_map_single and pci_map_page
by using pci_dma_mapping_error():
dma_addr_t dma_handle;
dma_handle = pci_map_single(pdev, addr, size, direction);
if (pci_dma_mapping_error(pdev, dma_handle)) {
/*
* reduce current DMA mapping usage,
* delay and try again later or
* reset driver.
*/
}
Closing
This document, and the API itself, would not be in it's current
form without the feedback and suggestions from numerous individuals.
We would like to specifically mention, in no particular order, the
following people:
Russell King <rmk@arm.linux.org.uk>
Leo Dagum <dagum@barrel.engr.sgi.com>
Ralf Baechle <ralf@oss.sgi.com>
Grant Grundler <grundler@cup.hp.com>
Jay Estabrook <Jay.Estabrook@compaq.com>
Thomas Sailer <sailer@ife.ee.ethz.ch>
Andrea Arcangeli <andrea@suse.de>
Jens Axboe <jens.axboe@oracle.com>
David Mosberger-Tang <davidm@hpl.hp.com>

View File

@@ -0,0 +1,561 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE set PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<set>
<setinfo>
<title>The 802.11 subsystems &ndash; for kernel developers</title>
<subtitle>
Explaining wireless 802.11 networking in the Linux kernel
</subtitle>
<copyright>
<year>2007-2009</year>
<holder>Johannes Berg</holder>
</copyright>
<authorgroup>
<author>
<firstname>Johannes</firstname>
<surname>Berg</surname>
<affiliation>
<address><email>johannes@sipsolutions.net</email></address>
</affiliation>
</author>
</authorgroup>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License version 2 as published by the Free Software Foundation.
</para>
<para>
This documentation is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this documentation; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
<abstract>
<para>
These books attempt to give a description of the
various subsystems that play a role in 802.11 wireless
networking in Linux. Since these books are for kernel
developers they attempts to document the structures
and functions used in the kernel as well as giving a
higher-level overview.
</para>
<para>
The reader is expected to be familiar with the 802.11
standard as published by the IEEE in 802.11-2007 (or
possibly later versions). References to this standard
will be given as "802.11-2007 8.1.5".
</para>
</abstract>
</setinfo>
<book id="cfg80211-developers-guide">
<bookinfo>
<title>The cfg80211 subsystem</title>
<abstract>
!Pinclude/net/cfg80211.h Introduction
</abstract>
</bookinfo>
<chapter>
<title>Device registration</title>
!Pinclude/net/cfg80211.h Device registration
!Finclude/net/cfg80211.h ieee80211_band
!Finclude/net/cfg80211.h ieee80211_channel_flags
!Finclude/net/cfg80211.h ieee80211_channel
!Finclude/net/cfg80211.h ieee80211_rate_flags
!Finclude/net/cfg80211.h ieee80211_rate
!Finclude/net/cfg80211.h ieee80211_sta_ht_cap
!Finclude/net/cfg80211.h ieee80211_supported_band
!Finclude/net/cfg80211.h cfg80211_signal_type
!Finclude/net/cfg80211.h wiphy_params_flags
!Finclude/net/cfg80211.h wiphy_flags
!Finclude/net/cfg80211.h wiphy
!Finclude/net/cfg80211.h wireless_dev
!Finclude/net/cfg80211.h wiphy_new
!Finclude/net/cfg80211.h wiphy_register
!Finclude/net/cfg80211.h wiphy_unregister
!Finclude/net/cfg80211.h wiphy_free
!Finclude/net/cfg80211.h wiphy_name
!Finclude/net/cfg80211.h wiphy_dev
!Finclude/net/cfg80211.h wiphy_priv
!Finclude/net/cfg80211.h priv_to_wiphy
!Finclude/net/cfg80211.h set_wiphy_dev
!Finclude/net/cfg80211.h wdev_priv
</chapter>
<chapter>
<title>Actions and configuration</title>
!Pinclude/net/cfg80211.h Actions and configuration
!Finclude/net/cfg80211.h cfg80211_ops
!Finclude/net/cfg80211.h vif_params
!Finclude/net/cfg80211.h key_params
!Finclude/net/cfg80211.h survey_info_flags
!Finclude/net/cfg80211.h survey_info
!Finclude/net/cfg80211.h beacon_parameters
!Finclude/net/cfg80211.h plink_actions
!Finclude/net/cfg80211.h station_parameters
!Finclude/net/cfg80211.h station_info_flags
!Finclude/net/cfg80211.h rate_info_flags
!Finclude/net/cfg80211.h rate_info
!Finclude/net/cfg80211.h station_info
!Finclude/net/cfg80211.h monitor_flags
!Finclude/net/cfg80211.h mpath_info_flags
!Finclude/net/cfg80211.h mpath_info
!Finclude/net/cfg80211.h bss_parameters
!Finclude/net/cfg80211.h ieee80211_txq_params
!Finclude/net/cfg80211.h cfg80211_crypto_settings
!Finclude/net/cfg80211.h cfg80211_auth_request
!Finclude/net/cfg80211.h cfg80211_assoc_request
!Finclude/net/cfg80211.h cfg80211_deauth_request
!Finclude/net/cfg80211.h cfg80211_disassoc_request
!Finclude/net/cfg80211.h cfg80211_ibss_params
!Finclude/net/cfg80211.h cfg80211_connect_params
!Finclude/net/cfg80211.h cfg80211_pmksa
!Finclude/net/cfg80211.h cfg80211_send_rx_auth
!Finclude/net/cfg80211.h cfg80211_send_auth_timeout
!Finclude/net/cfg80211.h __cfg80211_auth_canceled
!Finclude/net/cfg80211.h cfg80211_send_rx_assoc
!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
!Finclude/net/cfg80211.h cfg80211_send_deauth
!Finclude/net/cfg80211.h __cfg80211_send_deauth
!Finclude/net/cfg80211.h cfg80211_send_disassoc
!Finclude/net/cfg80211.h __cfg80211_send_disassoc
!Finclude/net/cfg80211.h cfg80211_ibss_joined
!Finclude/net/cfg80211.h cfg80211_connect_result
!Finclude/net/cfg80211.h cfg80211_roamed
!Finclude/net/cfg80211.h cfg80211_disconnected
!Finclude/net/cfg80211.h cfg80211_ready_on_channel
!Finclude/net/cfg80211.h cfg80211_remain_on_channel_expired
!Finclude/net/cfg80211.h cfg80211_new_sta
!Finclude/net/cfg80211.h cfg80211_rx_mgmt
!Finclude/net/cfg80211.h cfg80211_mgmt_tx_status
!Finclude/net/cfg80211.h cfg80211_cqm_rssi_notify
!Finclude/net/cfg80211.h cfg80211_cqm_pktloss_notify
!Finclude/net/cfg80211.h cfg80211_michael_mic_failure
</chapter>
<chapter>
<title>Scanning and BSS list handling</title>
!Pinclude/net/cfg80211.h Scanning and BSS list handling
!Finclude/net/cfg80211.h cfg80211_ssid
!Finclude/net/cfg80211.h cfg80211_scan_request
!Finclude/net/cfg80211.h cfg80211_scan_done
!Finclude/net/cfg80211.h cfg80211_bss
!Finclude/net/cfg80211.h cfg80211_inform_bss_frame
!Finclude/net/cfg80211.h cfg80211_inform_bss
!Finclude/net/cfg80211.h cfg80211_unlink_bss
!Finclude/net/cfg80211.h cfg80211_find_ie
!Finclude/net/cfg80211.h ieee80211_bss_get_ie
</chapter>
<chapter>
<title>Utility functions</title>
!Pinclude/net/cfg80211.h Utility functions
!Finclude/net/cfg80211.h ieee80211_channel_to_frequency
!Finclude/net/cfg80211.h ieee80211_frequency_to_channel
!Finclude/net/cfg80211.h ieee80211_get_channel
!Finclude/net/cfg80211.h ieee80211_get_response_rate
!Finclude/net/cfg80211.h ieee80211_hdrlen
!Finclude/net/cfg80211.h ieee80211_get_hdrlen_from_skb
!Finclude/net/cfg80211.h ieee80211_radiotap_iterator
</chapter>
<chapter>
<title>Data path helpers</title>
!Pinclude/net/cfg80211.h Data path helpers
!Finclude/net/cfg80211.h ieee80211_data_to_8023
!Finclude/net/cfg80211.h ieee80211_data_from_8023
!Finclude/net/cfg80211.h ieee80211_amsdu_to_8023s
!Finclude/net/cfg80211.h cfg80211_classify8021d
</chapter>
<chapter>
<title>Regulatory enforcement infrastructure</title>
!Pinclude/net/cfg80211.h Regulatory enforcement infrastructure
!Finclude/net/cfg80211.h regulatory_hint
!Finclude/net/cfg80211.h wiphy_apply_custom_regulatory
!Finclude/net/cfg80211.h freq_reg_info
</chapter>
<chapter>
<title>RFkill integration</title>
!Pinclude/net/cfg80211.h RFkill integration
!Finclude/net/cfg80211.h wiphy_rfkill_set_hw_state
!Finclude/net/cfg80211.h wiphy_rfkill_start_polling
!Finclude/net/cfg80211.h wiphy_rfkill_stop_polling
</chapter>
<chapter>
<title>Test mode</title>
!Pinclude/net/cfg80211.h Test mode
!Finclude/net/cfg80211.h cfg80211_testmode_alloc_reply_skb
!Finclude/net/cfg80211.h cfg80211_testmode_reply
!Finclude/net/cfg80211.h cfg80211_testmode_alloc_event_skb
!Finclude/net/cfg80211.h cfg80211_testmode_event
</chapter>
</book>
<book id="mac80211-developers-guide">
<bookinfo>
<title>The mac80211 subsystem</title>
<abstract>
!Pinclude/net/mac80211.h Introduction
!Pinclude/net/mac80211.h Warning
</abstract>
</bookinfo>
<toc></toc>
<!--
Generally, this document shall be ordered by increasing complexity.
It is important to note that readers should be able to read only
the first few sections to get a working driver and only advanced
usage should require reading the full document.
-->
<part>
<title>The basic mac80211 driver interface</title>
<partintro>
<para>
You should read and understand the information contained
within this part of the book while implementing a driver.
In some chapters, advanced usage is noted, that may be
skipped at first.
</para>
<para>
This part of the book only covers station and monitor mode
functionality, additional information required to implement
the other modes is covered in the second part of the book.
</para>
</partintro>
<chapter id="basics">
<title>Basic hardware handling</title>
<para>TBD</para>
<para>
This chapter shall contain information on getting a hw
struct allocated and registered with mac80211.
</para>
<para>
Since it is required to allocate rates/modes before registering
a hw struct, this chapter shall also contain information on setting
up the rate/mode structs.
</para>
<para>
Additionally, some discussion about the callbacks and
the general programming model should be in here, including
the definition of ieee80211_ops which will be referred to
a lot.
</para>
<para>
Finally, a discussion of hardware capabilities should be done
with references to other parts of the book.
</para>
<!-- intentionally multiple !F lines to get proper order -->
!Finclude/net/mac80211.h ieee80211_hw
!Finclude/net/mac80211.h ieee80211_hw_flags
!Finclude/net/mac80211.h SET_IEEE80211_DEV
!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR
!Finclude/net/mac80211.h ieee80211_ops
!Finclude/net/mac80211.h ieee80211_alloc_hw
!Finclude/net/mac80211.h ieee80211_register_hw
!Finclude/net/mac80211.h ieee80211_get_tx_led_name
!Finclude/net/mac80211.h ieee80211_get_rx_led_name
!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
!Finclude/net/mac80211.h ieee80211_get_radio_led_name
!Finclude/net/mac80211.h ieee80211_unregister_hw
!Finclude/net/mac80211.h ieee80211_free_hw
</chapter>
<chapter id="phy-handling">
<title>PHY configuration</title>
<para>TBD</para>
<para>
This chapter should describe PHY handling including
start/stop callbacks and the various structures used.
</para>
!Finclude/net/mac80211.h ieee80211_conf
!Finclude/net/mac80211.h ieee80211_conf_flags
</chapter>
<chapter id="iface-handling">
<title>Virtual interfaces</title>
<para>TBD</para>
<para>
This chapter should describe virtual interface basics
that are relevant to the driver (VLANs, MGMT etc are not.)
It should explain the use of the add_iface/remove_iface
callbacks as well as the interface configuration callbacks.
</para>
<para>Things related to AP mode should be discussed there.</para>
<para>
Things related to supporting multiple interfaces should be
in the appropriate chapter, a BIG FAT note should be here about
this though and the recommendation to allow only a single
interface in STA mode at first!
</para>
!Finclude/net/mac80211.h ieee80211_vif
</chapter>
<chapter id="rx-tx">
<title>Receive and transmit processing</title>
<sect1>
<title>what should be here</title>
<para>TBD</para>
<para>
This should describe the receive and transmit
paths in mac80211/the drivers as well as
transmit status handling.
</para>
</sect1>
<sect1>
<title>Frame format</title>
!Pinclude/net/mac80211.h Frame format
</sect1>
<sect1>
<title>Packet alignment</title>
!Pnet/mac80211/rx.c Packet alignment
</sect1>
<sect1>
<title>Calling into mac80211 from interrupts</title>
!Pinclude/net/mac80211.h Calling mac80211 from interrupts
</sect1>
<sect1>
<title>functions/definitions</title>
!Finclude/net/mac80211.h ieee80211_rx_status
!Finclude/net/mac80211.h mac80211_rx_flags
!Finclude/net/mac80211.h mac80211_tx_control_flags
!Finclude/net/mac80211.h mac80211_rate_control_flags
!Finclude/net/mac80211.h ieee80211_tx_rate
!Finclude/net/mac80211.h ieee80211_tx_info
!Finclude/net/mac80211.h ieee80211_tx_info_clear_status
!Finclude/net/mac80211.h ieee80211_rx
!Finclude/net/mac80211.h ieee80211_rx_ni
!Finclude/net/mac80211.h ieee80211_rx_irqsafe
!Finclude/net/mac80211.h ieee80211_tx_status
!Finclude/net/mac80211.h ieee80211_tx_status_ni
!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe
!Finclude/net/mac80211.h ieee80211_rts_get
!Finclude/net/mac80211.h ieee80211_rts_duration
!Finclude/net/mac80211.h ieee80211_ctstoself_get
!Finclude/net/mac80211.h ieee80211_ctstoself_duration
!Finclude/net/mac80211.h ieee80211_generic_frame_duration
!Finclude/net/mac80211.h ieee80211_wake_queue
!Finclude/net/mac80211.h ieee80211_stop_queue
!Finclude/net/mac80211.h ieee80211_wake_queues
!Finclude/net/mac80211.h ieee80211_stop_queues
!Finclude/net/mac80211.h ieee80211_queue_stopped
</sect1>
</chapter>
<chapter id="filters">
<title>Frame filtering</title>
!Pinclude/net/mac80211.h Frame filtering
!Finclude/net/mac80211.h ieee80211_filter_flags
</chapter>
<chapter id="workqueue">
<title>The mac80211 workqueue</title>
!Pinclude/net/mac80211.h mac80211 workqueue
!Finclude/net/mac80211.h ieee80211_queue_work
!Finclude/net/mac80211.h ieee80211_queue_delayed_work
</chapter>
</part>
<part id="advanced">
<title>Advanced driver interface</title>
<partintro>
<para>
Information contained within this part of the book is
of interest only for advanced interaction of mac80211
with drivers to exploit more hardware capabilities and
improve performance.
</para>
</partintro>
<chapter id="hardware-crypto-offload">
<title>Hardware crypto acceleration</title>
!Pinclude/net/mac80211.h Hardware crypto acceleration
<!-- intentionally multiple !F lines to get proper order -->
!Finclude/net/mac80211.h set_key_cmd
!Finclude/net/mac80211.h ieee80211_key_conf
!Finclude/net/mac80211.h ieee80211_key_flags
!Finclude/net/mac80211.h ieee80211_tkip_key_type
!Finclude/net/mac80211.h ieee80211_get_tkip_key
!Finclude/net/mac80211.h ieee80211_key_removed
</chapter>
<chapter id="powersave">
<title>Powersave support</title>
!Pinclude/net/mac80211.h Powersave support
</chapter>
<chapter id="beacon-filter">
<title>Beacon filter support</title>
!Pinclude/net/mac80211.h Beacon filter support
!Finclude/net/mac80211.h ieee80211_beacon_loss
</chapter>
<chapter id="qos">
<title>Multiple queues and QoS support</title>
<para>TBD</para>
!Finclude/net/mac80211.h ieee80211_tx_queue_params
</chapter>
<chapter id="AP">
<title>Access point mode support</title>
<para>TBD</para>
<para>Some parts of the if_conf should be discussed here instead</para>
<para>
Insert notes about VLAN interfaces with hw crypto here or
in the hw crypto chapter.
</para>
!Finclude/net/mac80211.h ieee80211_get_buffered_bc
!Finclude/net/mac80211.h ieee80211_beacon_get
</chapter>
<chapter id="multi-iface">
<title>Supporting multiple virtual interfaces</title>
<para>TBD</para>
<para>
Note: WDS with identical MAC address should almost always be OK
</para>
<para>
Insert notes about having multiple virtual interfaces with
different MAC addresses here, note which configurations are
supported by mac80211, add notes about supporting hw crypto
with it.
</para>
!Finclude/net/mac80211.h ieee80211_iterate_active_interfaces
!Finclude/net/mac80211.h ieee80211_iterate_active_interfaces_atomic
</chapter>
<chapter id="station-handling">
<title>Station handling</title>
<para>TODO</para>
!Finclude/net/mac80211.h ieee80211_sta
!Finclude/net/mac80211.h sta_notify_cmd
!Finclude/net/mac80211.h ieee80211_find_sta
!Finclude/net/mac80211.h ieee80211_find_sta_by_ifaddr
!Finclude/net/mac80211.h ieee80211_sta_block_awake
</chapter>
<chapter id="hardware-scan-offload">
<title>Hardware scan offload</title>
<para>TBD</para>
!Finclude/net/mac80211.h ieee80211_scan_completed
</chapter>
<chapter id="aggregation">
<title>Aggregation</title>
<sect1>
<title>TX A-MPDU aggregation</title>
!Pnet/mac80211/agg-tx.c TX A-MPDU aggregation
!Cnet/mac80211/agg-tx.c
</sect1>
<sect1>
<title>RX A-MPDU aggregation</title>
!Pnet/mac80211/agg-rx.c RX A-MPDU aggregation
!Cnet/mac80211/agg-rx.c
</sect1>
!Finclude/net/mac80211.h ieee80211_ampdu_mlme_action
</chapter>
<chapter id="smps">
<title>Spatial Multiplexing Powersave (SMPS)</title>
!Pinclude/net/mac80211.h Spatial multiplexing power save
!Finclude/net/mac80211.h ieee80211_request_smps
!Finclude/net/mac80211.h ieee80211_smps_mode
</chapter>
</part>
<part id="rate-control">
<title>Rate control interface</title>
<partintro>
<para>TBD</para>
<para>
This part of the book describes the rate control algorithm
interface and how it relates to mac80211 and drivers.
</para>
</partintro>
<chapter id="ratecontrol-api">
<title>Rate Control API</title>
<para>TBD</para>
!Finclude/net/mac80211.h ieee80211_start_tx_ba_session
!Finclude/net/mac80211.h ieee80211_start_tx_ba_cb_irqsafe
!Finclude/net/mac80211.h ieee80211_stop_tx_ba_session
!Finclude/net/mac80211.h ieee80211_stop_tx_ba_cb_irqsafe
!Finclude/net/mac80211.h rate_control_changed
!Finclude/net/mac80211.h ieee80211_tx_rate_control
!Finclude/net/mac80211.h rate_control_send_low
</chapter>
</part>
<part id="internal">
<title>Internals</title>
<partintro>
<para>TBD</para>
<para>
This part of the book describes mac80211 internals.
</para>
</partintro>
<chapter id="key-handling">
<title>Key handling</title>
<sect1>
<title>Key handling basics</title>
!Pnet/mac80211/key.c Key handling basics
</sect1>
<sect1>
<title>MORE TBD</title>
<para>TBD</para>
</sect1>
</chapter>
<chapter id="rx-processing">
<title>Receive processing</title>
<para>TBD</para>
</chapter>
<chapter id="tx-processing">
<title>Transmit processing</title>
<para>TBD</para>
</chapter>
<chapter id="sta-info">
<title>Station info handling</title>
<sect1>
<title>Programming information</title>
!Fnet/mac80211/sta_info.h sta_info
!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags
</sect1>
<sect1>
<title>STA information lifetime rules</title>
!Pnet/mac80211/sta_info.c STA information lifetime rules
</sect1>
</chapter>
<chapter id="aggregation-internals">
<title>Aggregation</title>
!Fnet/mac80211/sta_info.h sta_ampdu_mlme
!Fnet/mac80211/sta_info.h tid_ampdu_tx
!Fnet/mac80211/sta_info.h tid_ampdu_rx
</chapter>
<chapter id="synchronisation">
<title>Synchronisation</title>
<para>TBD</para>
<para>Locking, lots of RCU</para>
</chapter>
</part>
</book>
</set>

View File

@@ -8,13 +8,13 @@
DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
procfs-guide.xml writing_usb_driver.xml networking.xml \
writing_usb_driver.xml networking.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
mac80211.xml debugobjects.xml sh.xml regulator.xml \
80211.xml debugobjects.xml sh.xml regulator.xml \
alsa-driver-api.xml writing-an-alsa-driver.xml \
tracepoint.xml
tracepoint.xml media.xml drm.xml
###
# The build process is as follows (targets):
@@ -32,7 +32,7 @@ PS_METHOD = $(prefer-db2x)
###
# The targets that may be used.
PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs
PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs xmldoclinks
BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
xmldocs: $(BOOKS)
@@ -45,12 +45,25 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
pdfdocs: $(PDF)
HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
htmldocs: $(HTML)
htmldocs: $(HTML) xmldoclinks
$(call build_main_index)
$(call build_images)
MAN := $(patsubst %.xml, %.9, $(BOOKS))
mandocs: $(MAN)
build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/
xmldoclinks:
ifneq ($(objtree),$(srctree))
for dep in dvb media-entities.tmpl media-indices.tmpl v4l; do \
rm -f $(objtree)/Documentation/DocBook/$$dep \
&& ln -s $(srctree)/Documentation/DocBook/$$dep $(objtree)/Documentation/DocBook/ \
|| exit; \
done
endif
installmandocs: mandocs
mkdir -p /usr/local/man/man9/
install Documentation/DocBook/man/*.9.gz /usr/local/man/man9/
@@ -61,7 +74,7 @@ KERNELDOC = $(srctree)/scripts/kernel-doc
DOCPROC = $(objtree)/scripts/basic/docproc
XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
#XMLTOFLAGS += --skip-validation
XMLTOFLAGS += --skip-validation
###
# DOCPROC is used for two purposes:
@@ -82,7 +95,7 @@ define rule_docproc
) > $(dir $@).$(notdir $@).cmd
endef
%.xml: %.tmpl FORCE
%.xml: %.tmpl xmldoclinks FORCE
$(call if_changed_rule,docproc)
###
@@ -97,17 +110,6 @@ endif
# Changes in kernel-doc force a rebuild of all documentation
$(BOOKS): $(KERNELDOC)
###
# procfs guide uses a .c file as example code.
# This requires an explicit dependency
C-procfs-example = procfs_example.xml
C-procfs-example2 = $(addprefix $(obj)/,$(C-procfs-example))
$(obj)/procfs-guide.xml: $(C-procfs-example2)
# List of programs to build
##oops, this is a kernel module::hostprogs-y := procfs_example
obj-m += procfs_example.o
# Tell kbuild to always build the programs
always := $(hostprogs-y)
@@ -234,7 +236,7 @@ clean-files := $(DOCBOOKS) \
$(patsubst %.xml, %.pdf, $(DOCBOOKS)) \
$(patsubst %.xml, %.html, $(DOCBOOKS)) \
$(patsubst %.xml, %.9, $(DOCBOOKS)) \
$(C-procfs-example) $(index)
$(index)
clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man

View File

@@ -45,14 +45,18 @@
</sect1>
<sect1><title>Atomic and pointer manipulation</title>
!Iarch/x86/include/asm/atomic_32.h
!Iarch/x86/include/asm/unaligned.h
!Iarch/x86/include/asm/atomic.h
</sect1>
<sect1><title>Delaying, scheduling, and timer routines</title>
!Iinclude/linux/sched.h
!Ekernel/sched.c
!Iinclude/linux/completion.h
!Ekernel/timer.c
</sect1>
<sect1><title>Wait queues and Wake events</title>
!Iinclude/linux/wait.h
!Ekernel/wait.c
</sect1>
<sect1><title>High-resolution timers</title>
!Iinclude/linux/ktime.h
@@ -111,6 +115,7 @@ X!Edrivers/base/attribute_container.c
<!--
X!Edrivers/base/interface.c
-->
!Iinclude/linux/platform_device.h
!Edrivers/base/platform.c
!Edrivers/base/bus.c
</sect1>
@@ -293,10 +298,27 @@ X!Idrivers/video/console/fonts.c
<chapter id="input_subsystem">
<title>Input Subsystem</title>
<sect1><title>Input core</title>
!Iinclude/linux/input.h
!Edrivers/input/input.c
!Edrivers/input/ff-core.c
!Edrivers/input/ff-memless.c
</sect1>
<sect1><title>Multitouch Library</title>
!Iinclude/linux/input/mt.h
!Edrivers/input/input-mt.c
</sect1>
<sect1><title>Polled input devices</title>
!Iinclude/linux/input-polldev.h
!Edrivers/input/input-polldev.c
</sect1>
<sect1><title>Matrix keyboars/keypads</title>
!Iinclude/linux/input/matrix_keypad.h
</sect1>
<sect1><title>Sparse keymap support</title>
!Iinclude/linux/input/sparse-keymap.h
!Edrivers/input/sparse-keymap.c
</sect1>
</chapter>
<chapter id="spi">

View File

@@ -316,7 +316,7 @@ CPU B: spin_unlock_irqrestore(&amp;dev_lock, flags)
<chapter id="pubfunctions">
<title>Public Functions Provided</title>
!Iarch/x86/include/asm/io_32.h
!Iarch/x86/include/asm/io.h
!Elib/iomap.c
</chapter>

View File

@@ -0,0 +1,840 @@
<?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 &lt;jesse.barnes@intel.com&gt;)
</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 &amp; 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 = &amp;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
.llseek = noop_llseek,
},
.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 &amp;
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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 initialize
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 desirable. 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 initialization 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(&amp;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 registered 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 to 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
returning 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 &amp; 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&lt;-&gt;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 &amp;
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 &amp; 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 &amp; 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>

1
Documentation/DocBook/dvb/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
!*.xml

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,221 @@
<title>DVB CA Device</title>
<para>The DVB CA device controls the conditional access hardware. It can be accessed through
<emphasis role="tt">/dev/dvb/adapter0/ca0</emphasis>. Data types and and ioctl definitions can be accessed by
including <emphasis role="tt">linux/dvb/ca.h</emphasis> in your application.
</para>
<section id="ca_data_types">
<title>CA Data Types</title>
<section id="ca_slot_info_t">
<title>ca_slot_info_t</title>
<programlisting>
/&#x22C6; slot interface types and info &#x22C6;/
typedef struct ca_slot_info_s {
int num; /&#x22C6; slot number &#x22C6;/
int type; /&#x22C6; CA interface this slot supports &#x22C6;/
#define CA_CI 1 /&#x22C6; CI high level interface &#x22C6;/
#define CA_CI_LINK 2 /&#x22C6; CI link layer level interface &#x22C6;/
#define CA_CI_PHYS 4 /&#x22C6; CI physical layer level interface &#x22C6;/
#define CA_SC 128 /&#x22C6; simple smart card interface &#x22C6;/
unsigned int flags;
#define CA_CI_MODULE_PRESENT 1 /&#x22C6; module (or card) inserted &#x22C6;/
#define CA_CI_MODULE_READY 2
} ca_slot_info_t;
</programlisting>
</section>
<section id="ca_descr_info_t">
<title>ca_descr_info_t</title>
<programlisting>
typedef struct ca_descr_info_s {
unsigned int num; /&#x22C6; number of available descramblers (keys) &#x22C6;/
unsigned int type; /&#x22C6; type of supported scrambling system &#x22C6;/
#define CA_ECD 1
#define CA_NDS 2
#define CA_DSS 4
} ca_descr_info_t;
</programlisting>
</section>
<section id="ca_cap_t">
<title>ca_cap_t</title>
<programlisting>
typedef struct ca_cap_s {
unsigned int slot_num; /&#x22C6; total number of CA card and module slots &#x22C6;/
unsigned int slot_type; /&#x22C6; OR of all supported types &#x22C6;/
unsigned int descr_num; /&#x22C6; total number of descrambler slots (keys) &#x22C6;/
unsigned int descr_type;/&#x22C6; OR of all supported types &#x22C6;/
} ca_cap_t;
</programlisting>
</section>
<section id="ca_msg_t">
<title>ca_msg_t</title>
<programlisting>
/&#x22C6; a message to/from a CI-CAM &#x22C6;/
typedef struct ca_msg_s {
unsigned int index;
unsigned int type;
unsigned int length;
unsigned char msg[256];
} ca_msg_t;
</programlisting>
</section>
<section id="ca_descr_t">
<title>ca_descr_t</title>
<programlisting>
typedef struct ca_descr_s {
unsigned int index;
unsigned int parity;
unsigned char cw[8];
} ca_descr_t;
</programlisting>
</section></section>
<section id="ca_function_calls">
<title>CA Function Calls</title>
<section id="ca_fopen">
<title>open()</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This system call opens a named ca device (e.g. /dev/ost/ca) for subsequent use.</para>
<para>When an open() call has succeeded, the device will be ready for use.
The significance of blocking or non-blocking mode is described in the
documentation for functions where there is a difference. It does not affect the
semantics of the open() call itself. A device opened in blocking mode can later
be put into non-blocking mode (and vice versa) using the F_SETFL command
of the fcntl system call. This is a standard system call, documented in the Linux
manual page for fcntl. Only one user can open the CA Device in O_RDWR
mode. All other attempts to open the device in this mode will fail, and an error
code will be returned.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int open(const char &#x22C6;deviceName, int flags);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>const char
*deviceName</para>
</entry><entry
align="char">
<para>Name of specific video device.</para>
</entry>
</row><row><entry
align="char">
<para>int flags</para>
</entry><entry
align="char">
<para>A bit-wise OR of the following flags:</para>
</entry>
</row><row><entry
align="char">
</entry><entry
align="char">
<para>O_RDONLY read-only access</para>
</entry>
</row><row><entry
align="char">
</entry><entry
align="char">
<para>O_RDWR read/write access</para>
</entry>
</row><row><entry
align="char">
</entry><entry
align="char">
<para>O_NONBLOCK open in non-blocking mode</para>
</entry>
</row><row><entry
align="char">
</entry><entry
align="char">
<para>(blocking mode is the default)</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>ENODEV</para>
</entry><entry
align="char">
<para>Device driver not loaded/available.</para>
</entry>
</row><row><entry
align="char">
<para>EINTERNAL</para>
</entry><entry
align="char">
<para>Internal error.</para>
</entry>
</row><row><entry
align="char">
<para>EBUSY</para>
</entry><entry
align="char">
<para>Device or resource busy.</para>
</entry>
</row><row><entry
align="char">
<para>EINVAL</para>
</entry><entry
align="char">
<para>Invalid argument.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="ca_fclose">
<title>close()</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This system call closes a previously opened audio device.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int close(int fd);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid open file descriptor.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
</section>

View File

@@ -0,0 +1,973 @@
<title>DVB Demux Device</title>
<para>The DVB demux device controls the filters of the DVB hardware/software. It can be
accessed through <emphasis role="tt">/dev/adapter0/demux0</emphasis>. Data types and and ioctl definitions can be
accessed by including <emphasis role="tt">linux/dvb/dmx.h</emphasis> in your application.
</para>
<section id="dmx_types">
<title>Demux Data Types</title>
<section id="dmx_output_t">
<title>dmx_output_t</title>
<programlisting>
typedef enum
{
DMX_OUT_DECODER,
DMX_OUT_TAP,
DMX_OUT_TS_TAP
} dmx_output_t;
</programlisting>
<para><emphasis role="tt">DMX_OUT_TAP</emphasis> delivers the stream output to the demux device on which the ioctl is
called.
</para>
<para><emphasis role="tt">DMX_OUT_TS_TAP</emphasis> routes output to the logical DVR device <emphasis role="tt">/dev/dvb/adapter0/dvr0</emphasis>,
which delivers a TS multiplexed from all filters for which <emphasis role="tt">DMX_OUT_TS_TAP</emphasis> was
specified.
</para>
</section>
<section id="dmx_input_t">
<title>dmx_input_t</title>
<programlisting>
typedef enum
{
DMX_IN_FRONTEND,
DMX_IN_DVR
} dmx_input_t;
</programlisting>
</section>
<section id="dmx_pes_type_t">
<title>dmx_pes_type_t</title>
<programlisting>
typedef enum
{
DMX_PES_AUDIO,
DMX_PES_VIDEO,
DMX_PES_TELETEXT,
DMX_PES_SUBTITLE,
DMX_PES_PCR,
DMX_PES_OTHER
} dmx_pes_type_t;
</programlisting>
</section>
<section id="dmx_event_t">
<title>dmx_event_t</title>
<programlisting>
typedef enum
{
DMX_SCRAMBLING_EV,
DMX_FRONTEND_EV
} dmx_event_t;
</programlisting>
</section>
<section id="dmx_scrambling_status_t">
<title>dmx_scrambling_status_t</title>
<programlisting>
typedef enum
{
DMX_SCRAMBLING_OFF,
DMX_SCRAMBLING_ON
} dmx_scrambling_status_t;
</programlisting>
</section>
<section id="dmx_filter">
<title>struct dmx_filter</title>
<programlisting>
typedef struct dmx_filter
{
uint8_t filter[DMX_FILTER_SIZE];
uint8_t mask[DMX_FILTER_SIZE];
} dmx_filter_t;
</programlisting>
</section>
<section id="dmx_sct_filter_params">
<title>struct dmx_sct_filter_params</title>
<programlisting>
struct dmx_sct_filter_params
{
uint16_t pid;
dmx_filter_t filter;
uint32_t timeout;
uint32_t flags;
#define DMX_CHECK_CRC 1
#define DMX_ONESHOT 2
#define DMX_IMMEDIATE_START 4
};
</programlisting>
</section>
<section id="dmx_pes_filter_params">
<title>struct dmx_pes_filter_params</title>
<programlisting>
struct dmx_pes_filter_params
{
uint16_t pid;
dmx_input_t input;
dmx_output_t output;
dmx_pes_type_t pes_type;
uint32_t flags;
};
</programlisting>
</section>
<section id="dmx_event">
<title>struct dmx_event</title>
<programlisting>
struct dmx_event
{
dmx_event_t event;
time_t timeStamp;
union
{
dmx_scrambling_status_t scrambling;
} u;
};
</programlisting>
</section>
<section id="dmx_stc">
<title>struct dmx_stc</title>
<programlisting>
struct dmx_stc {
unsigned int num; /&#x22C6; input : which STC? 0..N &#x22C6;/
unsigned int base; /&#x22C6; output: divisor for stc to get 90 kHz clock &#x22C6;/
uint64_t stc; /&#x22C6; output: stc in 'base'&#x22C6;90 kHz units &#x22C6;/
};
</programlisting>
</section>
</section>
<section id="dmx_fcalls">
<title>Demux Function Calls</title>
<section id="dmx_fopen">
<title>open()</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This system call, used with a device name of /dev/dvb/adapter0/demux0,
allocates a new filter and returns a handle which can be used for subsequent
control of that filter. This call has to be made for each filter to be used, i.e. every
returned file descriptor is a reference to a single filter. /dev/dvb/adapter0/dvr0
is a logical device to be used for retrieving Transport Streams for digital
video recording. When reading from this device a transport stream containing
the packets from all PES filters set in the corresponding demux device
(/dev/dvb/adapter0/demux0) having the output set to DMX_OUT_TS_TAP. A
recorded Transport Stream is replayed by writing to this device. </para>
<para>The significance of blocking or non-blocking mode is described in the
documentation for functions where there is a difference. It does not affect the
semantics of the open() call itself. A device opened in blocking mode can later
be put into non-blocking mode (and vice versa) using the F_SETFL command
of the fcntl system call.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int open(const char &#x22C6;deviceName, int flags);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>const char
*deviceName</para>
</entry><entry
align="char">
<para>Name of demux device.</para>
</entry>
</row><row><entry
align="char">
<para>int flags</para>
</entry><entry
align="char">
<para>A bit-wise OR of the following flags:</para>
</entry>
</row><row><entry
align="char">
</entry><entry
align="char">
<para>O_RDWR read/write access</para>
</entry>
</row><row><entry
align="char">
</entry><entry
align="char">
<para>O_NONBLOCK open in non-blocking mode</para>
</entry>
</row><row><entry
align="char">
</entry><entry
align="char">
<para>(blocking mode is the default)</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>ENODEV</para>
</entry><entry
align="char">
<para>Device driver not loaded/available.</para>
</entry>
</row><row><entry
align="char">
<para>EINVAL</para>
</entry><entry
align="char">
<para>Invalid argument.</para>
</entry>
</row><row><entry
align="char">
<para>EMFILE</para>
</entry><entry
align="char">
<para>&#8220;Too many open files&#8221;, i.e. no more filters available.</para>
</entry>
</row><row><entry
align="char">
<para>ENOMEM</para>
</entry><entry
align="char">
<para>The driver failed to allocate enough memory.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_fclose">
<title>close()</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This system call deactivates and deallocates a filter that was previously
allocated via the open() call.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int close(int fd);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid open file descriptor.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_fread">
<title>read()</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This system call returns filtered data, which might be section or PES data. The
filtered data is transferred from the driver&#8217;s internal circular buffer to buf. The
maximum amount of data to be transferred is implied by count.</para>
</entry>
</row><row><entry
align="char">
<para>When returning section data the driver always tries to return a complete single
section (even though buf would provide buffer space for more data). If the size
of the buffer is smaller than the section as much as possible will be returned,
and the remaining data will be provided in subsequent calls.</para>
</entry>
</row><row><entry
align="char">
<para>The size of the internal buffer is 2 * 4096 bytes (the size of two maximum
sized sections) by default. The size of this buffer may be changed by using the
DMX_SET_BUFFER_SIZE function. If the buffer is not large enough, or if
the read operations are not performed fast enough, this may result in a buffer
overflow error. In this case EOVERFLOW will be returned, and the circular
buffer will be emptied. This call is blocking if there is no data to return, i.e. the
process will be put to sleep waiting for data, unless the O_NONBLOCK flag
is specified.</para>
</entry>
</row><row><entry
align="char">
<para>Note that in order to be able to read, the filtering process has to be started
by defining either a section or a PES filter by means of the ioctl functions,
and then starting the filtering process via the DMX_START ioctl function
or by setting the DMX_IMMEDIATE_START flag. If the reading is done
from a logical DVR demux device, the data will constitute a Transport Stream
including the packets from all PES filters in the corresponding demux device
/dev/dvb/adapter0/demux0 having the output set to DMX_OUT_TS_TAP.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>size_t read(int fd, void &#x22C6;buf, size_t count);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>void *buf</para>
</entry><entry
align="char">
<para>Pointer to the buffer to be used for returned filtered data.</para>
</entry>
</row><row><entry
align="char">
<para>size_t count</para>
</entry><entry
align="char">
<para>Size of buf.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EWOULDBLOCK</para>
</entry><entry
align="char">
<para>No data to return and O_NONBLOCK was specified.</para>
</entry>
</row><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid open file descriptor.</para>
</entry>
</row><row><entry
align="char">
<para>ECRC</para>
</entry><entry
align="char">
<para>Last section had a CRC error - no data returned. The
buffer is flushed.</para>
</entry>
</row><row><entry
align="char">
<para>EOVERFLOW</para>
</entry><entry
align="char">
</entry>
</row><row><entry
align="char">
</entry><entry
align="char">
<para>The filtered data was not read from the buffer in due
time, resulting in non-read data being lost. The buffer is
flushed.</para>
</entry>
</row><row><entry
align="char">
<para>ETIMEDOUT</para>
</entry><entry
align="char">
<para>The section was not loaded within the stated timeout
period. See ioctl DMX_SET_FILTER for how to set a
timeout.</para>
</entry>
</row><row><entry
align="char">
<para>EFAULT</para>
</entry><entry
align="char">
<para>The driver failed to write to the callers buffer due to an
invalid *buf pointer.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_fwrite">
<title>write()</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This system call is only provided by the logical device /dev/dvb/adapter0/dvr0,
associated with the physical demux device that provides the actual DVR
functionality. It is used for replay of a digitally recorded Transport Stream.
Matching filters have to be defined in the corresponding physical demux
device, /dev/dvb/adapter0/demux0. The amount of data to be transferred is
implied by count.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>ssize_t write(int fd, const void &#x22C6;buf, size_t
count);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>void *buf</para>
</entry><entry
align="char">
<para>Pointer to the buffer containing the Transport Stream.</para>
</entry>
</row><row><entry
align="char">
<para>size_t count</para>
</entry><entry
align="char">
<para>Size of buf.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EWOULDBLOCK</para>
</entry><entry
align="char">
<para>No data was written. This
might happen if O_NONBLOCK was specified and there
is no more buffer space available (if O_NONBLOCK is
not specified the function will block until buffer space is
available).</para>
</entry>
</row><row><entry
align="char">
<para>EBUSY</para>
</entry><entry
align="char">
<para>This error code indicates that there are conflicting
requests. The corresponding demux device is setup to
receive data from the front- end. Make sure that these
filters are stopped and that the filters with input set to
DMX_IN_DVR are started.</para>
</entry>
</row><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid open file descriptor.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_start">
<title>DMX_START</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call is used to start the actual filtering operation defined via the ioctl
calls DMX_SET_FILTER or DMX_SET_PES_FILTER.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int ioctl( int fd, int request = DMX_START);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>int request</para>
</entry><entry
align="char">
<para>Equals DMX_START for this command.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid file descriptor.</para>
</entry>
</row><row><entry
align="char">
<para>EINVAL</para>
</entry><entry
align="char">
<para>Invalid argument, i.e. no filtering parameters provided via
the DMX_SET_FILTER or DMX_SET_PES_FILTER
functions.</para>
</entry>
</row><row><entry
align="char">
<para>EBUSY</para>
</entry><entry
align="char">
<para>This error code indicates that there are conflicting
requests. There are active filters filtering data from
another input source. Make sure that these filters are
stopped before starting this filter.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_stop">
<title>DMX_STOP</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call is used to stop the actual filtering operation defined via the
ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and started via
the DMX_START command.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int ioctl( int fd, int request = DMX_STOP);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>int request</para>
</entry><entry
align="char">
<para>Equals DMX_STOP for this command.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid file descriptor.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_set_filter">
<title>DMX_SET_FILTER</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call sets up a filter according to the filter and mask parameters
provided. A timeout may be defined stating number of seconds to wait for a
section to be loaded. A value of 0 means that no timeout should be applied.
Finally there is a flag field where it is possible to state whether a section should
be CRC-checked, whether the filter should be a &#8221;one-shot&#8221; filter, i.e. if the
filtering operation should be stopped after the first section is received, and
whether the filtering operation should be started immediately (without waiting
for a DMX_START ioctl call). If a filter was previously set-up, this filter will
be canceled, and the receive buffer will be flushed.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int ioctl( int fd, int request = DMX_SET_FILTER,
struct dmx_sct_filter_params &#x22C6;params);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>int request</para>
</entry><entry
align="char">
<para>Equals DMX_SET_FILTER for this command.</para>
</entry>
</row><row><entry
align="char">
<para>struct
dmx_sct_filter_params
*params</para>
</entry><entry
align="char">
<para>Pointer to structure containing filter parameters.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid file descriptor.</para>
</entry>
</row><row><entry
align="char">
<para>EINVAL</para>
</entry><entry
align="char">
<para>Invalid argument.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_set_pes_filter">
<title>DMX_SET_PES_FILTER</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call sets up a PES filter according to the parameters provided. By a
PES filter is meant a filter that is based just on the packet identifier (PID), i.e.
no PES header or payload filtering capability is supported.</para>
</entry>
</row><row><entry
align="char">
<para>The transport stream destination for the filtered output may be set. Also the
PES type may be stated in order to be able to e.g. direct a video stream directly
to the video decoder. Finally there is a flag field where it is possible to state
whether the filtering operation should be started immediately (without waiting
for a DMX_START ioctl call). If a filter was previously set-up, this filter will
be cancelled, and the receive buffer will be flushed.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int ioctl( int fd, int request = DMX_SET_PES_FILTER,
struct dmx_pes_filter_params &#x22C6;params);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>int request</para>
</entry><entry
align="char">
<para>Equals DMX_SET_PES_FILTER for this command.</para>
</entry>
</row><row><entry
align="char">
<para>struct
dmx_pes_filter_params
*params</para>
</entry><entry
align="char">
<para>Pointer to structure containing filter parameters.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid file descriptor.</para>
</entry>
</row><row><entry
align="char">
<para>EINVAL</para>
</entry><entry
align="char">
<para>Invalid argument.</para>
</entry>
</row><row><entry
align="char">
<para>EBUSY</para>
</entry><entry
align="char">
<para>This error code indicates that there are conflicting
requests. There are active filters filtering data from
another input source. Make sure that these filters are
stopped before starting this filter.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dms_set_buffer_size">
<title>DMX_SET_BUFFER_SIZE</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call is used to set the size of the circular buffer used for filtered data.
The default size is two maximum sized sections, i.e. if this function is not called
a buffer size of 2 * 4096 bytes will be used.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int ioctl( int fd, int request =
DMX_SET_BUFFER_SIZE, unsigned long size);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>int request</para>
</entry><entry
align="char">
<para>Equals DMX_SET_BUFFER_SIZE for this command.</para>
</entry>
</row><row><entry
align="char">
<para>unsigned long size</para>
</entry><entry
align="char">
<para>Size of circular buffer.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid file descriptor.</para>
</entry>
</row><row><entry
align="char">
<para>ENOMEM</para>
</entry><entry
align="char">
<para>The driver was not able to allocate a buffer of the
requested size.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_get_event">
<title>DMX_GET_EVENT</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call returns an event if available. If an event is not available,
the behavior depends on whether the device is in blocking or non-blocking
mode. In the latter case, the call fails immediately with errno set to
EWOULDBLOCK. In the former case, the call blocks until an event becomes
available.</para>
</entry>
</row><row><entry
align="char">
<para>The standard Linux poll() and/or select() system calls can be used with the
device file descriptor to watch for new events. For select(), the file descriptor
should be included in the exceptfds argument, and for poll(), POLLPRI should
be specified as the wake-up condition. Only the latest event for each filter is
saved.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int ioctl( int fd, int request = DMX_GET_EVENT,
struct dmx_event &#x22C6;ev);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>int request</para>
</entry><entry
align="char">
<para>Equals DMX_GET_EVENT for this command.</para>
</entry>
</row><row><entry
align="char">
<para>struct dmx_event *ev</para>
</entry><entry
align="char">
<para>Pointer to the location where the event is to be stored.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid file descriptor.</para>
</entry>
</row><row><entry
align="char">
<para>EFAULT</para>
</entry><entry
align="char">
<para>ev points to an invalid address.</para>
</entry>
</row><row><entry
align="char">
<para>EWOULDBLOCK</para>
</entry><entry
align="char">
<para>There is no event pending, and the device is in
non-blocking mode.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section>
<section id="dmx_get_stc">
<title>DMX_GET_STC</title>
<para>DESCRIPTION
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call returns the current value of the system time counter (which is driven
by a PES filter of type DMX_PES_PCR). Some hardware supports more than one
STC, so you must specify which one by setting the num field of stc before the ioctl
(range 0...n). The result is returned in form of a ratio with a 64 bit numerator
and a 32 bit denominator, so the real 90kHz STC value is stc-&#x003E;stc /
stc-&#x003E;base
.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>SYNOPSIS
</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>int ioctl( int fd, int request = DMX_GET_STC, struct
dmx_stc &#x22C6;stc);</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>PARAMETERS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>int fd</para>
</entry><entry
align="char">
<para>File descriptor returned by a previous call to open().</para>
</entry>
</row><row><entry
align="char">
<para>int request</para>
</entry><entry
align="char">
<para>Equals DMX_GET_STC for this command.</para>
</entry>
</row><row><entry
align="char">
<para>struct dmx_stc *stc</para>
</entry><entry
align="char">
<para>Pointer to the location where the stc is to be stored.</para>
</entry>
</row></tbody></tgroup></informaltable>
<para>ERRORS
</para>
<informaltable><tgroup cols="2"><tbody><row><entry
align="char">
<para>EBADF</para>
</entry><entry
align="char">
<para>fd is not a valid file descriptor.</para>
</entry>
</row><row><entry
align="char">
<para>EFAULT</para>
</entry><entry
align="char">
<para>stc points to an invalid address.</para>
</entry>
</row><row><entry
align="char">
<para>EINVAL</para>
</entry><entry
align="char">
<para>Invalid stc number.</para>
</entry>
</row></tbody></tgroup></informaltable>
</section></section>

View File

@@ -0,0 +1,113 @@
<partinfo>
<authorgroup>
<author>
<firstname>Ralph</firstname>
<surname>Metzler</surname>
<othername role="mi">J. K.</othername>
<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
</author>
<author>
<firstname>Marcus</firstname>
<surname>Metzler</surname>
<othername role="mi">O. C.</othername>
<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
</author>
</authorgroup>
<authorgroup>
<author>
<firstname>Mauro</firstname>
<othername role="mi">Carvalho</othername>
<surname>Chehab</surname>
<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
<contrib>Ported document to Docbook XML.</contrib>
</author>
</authorgroup>
<copyright>
<year>2002</year>
<year>2003</year>
<holder>Convergence GmbH</holder>
</copyright>
<copyright>
<year>2009-2010</year>
<holder>Mauro Carvalho Chehab</holder>
</copyright>
<revhistory>
<!-- Put document revisions here, newest first. -->
<revision>
<revnumber>2.0.3</revnumber>
<date>2010-07-03</date>
<authorinitials>mcc</authorinitials>
<revremark>
Add some frontend capabilities flags, present on kernel, but missing at the specs.
</revremark>
</revision>
<revision>
<revnumber>2.0.2</revnumber>
<date>2009-10-25</date>
<authorinitials>mcc</authorinitials>
<revremark>
documents FE_SET_FRONTEND_TUNE_MODE and FE_DISHETWORK_SEND_LEGACY_CMD ioctls.
</revremark>
</revision>
<revision>
<revnumber>2.0.1</revnumber>
<date>2009-09-16</date>
<authorinitials>mcc</authorinitials>
<revremark>
Added ISDB-T test originally written by Patrick Boettcher
</revremark>
</revision>
<revision>
<revnumber>2.0.0</revnumber>
<date>2009-09-06</date>
<authorinitials>mcc</authorinitials>
<revremark>Conversion from LaTex to DocBook XML. The
contents is the same as the original LaTex version.</revremark>
</revision>
<revision>
<revnumber>1.0.0</revnumber>
<date>2003-07-24</date>
<authorinitials>rjkm</authorinitials>
<revremark>Initial revision on LaTEX.</revremark>
</revision>
</revhistory>
</partinfo>
<title>LINUX DVB API</title>
<subtitle>Version 5.2</subtitle>
<!-- ADD THE CHAPTERS HERE -->
<chapter id="dvb_introdution">
&sub-intro;
</chapter>
<chapter id="dvb_frontend">
&sub-frontend;
</chapter>
<chapter id="dvb_demux">
&sub-demux;
</chapter>
<chapter id="dvb_video">
&sub-video;
</chapter>
<chapter id="dvb_audio">
&sub-audio;
</chapter>
<chapter id="dvb_ca">
&sub-ca;
</chapter>
<chapter id="dvb_net">
&sub-net;
</chapter>
<chapter id="dvb_kdapi">
&sub-kdapi;
</chapter>
<chapter id="dvb_examples">
&sub-examples;
</chapter>
<!-- END OF CHAPTERS -->
<appendix id="frontend_h">
<title>DVB Frontend Header File</title>
&sub-frontend-h;
</appendix>

View File

@@ -0,0 +1,318 @@
<section id="FE_GET_PROPERTY">
<title>FE_GET_PROPERTY/FE_SET_PROPERTY</title>
<section id="isdbt">
<title>ISDB-T frontend</title>
<para>This section describes shortly what are the possible parameters in the Linux
DVB-API called "S2API" and now DVB API 5 in order to tune an ISDB-T/ISDB-Tsb
demodulator:</para>
<para>This ISDB-T/ISDB-Tsb API extension should reflect all information
needed to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible
that some very sophisticated devices won't need certain parameters to
tune.</para>
<para>The information given here should help application writers to know how
to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API.</para>
<para>The details given here about ISDB-T and ISDB-Tsb are just enough to
basically show the dependencies between the needed parameter values,
but surely some information is left out. For more detailed information
see the following documents:</para>
<para>ARIB STD-B31 - "Transmission System for Digital Terrestrial
Television Broadcasting" and</para>
<para>ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial
Television Broadcasting".</para>
<para>In order to read this document one has to have some knowledge the
channel structure in ISDB-T and ISDB-Tsb. I.e. it has to be known to
the reader that an ISDB-T channel consists of 13 segments, that it can
have up to 3 layer sharing those segments, and things like that.</para>
<para>Parameters used by ISDB-T and ISDB-Tsb.</para>
<section id="isdbt-parms">
<title>Parameters that are common with DVB-T and ATSC</title>
<section id="isdbt-freq">
<title><constant>DTV_FREQUENCY</constant></title>
<para>Central frequency of the channel.</para>
<para>For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a
valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
the channel which is 6MHz.</para>
<para>As in ISDB-Tsb the channel consists of only one or three segments the
frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
central frequency of the channel is expected.</para>
</section>
<section id="isdbt-bw">
<title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
<para>Possible values:</para>
<para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
<para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
<para>Note: Hardware specific values might be given here, but standard
applications should not bother to set a value to this field as
standard demods are ignoring it anyway.</para>
<para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
DTV_ISDBT_SB_SEGMENT_COUNT).</para>
</section>
<section id="isdbt-delivery-sys">
<title><constant>DTV_DELIVERY_SYSTEM</constant></title>
<para>Possible values: <constant>SYS_ISDBT</constant></para>
</section>
<section id="isdbt-tx-mode">
<title><constant>DTV_TRANSMISSION_MODE</constant></title>
<para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
<para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
<constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
<para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
hardware will try to find the correct FFT-size (if capable) and will
use TMCC to fill in the missing parameters.</para>
<para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
</section>
<section id="isdbt-guard-interval">
<title><constant>DTV_GUARD_INTERVAL</constant></title>
<para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
<constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
<para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
try to find the correct guard interval (if capable) and will use TMCC to fill
in the missing parameters.</para>
</section>
</section>
<section id="isdbt-new-parms">
<title>ISDB-T only parameters</title>
<section id="isdbt-part-rec">
<title><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></title>
<para><constant>If DTV_ISDBT_SOUND_BROADCASTING</constant> is '0' this bit-field represents whether
the channel is in partial reception mode or not.</para>
<para>If '1' <constant>DTV_ISDBT_LAYERA_*</constant> values are assigned to the center segment and
<constant>DTV_ISDBT_LAYERA_SEGMENT_COUNT</constant> has to be '1'.</para>
<para>If in addition <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'
<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> represents whether this ISDB-Tsb channel
is consisting of one segment and layer or three segments and two layers.</para>
<para>Possible values: 0, 1, -1 (AUTO)</para>
</section>
<section id="isdbt-sound-bcast">
<title><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></title>
<para>This field represents whether the other DTV_ISDBT_*-parameters are
referring to an ISDB-T and an ISDB-Tsb channel. (See also
<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>).</para>
<para>Possible values: 0, 1, -1 (AUTO)</para>
</section>
<section id="isdbt-sb-ch-id">
<title><constant>DTV_ISDBT_SB_SUBCHANNEL_ID</constant></title>
<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
<para>(Note of the author: This might not be the correct description of the
<constant>SUBCHANNEL-ID</constant> in all details, but it is my understanding of the technical
background needed to program a device)</para>
<para>An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
set of connected ISDB-Tsb channels. In this set of channels every
channel can be received independently. The number of connected
ISDB-Tsb segment can vary, e.g. depending on the frequency spectrum
bandwidth available.</para>
<para>Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
broadcaster has several possibilities to put those channels in the
air: Assuming a normal 13-segment ISDB-T spectrum he can align the 8
segments from position 1-8 to 5-13 or anything in between.</para>
<para>The underlying layer of segments are subchannels: each segment is
consisting of several subchannels with a predefined IDs. A sub-channel
is used to help the demodulator to synchronize on the channel.</para>
<para>An ISDB-T channel is always centered over all sub-channels. As for
the example above, in ISDB-Tsb it is no longer as simple as that.</para>
<para><constant>The DTV_ISDBT_SB_SUBCHANNEL_ID</constant> parameter is used to give the
sub-channel ID of the segment to be demodulated.</para>
<para>Possible values: 0 .. 41, -1 (AUTO)</para>
</section>
<section id="isdbt-sb-seg-idx">
<title><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant></title>
<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
<para><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant> gives the index of the segment to be
demodulated for an ISDB-Tsb channel where several of them are
transmitted in the connected manner.</para>
<para>Possible values: 0 .. <constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> - 1</para>
<para>Note: This value cannot be determined by an automatic channel search.</para>
</section>
<section id="isdbt-sb-seg-cnt">
<title><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant></title>
<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
<para><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> gives the total count of connected ISDB-Tsb
channels.</para>
<para>Possible values: 1 .. 13</para>
<para>Note: This value cannot be determined by an automatic channel search.</para>
</section>
<section id="isdb-hierq-layers">
<title>Hierarchical layers</title>
<para>ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
ISDB-T hierarchical layers can be decoded simultaneously. For that
reason a ISDB-T demodulator has 3 viterbi and 3 reed-solomon-decoders.</para>
<para>ISDB-T has 3 hierarchical layers which each can use a part of the
available segments. The total number of segments over all layers has
to 13 in ISDB-T.</para>
<section id="isdbt-layer-ena">
<title><constant>DTV_ISDBT_LAYER_ENABLED</constant></title>
<para>Hierarchical reception in ISDB-T is achieved by enabling or disabling
layers in the decoding process. Setting all bits of
<constant>DTV_ISDBT_LAYER_ENABLED</constant> to '1' forces all layers (if applicable) to be
demodulated. This is the default.</para>
<para>If the channel is in the partial reception mode
(<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> = 1) the central segment can be decoded
independently of the other 12 segments. In that mode layer A has to
have a <constant>SEGMENT_COUNT</constant> of 1.</para>
<para>In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb
according to <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>. <constant>SEGMENT_COUNT</constant> must be filled
accordingly.</para>
<para>Possible values: 0x1, 0x2, 0x4 (|-able)</para>
<para><constant>DTV_ISDBT_LAYER_ENABLED[0:0]</constant> - layer A</para>
<para><constant>DTV_ISDBT_LAYER_ENABLED[1:1]</constant> - layer B</para>
<para><constant>DTV_ISDBT_LAYER_ENABLED[2:2]</constant> - layer C</para>
<para><constant>DTV_ISDBT_LAYER_ENABLED[31:3]</constant> unused</para>
</section>
<section id="isdbt-layer-fec">
<title><constant>DTV_ISDBT_LAYER*_FEC</constant></title>
<para>Possible values: <constant>FEC_AUTO</constant>, <constant>FEC_1_2</constant>, <constant>FEC_2_3</constant>, <constant>FEC_3_4</constant>, <constant>FEC_5_6</constant>, <constant>FEC_7_8</constant></para>
</section>
<section id="isdbt-layer-mod">
<title><constant>DTV_ISDBT_LAYER*_MODULATION</constant></title>
<para>Possible values: <constant>QAM_AUTO</constant>, QP<constant>SK, QAM_16</constant>, <constant>QAM_64</constant>, <constant>DQPSK</constant></para>
<para>Note: If layer C is <constant>DQPSK</constant> layer B has to be <constant>DQPSK</constant>. If layer B is <constant>DQPSK</constant>
and <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>=0 layer has to be <constant>DQPSK</constant>.</para>
</section>
<section id="isdbt-layer-seg-cnt">
<title><constant>DTV_ISDBT_LAYER*_SEGMENT_COUNT</constant></title>
<para>Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)</para>
<para>Note: Truth table for <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> and
<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> and <constant>LAYER</constant>*_SEGMENT_COUNT</para>
<informaltable id="isdbt-layer_seg-cnt-table">
<tgroup cols="6">
<tbody>
<row>
<entry>PR</entry>
<entry>SB</entry>
<entry>Layer A width</entry>
<entry>Layer B width</entry>
<entry>Layer C width</entry>
<entry>total width</entry>
</row>
<row>
<entry>0</entry>
<entry>0</entry>
<entry>1 .. 13</entry>
<entry>1 .. 13</entry>
<entry>1 .. 13</entry>
<entry>13</entry>
</row>
<row>
<entry>1</entry>
<entry>0</entry>
<entry>1</entry>
<entry>1 .. 13</entry>
<entry>1 .. 13</entry>
<entry>13</entry>
</row>
<row>
<entry>0</entry>
<entry>1</entry>
<entry>1</entry>
<entry>0</entry>
<entry>0</entry>
<entry>1</entry>
</row>
<row>
<entry>1</entry>
<entry>1</entry>
<entry>1</entry>
<entry>2</entry>
<entry>0</entry>
<entry>13</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section id="isdbt_layer_t_interl">
<title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
<para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
<para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
here are referring to what can be found in the TMCC-structure -
independent of the mode.</para>
</section>
</section>
</section>
</section>
</section>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1,365 @@
<title>Examples</title>
<para>In this section we would like to present some examples for using the DVB API.
</para>
<para>Maintainer note: This section is out of date. Please refer to the sample programs packaged
with the driver distribution from <ulink url="http://linuxtv.org/hg/dvb-apps" />.
</para>
<section id="tuning">
<title>Tuning</title>
<para>We will start with a generic tuning subroutine that uses the frontend and SEC, as well as
the demux devices. The example is given for QPSK tuners, but can easily be adjusted for
QAM.
</para>
<programlisting>
#include &#x003C;sys/ioctl.h&#x003E;
#include &#x003C;stdio.h&#x003E;
#include &#x003C;stdint.h&#x003E;
#include &#x003C;sys/types.h&#x003E;
#include &#x003C;sys/stat.h&#x003E;
#include &#x003C;fcntl.h&#x003E;
#include &#x003C;time.h&#x003E;
#include &#x003C;unistd.h&#x003E;
#include &#x003C;linux/dvb/dmx.h&#x003E;
#include &#x003C;linux/dvb/frontend.h&#x003E;
#include &#x003C;linux/dvb/sec.h&#x003E;
#include &#x003C;sys/poll.h&#x003E;
#define DMX "/dev/dvb/adapter0/demux1"
#define FRONT "/dev/dvb/adapter0/frontend1"
#define SEC "/dev/dvb/adapter0/sec1"
/&#x22C6; routine for checking if we have a signal and other status information&#x22C6;/
int FEReadStatus(int fd, fe_status_t &#x22C6;stat)
{
int ans;
if ( (ans = ioctl(fd,FE_READ_STATUS,stat) &#x003C; 0)){
perror("FE READ STATUS: ");
return -1;
}
if (&#x22C6;stat &amp; FE_HAS_POWER)
printf("FE HAS POWER\n");
if (&#x22C6;stat &amp; FE_HAS_SIGNAL)
printf("FE HAS SIGNAL\n");
if (&#x22C6;stat &amp; FE_SPECTRUM_INV)
printf("SPEKTRUM INV\n");
return 0;
}
/&#x22C6; tune qpsk &#x22C6;/
/&#x22C6; freq: frequency of transponder &#x22C6;/
/&#x22C6; vpid, apid, tpid: PIDs of video, audio and teletext TS packets &#x22C6;/
/&#x22C6; diseqc: DiSEqC address of the used LNB &#x22C6;/
/&#x22C6; pol: Polarisation &#x22C6;/
/&#x22C6; srate: Symbol Rate &#x22C6;/
/&#x22C6; fec. FEC &#x22C6;/
/&#x22C6; lnb_lof1: local frequency of lower LNB band &#x22C6;/
/&#x22C6; lnb_lof2: local frequency of upper LNB band &#x22C6;/
/&#x22C6; lnb_slof: switch frequency of LNB &#x22C6;/
int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
int diseqc, int pol, int srate, int fec, int lnb_lof1,
int lnb_lof2, int lnb_slof)
{
struct secCommand scmd;
struct secCmdSequence scmds;
struct dmx_pes_filter_params pesFilterParams;
FrontendParameters frp;
struct pollfd pfd[1];
FrontendEvent event;
int demux1, demux2, demux3, front;
frequency = (uint32_t) freq;
symbolrate = (uint32_t) srate;
if((front = open(FRONT,O_RDWR)) &#x003C; 0){
perror("FRONTEND DEVICE: ");
return -1;
}
if((sec = open(SEC,O_RDWR)) &#x003C; 0){
perror("SEC DEVICE: ");
return -1;
}
if (demux1 &#x003C; 0){
if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
&#x003C; 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
if (demux2 &#x003C; 0){
if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
&#x003C; 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
if (demux3 &#x003C; 0){
if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
&#x003C; 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
if (freq &#x003C; lnb_slof) {
frp.Frequency = (freq - lnb_lof1);
scmds.continuousTone = SEC_TONE_OFF;
} else {
frp.Frequency = (freq - lnb_lof2);
scmds.continuousTone = SEC_TONE_ON;
}
frp.Inversion = INVERSION_AUTO;
if (pol) scmds.voltage = SEC_VOLTAGE_18;
else scmds.voltage = SEC_VOLTAGE_13;
scmd.type=0;
scmd.u.diseqc.addr=0x10;
scmd.u.diseqc.cmd=0x38;
scmd.u.diseqc.numParams=1;
scmd.u.diseqc.params[0] = 0xF0 | ((diseqc &#x22C6; 4) &amp; 0x0F) |
(scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
(scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
scmds.miniCommand=SEC_MINI_NONE;
scmds.numCommands=1;
scmds.commands=&amp;scmd;
if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
perror("SEC SEND: ");
return -1;
}
if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
perror("SEC SEND: ");
return -1;
}
frp.u.qpsk.SymbolRate = srate;
frp.u.qpsk.FEC_inner = fec;
if (ioctl(front, FE_SET_FRONTEND, &amp;frp) &#x003C; 0){
perror("QPSK TUNE: ");
return -1;
}
pfd[0].fd = front;
pfd[0].events = POLLIN;
if (poll(pfd,1,3000)){
if (pfd[0].revents &amp; POLLIN){
printf("Getting QPSK event\n");
if ( ioctl(front, FE_GET_EVENT, &amp;event)
== -EOVERFLOW){
perror("qpsk get event");
return -1;
}
printf("Received ");
switch(event.type){
case FE_UNEXPECTED_EV:
printf("unexpected event\n");
return -1;
case FE_FAILURE_EV:
printf("failure event\n");
return -1;
case FE_COMPLETION_EV:
printf("completion event\n");
}
}
}
pesFilterParams.pid = vpid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_DECODER;
pesFilterParams.pes_type = DMX_PES_VIDEO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux1, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
perror("set_vpid");
return -1;
}
pesFilterParams.pid = apid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_DECODER;
pesFilterParams.pes_type = DMX_PES_AUDIO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux2, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
perror("set_apid");
return -1;
}
pesFilterParams.pid = tpid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_DECODER;
pesFilterParams.pes_type = DMX_PES_TELETEXT;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux3, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
perror("set_tpid");
return -1;
}
return has_signal(fds);
}
</programlisting>
<para>The program assumes that you are using a universal LNB and a standard DiSEqC
switch with up to 4 addresses. Of course, you could build in some more checking if
tuning was successful and maybe try to repeat the tuning process. Depending on the
external hardware, i.e. LNB and DiSEqC switch, and weather conditions this may be
necessary.
</para>
</section>
<section id="the_dvr_device">
<title>The DVR device</title>
<para>The following program code shows how to use the DVR device for recording.
</para>
<programlisting>
#include &#x003C;sys/ioctl.h&#x003E;
#include &#x003C;stdio.h&#x003E;
#include &#x003C;stdint.h&#x003E;
#include &#x003C;sys/types.h&#x003E;
#include &#x003C;sys/stat.h&#x003E;
#include &#x003C;fcntl.h&#x003E;
#include &#x003C;time.h&#x003E;
#include &#x003C;unistd.h&#x003E;
#include &#x003C;linux/dvb/dmx.h&#x003E;
#include &#x003C;linux/dvb/video.h&#x003E;
#include &#x003C;sys/poll.h&#x003E;
#define DVR "/dev/dvb/adapter0/dvr1"
#define AUDIO "/dev/dvb/adapter0/audio1"
#define VIDEO "/dev/dvb/adapter0/video1"
#define BUFFY (188&#x22C6;20)
#define MAX_LENGTH (1024&#x22C6;1024&#x22C6;5) /&#x22C6; record 5MB &#x22C6;/
/&#x22C6; switch the demuxes to recording, assuming the transponder is tuned &#x22C6;/
/&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
/&#x22C6; vpid, apid: PIDs of video and audio channels &#x22C6;/
int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
{
struct dmx_pes_filter_params pesFilterParams;
if (demux1 &#x003C; 0){
if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
&#x003C; 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
if (demux2 &#x003C; 0){
if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
&#x003C; 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
pesFilterParams.pid = vpid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_TS_TAP;
pesFilterParams.pes_type = DMX_PES_VIDEO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux1, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
perror("DEMUX DEVICE");
return -1;
}
pesFilterParams.pid = apid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_TS_TAP;
pesFilterParams.pes_type = DMX_PES_AUDIO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux2, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
perror("DEMUX DEVICE");
return -1;
}
return 0;
}
/&#x22C6; start recording MAX_LENGTH , assuming the transponder is tuned &#x22C6;/
/&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
/&#x22C6; vpid, apid: PIDs of video and audio channels &#x22C6;/
int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
{
int i;
int len;
int written;
uint8_t buf[BUFFY];
uint64_t length;
struct pollfd pfd[1];
int dvr, dvr_out;
/&#x22C6; open dvr device &#x22C6;/
if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) &#x003C; 0){
perror("DVR DEVICE");
return -1;
}
/&#x22C6; switch video and audio demuxes to dvr &#x22C6;/
printf ("Switching dvr on\n");
i = switch_to_record(demux1, demux2, vpid, apid);
printf("finished: ");
printf("Recording %2.0f MB of test file in TS format\n",
MAX_LENGTH/(1024.0&#x22C6;1024.0));
length = 0;
/&#x22C6; open output file &#x22C6;/
if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
|O_TRUNC, S_IRUSR|S_IWUSR
|S_IRGRP|S_IWGRP|S_IROTH|
S_IWOTH)) &#x003C; 0){
perror("Can't open file for dvr test");
return -1;
}
pfd[0].fd = dvr;
pfd[0].events = POLLIN;
/&#x22C6; poll for dvr data and write to file &#x22C6;/
while (length &#x003C; MAX_LENGTH ) {
if (poll(pfd,1,1)){
if (pfd[0].revents &amp; POLLIN){
len = read(dvr, buf, BUFFY);
if (len &#x003C; 0){
perror("recording");
return -1;
}
if (len &#x003E; 0){
written = 0;
while (written &#x003C; len)
written +=
write (dvr_out,
buf, len);
length += len;
printf("written %2.0f MB\r",
length/1024./1024.);
}
}
}
}
return 0;
}
</programlisting>
</section>

View File

@@ -0,0 +1,416 @@
<programlisting>
/*
* frontend.h
*
* Copyright (C) 2000 Marcus Metzler &lt;marcus@convergence.de&gt;
* Ralph Metzler &lt;ralph@convergence.de&gt;
* Holger Waechtler &lt;holger@convergence.de&gt;
* Andre Draszik &lt;ad@convergence.de&gt;
* for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef _DVBFRONTEND_H_
#define _DVBFRONTEND_H_
#include &lt;linux/types.h&gt;
typedef enum fe_type {
FE_QPSK,
FE_QAM,
FE_OFDM,
FE_ATSC
} fe_type_t;
typedef enum fe_caps {
FE_IS_STUPID = 0,
FE_CAN_INVERSION_AUTO = 0x1,
FE_CAN_FEC_1_2 = 0x2,
FE_CAN_FEC_2_3 = 0x4,
FE_CAN_FEC_3_4 = 0x8,
FE_CAN_FEC_4_5 = 0x10,
FE_CAN_FEC_5_6 = 0x20,
FE_CAN_FEC_6_7 = 0x40,
FE_CAN_FEC_7_8 = 0x80,
FE_CAN_FEC_8_9 = 0x100,
FE_CAN_FEC_AUTO = 0x200,
FE_CAN_QPSK = 0x400,
FE_CAN_QAM_16 = 0x800,
FE_CAN_QAM_32 = 0x1000,
FE_CAN_QAM_64 = 0x2000,
FE_CAN_QAM_128 = 0x4000,
FE_CAN_QAM_256 = 0x8000,
FE_CAN_QAM_AUTO = 0x10000,
FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000,
FE_CAN_BANDWIDTH_AUTO = 0x40000,
FE_CAN_GUARD_INTERVAL_AUTO = 0x80000,
FE_CAN_HIERARCHY_AUTO = 0x100000,
FE_CAN_8VSB = 0x200000,
FE_CAN_16VSB = 0x400000,
FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */
FE_CAN_TURBO_FEC = 0x8000000, /* frontend supports "turbo fec modulation" */
FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */
FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */
FE_CAN_RECOVER = 0x40000000, /* frontend can recover from a cable unplug automatically */
FE_CAN_MUTE_TS = 0x80000000 /* frontend can stop spurious TS data output */
} fe_caps_t;
struct dvb_frontend_info {
char name[128];
fe_type_t type;
__u32 frequency_min;
__u32 frequency_max;
__u32 frequency_stepsize;
__u32 frequency_tolerance;
__u32 symbol_rate_min;
__u32 symbol_rate_max;
__u32 symbol_rate_tolerance; /* ppm */
__u32 notifier_delay; /* DEPRECATED */
fe_caps_t caps;
};
/**
* Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for
* the meaning of this struct...
*/
struct dvb_diseqc_master_cmd {
__u8 msg [6]; /* { framing, address, command, data [3] } */
__u8 msg_len; /* valid values are 3...6 */
};
struct dvb_diseqc_slave_reply {
__u8 msg [4]; /* { framing, data [3] } */
__u8 msg_len; /* valid values are 0...4, 0 means no msg */
int timeout; /* return from ioctl after timeout ms with */
}; /* errorcode when no message was received */
typedef enum fe_sec_voltage {
SEC_VOLTAGE_13,
SEC_VOLTAGE_18,
SEC_VOLTAGE_OFF
} fe_sec_voltage_t;
typedef enum fe_sec_tone_mode {
SEC_TONE_ON,
SEC_TONE_OFF
} fe_sec_tone_mode_t;
typedef enum fe_sec_mini_cmd {
SEC_MINI_A,
SEC_MINI_B
} fe_sec_mini_cmd_t;
typedef enum fe_status {
FE_HAS_SIGNAL = 0x01, /* found something above the noise level */
FE_HAS_CARRIER = 0x02, /* found a DVB signal */
FE_HAS_VITERBI = 0x04, /* FEC is stable */
FE_HAS_SYNC = 0x08, /* found sync bytes */
FE_HAS_LOCK = 0x10, /* everything's working... */
FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */
FE_REINIT = 0x40 /* frontend was reinitialized, */
} fe_status_t; /* application is recommended to reset */
/* DiSEqC, tone and parameters */
typedef enum fe_spectral_inversion {
INVERSION_OFF,
INVERSION_ON,
INVERSION_AUTO
} fe_spectral_inversion_t;
typedef enum fe_code_rate {
FEC_NONE = 0,
FEC_1_2,
FEC_2_3,
FEC_3_4,
FEC_4_5,
FEC_5_6,
FEC_6_7,
FEC_7_8,
FEC_8_9,
FEC_AUTO,
FEC_3_5,
FEC_9_10,
} fe_code_rate_t;
typedef enum fe_modulation {
QPSK,
QAM_16,
QAM_32,
QAM_64,
QAM_128,
QAM_256,
QAM_AUTO,
VSB_8,
VSB_16,
PSK_8,
APSK_16,
APSK_32,
DQPSK,
} fe_modulation_t;
typedef enum fe_transmit_mode {
TRANSMISSION_MODE_2K,
TRANSMISSION_MODE_8K,
TRANSMISSION_MODE_AUTO,
TRANSMISSION_MODE_4K
} fe_transmit_mode_t;
typedef enum fe_bandwidth {
BANDWIDTH_8_MHZ,
BANDWIDTH_7_MHZ,
BANDWIDTH_6_MHZ,
BANDWIDTH_AUTO
} fe_bandwidth_t;
typedef enum fe_guard_interval {
GUARD_INTERVAL_1_32,
GUARD_INTERVAL_1_16,
GUARD_INTERVAL_1_8,
GUARD_INTERVAL_1_4,
GUARD_INTERVAL_AUTO
} fe_guard_interval_t;
typedef enum fe_hierarchy {
HIERARCHY_NONE,
HIERARCHY_1,
HIERARCHY_2,
HIERARCHY_4,
HIERARCHY_AUTO
} fe_hierarchy_t;
struct dvb_qpsk_parameters {
__u32 symbol_rate; /* symbol rate in Symbols per second */
fe_code_rate_t fec_inner; /* forward error correction (see above) */
};
struct dvb_qam_parameters {
__u32 symbol_rate; /* symbol rate in Symbols per second */
fe_code_rate_t fec_inner; /* forward error correction (see above) */
fe_modulation_t modulation; /* modulation type (see above) */
};
struct dvb_vsb_parameters {
fe_modulation_t modulation; /* modulation type (see above) */
};
struct dvb_ofdm_parameters {
fe_bandwidth_t bandwidth;
fe_code_rate_t code_rate_HP; /* high priority stream code rate */
fe_code_rate_t code_rate_LP; /* low priority stream code rate */
fe_modulation_t constellation; /* modulation type (see above) */
fe_transmit_mode_t transmission_mode;
fe_guard_interval_t guard_interval;
fe_hierarchy_t hierarchy_information;
};
struct dvb_frontend_parameters {
__u32 frequency; /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
/* intermediate frequency in kHz for QPSK */
fe_spectral_inversion_t inversion;
union {
struct dvb_qpsk_parameters qpsk;
struct dvb_qam_parameters qam;
struct dvb_ofdm_parameters ofdm;
struct dvb_vsb_parameters vsb;
} u;
};
struct dvb_frontend_event {
fe_status_t status;
struct dvb_frontend_parameters parameters;
};
/* S2API Commands */
#define DTV_UNDEFINED 0
#define DTV_TUNE 1
#define DTV_CLEAR 2
#define DTV_FREQUENCY 3
#define DTV_MODULATION 4
#define DTV_BANDWIDTH_HZ 5
#define DTV_INVERSION 6
#define DTV_DISEQC_MASTER 7
#define DTV_SYMBOL_RATE 8
#define DTV_INNER_FEC 9
#define DTV_VOLTAGE 10
#define DTV_TONE 11
#define DTV_PILOT 12
#define DTV_ROLLOFF 13
#define DTV_DISEQC_SLAVE_REPLY 14
/* Basic enumeration set for querying unlimited capabilities */
#define DTV_FE_CAPABILITY_COUNT 15
#define DTV_FE_CAPABILITY 16
#define DTV_DELIVERY_SYSTEM 17
/* ISDB-T and ISDB-Tsb */
#define DTV_ISDBT_PARTIAL_RECEPTION 18
#define DTV_ISDBT_SOUND_BROADCASTING 19
#define DTV_ISDBT_SB_SUBCHANNEL_ID 20
#define DTV_ISDBT_SB_SEGMENT_IDX 21
#define DTV_ISDBT_SB_SEGMENT_COUNT 22
#define DTV_ISDBT_LAYERA_FEC 23
#define DTV_ISDBT_LAYERA_MODULATION 24
#define DTV_ISDBT_LAYERA_SEGMENT_COUNT 25
#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING 26
#define DTV_ISDBT_LAYERB_FEC 27
#define DTV_ISDBT_LAYERB_MODULATION 28
#define DTV_ISDBT_LAYERB_SEGMENT_COUNT 29
#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING 30
#define DTV_ISDBT_LAYERC_FEC 31
#define DTV_ISDBT_LAYERC_MODULATION 32
#define DTV_ISDBT_LAYERC_SEGMENT_COUNT 33
#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING 34
#define DTV_API_VERSION 35
#define DTV_CODE_RATE_HP 36
#define DTV_CODE_RATE_LP 37
#define DTV_GUARD_INTERVAL 38
#define DTV_TRANSMISSION_MODE 39
#define DTV_HIERARCHY 40
#define DTV_ISDBT_LAYER_ENABLED 41
#define DTV_ISDBS_TS_ID 42
#define DTV_MAX_COMMAND DTV_ISDBS_TS_ID
typedef enum fe_pilot {
PILOT_ON,
PILOT_OFF,
PILOT_AUTO,
} fe_pilot_t;
typedef enum fe_rolloff {
ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */
ROLLOFF_20,
ROLLOFF_25,
ROLLOFF_AUTO,
} fe_rolloff_t;
typedef enum fe_delivery_system {
SYS_UNDEFINED,
SYS_DVBC_ANNEX_AC,
SYS_DVBC_ANNEX_B,
SYS_DVBT,
SYS_DSS,
SYS_DVBS,
SYS_DVBS2,
SYS_DVBH,
SYS_ISDBT,
SYS_ISDBS,
SYS_ISDBC,
SYS_ATSC,
SYS_ATSCMH,
SYS_DMBTH,
SYS_CMMB,
SYS_DAB,
} fe_delivery_system_t;
struct dtv_cmds_h {
char *name; /* A display name for debugging purposes */
__u32 cmd; /* A unique ID */
/* Flags */
__u32 set:1; /* Either a set or get property */
__u32 buffer:1; /* Does this property use the buffer? */
__u32 reserved:30; /* Align */
};
struct dtv_property {
__u32 cmd;
__u32 reserved[3];
union {
__u32 data;
struct {
__u8 data[32];
__u32 len;
__u32 reserved1[3];
void *reserved2;
} buffer;
} u;
int result;
} __attribute__ ((packed));
/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */
#define DTV_IOCTL_MAX_MSGS 64
struct dtv_properties {
__u32 num;
struct dtv_property *props;
};
#define <link linkend="FE_GET_PROPERTY">FE_SET_PROPERTY</link> _IOW('o', 82, struct dtv_properties)
#define <link linkend="FE_GET_PROPERTY">FE_GET_PROPERTY</link> _IOR('o', 83, struct dtv_properties)
/**
* When set, this flag will disable any zigzagging or other "normal" tuning
* behaviour. Additionally, there will be no automatic monitoring of the lock
* status, and hence no frontend events will be generated. If a frontend device
* is closed, this flag will be automatically turned off when the device is
* reopened read-write.
*/
#define FE_TUNE_MODE_ONESHOT 0x01
#define <link linkend="FE_GET_INFO">FE_GET_INFO</link> _IOR('o', 61, struct dvb_frontend_info)
#define <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link> _IO('o', 62)
#define <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link> _IOW('o', 63, struct dvb_diseqc_master_cmd)
#define <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link> _IOR('o', 64, struct dvb_diseqc_slave_reply)
#define <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link> _IO('o', 65) /* fe_sec_mini_cmd_t */
#define <link linkend="FE_SET_TONE">FE_SET_TONE</link> _IO('o', 66) /* fe_sec_tone_mode_t */
#define <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link> _IO('o', 67) /* fe_sec_voltage_t */
#define <link linkend="FE_ENABLE_HIGH_LNB_VOLTAGE">FE_ENABLE_HIGH_LNB_VOLTAGE</link> _IO('o', 68) /* int */
#define <link linkend="FE_READ_STATUS">FE_READ_STATUS</link> _IOR('o', 69, fe_status_t)
#define <link linkend="FE_READ_BER">FE_READ_BER</link> _IOR('o', 70, __u32)
#define <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link> _IOR('o', 71, __u16)
#define <link linkend="FE_READ_SNR">FE_READ_SNR</link> _IOR('o', 72, __u16)
#define <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link> _IOR('o', 73, __u32)
#define <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> _IOW('o', 76, struct dvb_frontend_parameters)
#define <link linkend="FE_GET_FRONTEND">FE_GET_FRONTEND</link> _IOR('o', 77, struct dvb_frontend_parameters)
#define <link linkend="FE_SET_FRONTEND_TUNE_MODE">FE_SET_FRONTEND_TUNE_MODE</link> _IO('o', 81) /* unsigned int */
#define <link linkend="FE_GET_EVENT">FE_GET_EVENT</link> _IOR('o', 78, struct dvb_frontend_event)
#define <link linkend="FE_DISHNETWORK_SEND_LEGACY_CMD">FE_DISHNETWORK_SEND_LEGACY_CMD</link> _IO('o', 80) /* unsigned int */
#endif /*_DVBFRONTEND_H_*/
</programlisting>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,191 @@
<title>Introduction</title>
<section id="requisites">
<title>What you need to know</title>
<para>The reader of this document is required to have some knowledge in
the area of digital video broadcasting (DVB) and should be familiar with
part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e
you should know what a program/transport stream (PS/TS) is and what is
meant by a packetized elementary stream (PES) or an I-frame.</para>
<para>Various DVB standards documents are available from
<ulink url="http://www.dvb.org" /> and/or
<ulink url="http://www.etsi.org" />.</para>
<para>It is also necessary to know how to access unix/linux devices and
how to use ioctl calls. This also includes the knowledge of C or C++.
</para>
</section>
<section id="history">
<title>History</title>
<para>The first API for DVB cards we used at Convergence in late 1999
was an extension of the Video4Linux API which was primarily developed
for frame grabber cards. As such it was not really well suited to be
used for DVB cards and their new features like recording MPEG streams
and filtering several section and PES data streams at the same time.
</para>
<para>In early 2000, we were approached by Nokia with a proposal for a
new standard Linux DVB API. As a commitment to the development of
terminals based on open standards, Nokia and Convergence made it
available to all Linux developers and published it on
<ulink url="http://www.linuxtv.org/" /> in September 2000.
Convergence is the maintainer of the Linux DVB API. Together with the
LinuxTV community (i.e. you, the reader of this document), the Linux DVB
API will be constantly reviewed and improved. With the Linux driver for
the Siemens/Hauppauge DVB PCI card Convergence provides a first
implementation of the Linux DVB API.</para>
</section>
<section id="overview">
<title>Overview</title>
<figure id="stb_components">
<title>Components of a DVB card/STB</title>
<mediaobject>
<imageobject>
<imagedata fileref="dvbstb.pdf" format="PS" />
</imageobject>
<imageobject>
<imagedata fileref="dvbstb.png" format="PNG" />
</imageobject>
</mediaobject>
</figure>
<para>A DVB PCI card or DVB set-top-box (STB) usually consists of the
following main hardware components: </para>
<itemizedlist>
<listitem>
<para>Frontend consisting of tuner and DVB demodulator</para>
<para>Here the raw signal reaches the DVB hardware from a satellite dish
or antenna or directly from cable. The frontend down-converts and
demodulates this signal into an MPEG transport stream (TS). In case of a
satellite frontend, this includes a facility for satellite equipment
control (SEC), which allows control of LNB polarization, multi feed
switches or dish rotors.</para>
</listitem>
<listitem>
<para>Conditional Access (CA) hardware like CI adapters and smartcard slots
</para>
<para>The complete TS is passed through the CA hardware. Programs to
which the user has access (controlled by the smart card) are decoded in
real time and re-inserted into the TS.</para>
</listitem>
<listitem>
<para>Demultiplexer which filters the incoming DVB stream</para>
<para>The demultiplexer splits the TS into its components like audio and
video streams. Besides usually several of such audio and video streams
it also contains data streams with information about the programs
offered in this or other streams of the same provider.</para>
</listitem>
<listitem>
<para>MPEG2 audio and video decoder</para>
<para>The main targets of the demultiplexer are the MPEG2 audio and
video decoders. After decoding they pass on the uncompressed audio and
video to the computer screen or (through a PAL/NTSC encoder) to a TV
set.</para>
</listitem>
</itemizedlist>
<para><xref linkend="stb_components" /> shows a crude schematic of the control and data flow
between those components.</para>
<para>On a DVB PCI card not all of these have to be present since some
functionality can be provided by the main CPU of the PC (e.g. MPEG
picture and sound decoding) or is not needed (e.g. for data-only uses
like &#8220;internet over satellite&#8221;). Also not every card or STB
provides conditional access hardware.</para>
</section>
<section id="dvb_devices">
<title>Linux DVB Devices</title>
<para>The Linux DVB API lets you control these hardware components
through currently six Unix-style character devices for video, audio,
frontend, demux, CA and IP-over-DVB networking. The video and audio
devices control the MPEG2 decoder hardware, the frontend device the
tuner and the DVB demodulator. The demux device gives you control over
the PES and section filters of the hardware. If the hardware does not
support filtering these filters can be implemented in software. Finally,
the CA device controls all the conditional access capabilities of the
hardware. It can depend on the individual security requirements of the
platform, if and how many of the CA functions are made available to the
application through this device.</para>
<para>All devices can be found in the <emphasis role="tt">/dev</emphasis>
tree under <emphasis role="tt">/dev/dvb</emphasis>. The individual devices
are called:</para>
<itemizedlist>
<listitem>
<para><emphasis role="tt">/dev/dvb/adapterN/audioM</emphasis>,</para>
</listitem>
<listitem>
<para><emphasis role="tt">/dev/dvb/adapterN/videoM</emphasis>,</para>
</listitem>
<listitem>
<para><emphasis role="tt">/dev/dvb/adapterN/frontendM</emphasis>,</para>
</listitem>
<listitem>
<para><emphasis role="tt">/dev/dvb/adapterN/netM</emphasis>,</para>
</listitem>
<listitem>
<para><emphasis role="tt">/dev/dvb/adapterN/demuxM</emphasis>,</para>
</listitem>
<listitem>
<para><emphasis role="tt">/dev/dvb/adapterN/caM</emphasis>,</para></listitem></itemizedlist>
<para>where N enumerates the DVB PCI cards in a system starting
from&#x00A0;0, and M enumerates the devices of each type within each
adapter, starting from&#x00A0;0, too. We will omit the &#8220;<emphasis
role="tt">/dev/dvb/adapterN/</emphasis>&#8221; in the further dicussion
of these devices. The naming scheme for the devices is the same wheter
devfs is used or not.</para>
<para>More details about the data structures and function calls of all
the devices are described in the following chapters.</para>
</section>
<section id="include_files">
<title>API include files</title>
<para>For each of the DVB devices a corresponding include file exists.
The DVB API include files should be included in application sources with
a partial path like:</para>
<programlisting>
#include &#x003C;linux/dvb/frontend.h&#x003E;
</programlisting>
<para>To enable applications to support different API version, an
additional include file <emphasis
role="tt">linux/dvb/version.h</emphasis> exists, which defines the
constant <emphasis role="tt">DVB_API_VERSION</emphasis>. This document
describes <emphasis role="tt">DVB_API_VERSION&#x00A0;3</emphasis>.
</para>
</section>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
<title>DVB Network API</title>
<para>The DVB net device enables feeding of MPE (multi protocol encapsulation) packets
received via DVB into the Linux network protocol stack, e.g. for internet via satellite
applications. It can be accessed through <emphasis role="tt">/dev/dvb/adapter0/net0</emphasis>. Data types and
and ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/net.h</emphasis> in your
application.
</para>
<section id="dvb_net_types">
<title>DVB Net Data Types</title>
<para>To be written&#x2026;
</para>
</section>

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,7 @@
</authorgroup>
<copyright>
<year>2005-2006</year>
<year>2005-2010</year>
<holder>Thomas Gleixner</holder>
</copyright>
<copyright>
@@ -100,6 +100,10 @@
<listitem><para>Edge type</para></listitem>
<listitem><para>Simple type</para></listitem>
</itemizedlist>
During the implementation we identified another type:
<itemizedlist>
<listitem><para>Fast EOI type</para></listitem>
</itemizedlist>
In the SMP world of the __do_IRQ() super-handler another type
was identified:
<itemizedlist>
@@ -153,6 +157,7 @@
is still available. This leads to a kind of duality for the time
being. Over time the new model should be used in more and more
architectures, as it enables smaller and cleaner IRQ subsystems.
It's deprecated for three years now and about to be removed.
</para>
</chapter>
<chapter id="bugs">
@@ -217,6 +222,7 @@
<itemizedlist>
<listitem><para>handle_level_irq</para></listitem>
<listitem><para>handle_edge_irq</para></listitem>
<listitem><para>handle_fasteoi_irq</para></listitem>
<listitem><para>handle_simple_irq</para></listitem>
<listitem><para>handle_percpu_irq</para></listitem>
</itemizedlist>
@@ -233,33 +239,33 @@
are used by the default flow implementations.
The following helper functions are implemented (simplified excerpt):
<programlisting>
default_enable(irq)
default_enable(struct irq_data *data)
{
desc->chip->unmask(irq);
desc->chip->irq_unmask(data);
}
default_disable(irq)
default_disable(struct irq_data *data)
{
if (!delay_disable(irq))
desc->chip->mask(irq);
if (!delay_disable(data))
desc->chip->irq_mask(data);
}
default_ack(irq)
default_ack(struct irq_data *data)
{
chip->ack(irq);
chip->irq_ack(data);
}
default_mask_ack(irq)
default_mask_ack(struct irq_data *data)
{
if (chip->mask_ack) {
chip->mask_ack(irq);
if (chip->irq_mask_ack) {
chip->irq_mask_ack(data);
} else {
chip->mask(irq);
chip->ack(irq);
chip->irq_mask(data);
chip->irq_ack(data);
}
}
noop(irq)
noop(struct irq_data *data))
{
}
@@ -278,12 +284,27 @@ noop(irq)
<para>
The following control flow is implemented (simplified excerpt):
<programlisting>
desc->chip->start();
desc->chip->irq_mask();
handle_IRQ_event(desc->action);
desc->chip->end();
desc->chip->irq_unmask();
</programlisting>
</para>
</sect3>
</sect3>
<sect3 id="Default_FASTEOI_IRQ_flow_handler">
<title>Default Fast EOI IRQ flow handler</title>
<para>
handle_fasteoi_irq provides a generic implementation
for interrupts, which only need an EOI at the end of
the handler
</para>
<para>
The following control flow is implemented (simplified excerpt):
<programlisting>
handle_IRQ_event(desc->action);
desc->chip->irq_eoi();
</programlisting>
</para>
</sect3>
<sect3 id="Default_Edge_IRQ_flow_handler">
<title>Default Edge IRQ flow handler</title>
<para>
@@ -294,20 +315,19 @@ desc->chip->end();
The following control flow is implemented (simplified excerpt):
<programlisting>
if (desc->status &amp; running) {
desc->chip->hold();
desc->chip->irq_mask();
desc->status |= pending | masked;
return;
}
desc->chip->start();
desc->chip->irq_ack();
desc->status |= running;
do {
if (desc->status &amp; masked)
desc->chip->enable();
desc->chip->irq_unmask();
desc->status &amp;= ~pending;
handle_IRQ_event(desc->action);
} while (status &amp; pending);
desc->status &amp;= ~running;
desc->chip->end();
</programlisting>
</para>
</sect3>
@@ -342,9 +362,9 @@ handle_IRQ_event(desc->action);
<para>
The following control flow is implemented (simplified excerpt):
<programlisting>
desc->chip->start();
handle_IRQ_event(desc->action);
desc->chip->end();
if (desc->chip->irq_eoi)
desc->chip->irq_eoi();
</programlisting>
</para>
</sect3>
@@ -375,8 +395,7 @@ desc->chip->end();
mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when
you want to use the delayed interrupt disable feature and your
hardware is not capable of retriggering an interrupt.)
The delayed interrupt disable can be runtime enabled, per interrupt,
by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field.
The delayed interrupt disable is not configurable.
</para>
</sect2>
</sect1>
@@ -387,13 +406,13 @@ desc->chip->end();
contains all the direct chip relevant functions, which
can be utilized by the irq flow implementations.
<itemizedlist>
<listitem><para>ack()</para></listitem>
<listitem><para>mask_ack() - Optional, recommended for performance</para></listitem>
<listitem><para>mask()</para></listitem>
<listitem><para>unmask()</para></listitem>
<listitem><para>retrigger() - Optional</para></listitem>
<listitem><para>set_type() - Optional</para></listitem>
<listitem><para>set_wake() - Optional</para></listitem>
<listitem><para>irq_ack()</para></listitem>
<listitem><para>irq_mask_ack() - Optional, recommended for performance</para></listitem>
<listitem><para>irq_mask()</para></listitem>
<listitem><para>irq_unmask()</para></listitem>
<listitem><para>irq_retrigger() - Optional</para></listitem>
<listitem><para>irq_set_type() - Optional</para></listitem>
<listitem><para>irq_set_wake() - Optional</para></listitem>
</itemizedlist>
These primitives are strictly intended to mean what they say: ack means
ACK, masking means masking of an IRQ line, etc. It is up to the flow
@@ -417,8 +436,8 @@ desc->chip->end();
</para>
<para>
To make use of the split implementation, replace the call to
__do_IRQ by a call to desc->chip->handle_irq() and associate
the appropriate handler function to desc->chip->handle_irq().
__do_IRQ by a call to desc->handle_irq() and associate
the appropriate handler function to desc->handle_irq().
In most cases the generic handler implementations should
be sufficient.
</para>
@@ -458,6 +477,7 @@ desc->chip->end();
<para>
This chapter contains the autogenerated documentation of the internal functions.
</para>
!Ikernel/irq/irqdesc.c
!Ikernel/irq/handle.c
!Ikernel/irq/chip.c
</chapter>

View File

@@ -57,7 +57,6 @@
</para>
<sect1><title>String Conversions</title>
!Ilib/vsprintf.c
!Elib/vsprintf.c
</sect1>
<sect1><title>String Manipulation</title>
@@ -94,6 +93,12 @@ X!Ilib/string.c
!Elib/crc32.c
!Elib/crc-ccitt.c
</sect1>
<sect1 id="idr"><title>idr/ida Functions</title>
!Pinclude/linux/idr.h idr sync
!Plib/idr.c IDA description
!Elib/idr.c
</sect1>
</chapter>
<chapter id="mm">
@@ -132,7 +137,6 @@ X!Ilib/string.c
<title>FIFO Buffer</title>
<sect1><title>kfifo interface</title>
!Iinclude/linux/kfifo.h
!Ekernel/kfifo.c
</sect1>
</chapter>
@@ -259,7 +263,8 @@ X!Earch/x86/kernel/mca_32.c
!Iblock/blk-sysfs.c
!Eblock/blk-settings.c
!Eblock/blk-exec.c
!Eblock/blk-barrier.c
!Eblock/blk-flush.c
!Eblock/blk-lib.c
!Eblock/blk-tag.c
!Iblock/blk-tag.c
!Eblock/blk-integrity.c

View File

@@ -352,7 +352,7 @@ asmlinkage long sys_mycall(int arg)
</para>
<programlisting>
if (signal_pending())
if (signal_pending(current))
return -ERESTARTSYS;
</programlisting>
@@ -449,8 +449,8 @@ printk(KERN_INFO "i = %u\n", i);
</para>
<programlisting>
__u32 ipaddress;
printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
__be32 ipaddress;
printk(KERN_INFO "my ip: %pI4\n", &amp;ipaddress);
</programlisting>
<para>

View File

@@ -1645,7 +1645,9 @@ the amount of locking which needs to be done.
all the readers who were traversing the list when we deleted the
element are finished. We use <function>call_rcu()</function> to
register a callback which will actually destroy the object once
the readers are finished.
all pre-existing readers are finished. Alternatively,
<function>synchronize_rcu()</function> may be used to block until
all pre-existing are finished.
</para>
<para>
But how does Read Copy Update know when the readers are
@@ -1714,7 +1716,7 @@ the amount of locking which needs to be done.
- object_put(obj);
+ list_del_rcu(&amp;obj-&gt;list);
cache_num--;
+ call_rcu(&amp;obj-&gt;rcu, cache_delete_rcu, obj);
+ call_rcu(&amp;obj-&gt;rcu, cache_delete_rcu);
}
/* Must be holding cache_lock */
@@ -1725,14 +1727,6 @@ the amount of locking which needs to be done.
if (++cache_num > MAX_CACHE_SIZE) {
struct object *i, *outcast = NULL;
list_for_each_entry(i, &amp;cache, list) {
@@ -85,6 +94,7 @@
obj-&gt;popularity = 0;
atomic_set(&amp;obj-&gt;refcnt, 1); /* The cache holds a reference */
spin_lock_init(&amp;obj-&gt;lock);
+ INIT_RCU_HEAD(&amp;obj-&gt;rcu);
spin_lock_irqsave(&amp;cache_lock, flags);
__cache_add(obj);
@@ -104,12 +114,11 @@
struct object *cache_find(int id)
{
@@ -1922,9 +1916,12 @@ machines due to caching.
<function>mutex_lock()</function>
</para>
<para>
There is a <function>mutex_trylock()</function> which can be
used inside interrupt context, as it will not sleep.
There is a <function>mutex_trylock()</function> which does not
sleep. Still, it must not be used inside interrupt context since
its implementation is not safe for that.
<function>mutex_unlock()</function> will also never sleep.
It cannot be used in interrupt context either since a mutex
must be released by the same task that acquired it.
</para>
</listitem>
</itemizedlist>
@@ -1958,6 +1955,12 @@ machines due to caching.
</sect1>
</chapter>
<chapter id="apiref">
<title>Mutex API reference</title>
!Iinclude/linux/mutex.h
!Ekernel/mutex.c
</chapter>
<chapter id="references">
<title>Further reading</title>

View File

@@ -4,7 +4,7 @@
<book id="kgdbOnLinux">
<bookinfo>
<title>Using kgdb and the kgdb Internals</title>
<title>Using kgdb, kdb and the kernel debugger internals</title>
<authorgroup>
<author>
@@ -17,33 +17,8 @@
</affiliation>
</author>
</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>
<year>2008</year>
<year>2008,2010</year>
<holder>Wind River Systems, Inc.</holder>
</copyright>
<copyright>
@@ -69,41 +44,76 @@
<chapter id="Introduction">
<title>Introduction</title>
<para>
kgdb is a source level debugger for 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 what an
application developer would use gdb for. It is possible to place
breakpoints in kernel code and perform some limited execution
stepping.
The kernel has two different debugger front ends (kdb and kgdb)
which interface to the debug core. It is possible to use either
of the debugger front ends and dynamically transition between them
if you configure the kernel properly at compile and runtime.
</para>
<para>
Two machines are required for using kgdb. One of these machines is a
development machine and the other is a test machine. The kernel
to be debugged runs on the test 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
builtin's or kernel modules in the test machine's kernel.
Kdb is simplistic shell-style interface which you can use on a
system console with a keyboard or serial console. You can use it
to inspect memory, registers, process lists, dmesg, and even set
breakpoints to stop in a certain location. Kdb is not a source
level debugger, although you can set breakpoints and execute some
basic kernel run control. Kdb is mainly aimed at doing some
analysis to aid in development or diagnosing kernel problems. You
can access some symbols by name in kernel built-ins or in 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>
</chapter>
<chapter id="CompilingAKernel">
<title>Compiling a kernel</title>
<title>Compiling a kernel</title>
<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
"Prompt for development and/or incomplete code/drivers"
(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>
It is advised, but not required that you turn on the
CONFIG_FRAME_POINTER kernel option. This option inserts code to
into the compiled executable which saves the frame information in
registers or on the stack at different points which will allow a
debugger such as gdb to more accurately construct stack back traces
while debugging the kernel.
<symbol>CONFIG_FRAME_POINTER</symbol> kernel option which is called "Compile the
kernel with frame pointers" in the config menu. This option
inserts code to into the compiled executable which saves the frame
information in registers or on the stack at different points which
allows a debugger such as gdb to more accurately construct
stack back traces while debugging the kernel.
</para>
<para>
If the architecture that you are using supports the kernel option
@@ -116,38 +126,192 @@
this option.
</para>
<para>
Next you should choose one of more I/O drivers to interconnect debugging
host and debugged target. Early boot debugging requires a KGDB
I/O driver that supports early debugging and the driver must be
built into the kernel directly. Kgdb I/O driver configuration
takes place via kernel or module parameters, see following
chapter.
Next you should choose one of more I/O drivers to interconnect
debugging host and debugged target. Early boot debugging requires
a KGDB I/O driver that supports early debugging and the driver
must be built into the kernel directly. Kgdb I/O driver
configuration takes place via kernel or module parameters which
you can learn more about in the in the section that describes the
parameter "kgdboc".
</para>
<para>
The kgdb test compile options are described in the kgdb test suite chapter.
<para>Here is an example set of .config symbols to enable or
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>
</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 id="EnableKGDB">
<title>Enable kgdb for debugging</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.
<chapter id="kgdbKernelArgs">
<title>Kernel Debugger Boot Arguments</title>
<para>This section describes the various runtime kernel
parameters that affect the configuration of the kernel debugger.
The following chapter covers using kdb and kgdb as well as
provides some examples of the configuration parameters.</para>
<sect1 id="kgdboc">
<title>Kernel parameter: kgdboc</title>
<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>
All 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/&lt;driver&gt;/parameter/&lt;option&gt;</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 unconfigure a kgdb I/O driver.
<para>For kgdb/gdb, kgdboc is designed to work with a single serial
port. It is intended to cover the circumstance where you want to
use a serial console as your primary console as well as using it to
perform kernel debugging. It is also possible to use kgdb on a
serial port which is not designated as a system console. Kgdboc
may be configured as a kernel built-in or a kernel loadable module.
You can only make use of <constant>kgdbwait</constant> and early
debugging if you build kgdboc into the kernel as a built-in.
<para>Optionally you can elect to activate kms (Kernel Mode
Setting) integration. When you use kms with kgdboc and you have a
video driver that has atomic mode setting hooks, it is possible to
enter the debugger on the graphics console. When the kernel
execution is resumed, the previous graphics mode will be restored.
This integration can serve as a useful tool to aid in diagnosing
crashes or doing analysis of memory with kdb while allowing the
full graphics console applications to run.
</para>
</para>
<sect2 id="kgdbocArgs">
<title>kgdboc arguments</title>
<para>Usage: <constant>kgdboc=[kms][[,]kbd][[,]serial_device][,baud]</constant></para>
<para>The order listed above must be observed if you use any of the
optional configurations together.
</para>
<para>Abbreviations:
<itemizedlist>
<listitem><para>kms = Kernel Mode Setting</para></listitem>
<listitem><para>kbd = Keyboard</para></listitem>
</itemizedlist>
</para>
<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. The order listed above must be observed if
you use any of the optional configurations together. Using kms +
only gdb is generally not a useful combination.</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=&lt;tty-device&gt;,[baud]</constant></para></listitem>
<listitem>
<para>As a kernel loadable module:</para>
<para>Use the command: <constant>modprobe kgdboc kgdboc=&lt;tty-device&gt;,[baud]</constant></para>
<para>Here are two examples of how you might format 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 &gt; /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
<listitem><para>Disable kgdboc</para>
<para><constant>echo "" &gt; /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.</para>
<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=&lt;serial_device&gt;[,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,&lt;serial_device&gt;[,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>
<listitem><para>kdb with kernel mode setting</para>
<para><constant>kgdboc=kms,kbd</constant></para>
</listitem>
<listitem><para>kdb with kernel mode setting and kgdb over a serial port</para>
<para><constant>kgdboc=kms,kbd,ttyS0,115200</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">
<title>Kernel parameter: kgdbwait</title>
<para>
@@ -162,103 +326,204 @@
</para>
<para>
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
kgdb I/O driver as a kernel module kgdbwait will not do anything.
architecture allows when you use this option. If you build the
kgdb I/O driver as a loadable kernel module kgdbwait will not do
anything.
</para>
</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=&lt;tty-device&gt;,[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 &gt; /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">
<title>Kernel parameter: kgdbcon</title>
<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>
<listitem><para>Activate with the kernel command line option:</para>
<para><constant>kgdbcon</constant></para>
</listitem>
<listitem><para>Use sysfs before configuring an io driver</para>
<para>
<constant>echo 1 &gt; /sys/module/kgdb/parameters/kgdb_use_con</constant>
</para>
<para>
NOTE: If you do this after you configure the kgdb I/O driver, the
setting will not take effect until the next point the I/O is
reconfigured.
</para>
</listitem>
</orderedlist>
</para>
<para>
IMPORTANT NOTE: Using this option with kgdb over the console
(kgdboc) is not supported.
<sect1 id="kgdbcon">
<title>Kernel parameter: kgdbcon</title>
<para> The kgdbcon feature allows you to see printk() messages
inside gdb while gdb is connected to the kernel. Kdb does not make
use of the kgdbcon 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>
<listitem><para>Activate with the kernel command line option:</para>
<para><constant>kgdbcon</constant></para>
</listitem>
<listitem><para>Use sysfs before configuring an I/O driver</para>
<para>
<constant>echo 1 &gt; /sys/module/kgdb/parameters/kgdb_use_con</constant>
</para>
<para>
NOTE: If you do this after you configure the kgdb I/O driver, the
setting will not take effect until the next point the I/O is
reconfigured.
</para>
</listitem>
</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>
</sect1>
</chapter>
<chapter id="ConnectingGDB">
<title>Connecting gdb</title>
<chapter id="usingKDB">
<title>Using kdb</title>
<para>
</para>
<sect1 id="quickKDBserial">
<title>Quick start for kdb on a serial port</title>
<para>This is a quick example of how to use kdb.</para>
<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 &gt; /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 &gt; /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 &gt; /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 &gt; /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/&lt;driver&gt;/parameter/&lt;option&gt;</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 &gt; /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 &gt; /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>
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>
If you are not using different kgdb I/O driver other than kgdboc,
you should be able to connect and the target will automatically
respond.
</para>
<para>
Example (using a serial port):
Example (using a directly connected port):
</para>
<programlisting>
% gdb ./vmlinux
@@ -266,7 +531,7 @@
(gdb) target remote /dev/ttyS0
</programlisting>
<para>
Example (kgdb to a terminal server on tcp port 2012):
Example (kgdb to a terminal server on TCP port 2012):
</para>
<programlisting>
% gdb ./vmlinux
@@ -283,6 +548,83 @@
communications. You do this prior to issuing the <constant>target
remote</constant> command by typing in: <constant>set debug remote 1</constant>
</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 id="KGDBTestSuite">
<title>kgdb Test Suite</title>
@@ -309,34 +651,38 @@
</para>
</chapter>
<chapter id="CommonBackEndReq">
<title>KGDB Internals</title>
<title>Kernel Debugger Internals</title>
<sect1 id="kgdbArchitecture">
<title>Architecture Specifics</title>
<para>
Kgdb is organized into three basic components:
The kernel debugger is organized into a number of components:
<orderedlist>
<listitem><para>kgdb core</para>
<listitem><para>The debug core</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>
<listitem><para>All the logic to implement the gdb serial protocol</para></listitem>
<listitem><para>A generic OS exception handler which includes sync'ing the processors into a stopped state on an multi cpu system.</para></listitem>
<listitem><para>A generic OS exception handler which includes
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 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>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>
<listitem><para>The structures and callback API for atomic kernel mode setting.</para>
<para>NOTE: kgdboc is where the kms callbacks are invoked.</para></listitem>
</itemizedlist>
</para>
</listitem>
<listitem><para>kgdb arch specific implementation</para>
<listitem><para>kgdb arch-specific implementation</para>
<para>
This implementation is generally found in arch/*/kernel/kgdb.c.
As an example, arch/x86/kernel/kgdb.c contains the specifics to
implement HW breakpoint as well as the initialization to
dynamically register and unregister for the trap handlers on
this architecture. The arch specific portion implements:
this architecture. The arch-specific portion implements:
<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
work</para></listitem>
<listitem><para>translation to and from gdb specific packet format to pt_regs</para></listitem>
@@ -347,11 +693,46 @@
</itemizedlist>
</para>
</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>
<itemizedlist>
<listitem><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>For an example of how to dynamically register
a new kdb command you can build the kdb_hello.ko kernel module
from samples/kdb/kdb_hello.c. To build this example you can
set CONFIG_SAMPLES=y and CONFIG_SAMPLE_KDB=m in your kernel
config. Later run "modprobe kdb_hello" and the next time you
enter the kdb shell, you can run the "hello"
command.</para></listitem>
</itemizedlist></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>
<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>
<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>read and write character interface</para></listitem>
<listitem><para>A cleanup handler for unconfiguring from the kgdb core</para></listitem>
@@ -411,20 +792,19 @@
</sect1>
<sect1 id="kgdbocDesign">
<title>kgdboc internals</title>
<sect2>
<title>kgdboc and uarts</title>
<para>
The kgdboc driver is actually a very thin driver that relies on the
underlying low level to the hardware driver having "polling hooks"
which the to which the tty driver is attached. In the initial
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
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
certainly possible to extend kgdboc to work with non-uart based
consoles in the future.
</para>
request to the debugger, kgdboc invokes a callback in the serial
core which in turn uses the callback in the UART driver.</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
.poll_get_char = serial8250_get_poll_char,
.poll_put_char = serial8250_put_poll_char,
@@ -434,11 +814,70 @@
<constant>#ifdef CONFIG_CONSOLE_POLL</constant>, as shown above.
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
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
with any kind of lock you consider, because failing here is most
with any kind of lock you consider, because failing here is most likely
going to mean pressing the reset button.
</para>
</sect2>
<sect2 id="kgdbocKbd">
<title>kgdboc and keyboards</title>
<para>The kgdboc driver contains logic to configure communications
with an attached keyboard. The keyboard infrastructure is only
compiled into the kernel when CONFIG_KDB_KEYBOARD=y is set in the
kernel configuration.</para>
<para>The core polled keyboard driver driver for PS/2 type keyboards
is in drivers/char/kdb_keyboard.c. This driver is hooked into the
debug core when kgdboc populates the callback in the array
called <constant>kdb_poll_funcs[]</constant>. The
kdb_get_kbd_char() is the top-level function which polls hardware
for single character input.
</para>
</sect2>
<sect2 id="kgdbocKms">
<title>kgdboc and kms</title>
<para>The kgdboc driver contains logic to request the graphics
display to switch to a text context when you are using
"kgdboc=kms,kbd", provided that you have a video driver which has a
frame buffer console and atomic kernel mode setting support.</para>
<para>
Every time the kernel
debugger is entered it calls kgdboc_pre_exp_handler() which in turn
calls con_debug_enter() in the virtual console layer. On resuming kernel
execution, the kernel debugger calls kgdboc_post_exp_handler() which
in turn calls con_debug_leave().</para>
<para>Any video driver that wants to be compatible with the kernel
debugger and the atomic kms callbacks must implement the
mode_set_base_atomic, fb_debug_enter and fb_debug_leave operations.
For the fb_debug_enter and fb_debug_leave the option exists to use
the generic drm fb helper functions or implement something custom for
the hardware. The following example shows the initialization of the
.mode_set_base_atomic operation in
drivers/gpu/drm/i915/intel_display.c:
<informalexample>
<programlisting>
static const struct drm_crtc_helper_funcs intel_helper_funcs = {
[...]
.mode_set_base_atomic = intel_pipe_set_base_atomic,
[...]
};
</programlisting>
</informalexample>
</para>
<para>Here is an example of how the i915 driver initializes the fb_debug_enter and fb_debug_leave functions to use the generic drm helpers in
drivers/gpu/drm/i915/intel_fb.c:
<informalexample>
<programlisting>
static struct fb_ops intelfb_ops = {
[...]
.fb_debug_enter = drm_fb_helper_debug_enter,
.fb_debug_leave = drm_fb_helper_debug_leave,
[...]
};
</programlisting>
</informalexample>
</para>
</sect2>
</sect1>
</chapter>
<chapter id="credits">
@@ -453,6 +892,10 @@
<itemizedlist>
<listitem><para>Jason Wessel<email>jason.wessel@windriver.com</email></para></listitem>
</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>
</chapter>
</book>

View File

@@ -81,16 +81,14 @@ void (*port_disable) (struct ata_port *);
</programlisting>
<para>
Called from ata_bus_probe() and ata_bus_reset() error paths,
as well as when unregistering from the SCSI module (rmmod, hot
unplug).
Called from ata_bus_probe() error path, as well as when
unregistering from the SCSI module (rmmod, hot unplug).
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
as this hook.
</para>
<para>
Called from ata_bus_probe() on a failed probe.
Called from ata_bus_reset() on a failed bus reset.
Called from ata_scsi_release().
</para>
@@ -107,10 +105,6 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
issue of SET FEATURES - XFER MODE, and prior to operation.
</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.
</para>
@@ -154,8 +148,8 @@ unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned in
<sect2><title>Taskfile read/write</title>
<programlisting>
void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
void (*sff_tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
</programlisting>
<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
taskfile register values.
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>
</sect2>
<sect2><title>PIO data read/write</title>
<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>
<para>
All bmdma-style drivers must implement this hook. This is the low-level
operation that actually copies the data bytes during a PIO data
transfer.
Typically the driver
will choose one of ata_pio_data_xfer_noirq(), ata_pio_data_xfer(), or
ata_mmio_data_xfer().
Typically the driver will choose one of ata_sff_data_xfer_noirq(),
ata_sff_data_xfer(), or ata_sff_data_xfer32().
</para>
</sect2>
<sect2><title>ATA command execute</title>
<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>
<para>
causes an ATA command, previously loaded with
->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.
</para>
@@ -218,8 +211,8 @@ command.
<sect2><title>Read specific ATA shadow registers</title>
<programlisting>
u8 (*check_status)(struct ata_port *ap);
u8 (*check_altstatus)(struct ata_port *ap);
u8 (*sff_check_status)(struct ata_port *ap);
u8 (*sff_check_altstatus)(struct ata_port *ap);
</programlisting>
<para>
@@ -227,20 +220,26 @@ u8 (*check_altstatus)(struct ata_port *ap);
hardware. On some hardware, reading the Status register has
the side effect of clearing the interrupt condition.
Most drivers for taskfile-based hardware use
ata_check_status() for this hook.
ata_sff_check_status() for this hook.
</para>
</sect2>
<sect2><title>Write specific ATA shadow register</title>
<programlisting>
void (*sff_set_devctl)(struct ata_port *ap, u8 ctl);
</programlisting>
<para>
Note that because this is called from ata_device_add(), at
least a dummy function that clears device interrupts must be
provided for all drivers, even if the controller doesn't
actually have a taskfile status register.
Write the device control ATA shadow register to the hardware.
Most drivers don't need to define this.
</para>
</sect2>
<sect2><title>Select ATA device on bus</title>
<programlisting>
void (*dev_select)(struct ata_port *ap, unsigned int device);
void (*sff_dev_select)(struct ata_port *ap, unsigned int device);
</programlisting>
<para>
@@ -251,9 +250,7 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
</para>
<para>
Most drivers for taskfile-based hardware use
ata_std_dev_select() for this hook. Controllers which do not
support second drives on a port (such as SATA contollers) will
use ata_noop_dev_select().
ata_sff_dev_select() for this hook.
</para>
</sect2>
@@ -441,13 +438,13 @@ void (*irq_clear) (struct ata_port *);
to struct ata_host_set.
</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,
determines which queued command was active (if any), and calls
ata_host_intr(ap,qc).
ata_sff_host_intr(ap,qc).
</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
flags in the DMA status register.
</para>
@@ -490,16 +487,12 @@ void (*host_stop) (struct ata_host_set *host_set);
allocates space for a legacy IDE PRD table and returns.
</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
actively being used. Many drivers also free driver-private
data from port at this time.
</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
have completed. The hook must finalize hardware shutdown, release DMA
and other resources, etc.

View File

@@ -1,340 +0,0 @@
<?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="mac80211-developers-guide">
<bookinfo>
<title>The mac80211 subsystem for kernel developers</title>
<authorgroup>
<author>
<firstname>Johannes</firstname>
<surname>Berg</surname>
<affiliation>
<address><email>johannes@sipsolutions.net</email></address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2007-2009</year>
<holder>Johannes Berg</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License version 2 as published by the Free Software Foundation.
</para>
<para>
This documentation is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this documentation; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
<abstract>
!Pinclude/net/mac80211.h Introduction
!Pinclude/net/mac80211.h Warning
</abstract>
</bookinfo>
<toc></toc>
<!--
Generally, this document shall be ordered by increasing complexity.
It is important to note that readers should be able to read only
the first few sections to get a working driver and only advanced
usage should require reading the full document.
-->
<part>
<title>The basic mac80211 driver interface</title>
<partintro>
<para>
You should read and understand the information contained
within this part of the book while implementing a driver.
In some chapters, advanced usage is noted, that may be
skipped at first.
</para>
<para>
This part of the book only covers station and monitor mode
functionality, additional information required to implement
the other modes is covered in the second part of the book.
</para>
</partintro>
<chapter id="basics">
<title>Basic hardware handling</title>
<para>TBD</para>
<para>
This chapter shall contain information on getting a hw
struct allocated and registered with mac80211.
</para>
<para>
Since it is required to allocate rates/modes before registering
a hw struct, this chapter shall also contain information on setting
up the rate/mode structs.
</para>
<para>
Additionally, some discussion about the callbacks and
the general programming model should be in here, including
the definition of ieee80211_ops which will be referred to
a lot.
</para>
<para>
Finally, a discussion of hardware capabilities should be done
with references to other parts of the book.
</para>
<!-- intentionally multiple !F lines to get proper order -->
!Finclude/net/mac80211.h ieee80211_hw
!Finclude/net/mac80211.h ieee80211_hw_flags
!Finclude/net/mac80211.h SET_IEEE80211_DEV
!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR
!Finclude/net/mac80211.h ieee80211_ops
!Finclude/net/mac80211.h ieee80211_alloc_hw
!Finclude/net/mac80211.h ieee80211_register_hw
!Finclude/net/mac80211.h ieee80211_get_tx_led_name
!Finclude/net/mac80211.h ieee80211_get_rx_led_name
!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
!Finclude/net/mac80211.h ieee80211_get_radio_led_name
!Finclude/net/mac80211.h ieee80211_unregister_hw
!Finclude/net/mac80211.h ieee80211_free_hw
</chapter>
<chapter id="phy-handling">
<title>PHY configuration</title>
<para>TBD</para>
<para>
This chapter should describe PHY handling including
start/stop callbacks and the various structures used.
</para>
!Finclude/net/mac80211.h ieee80211_conf
!Finclude/net/mac80211.h ieee80211_conf_flags
</chapter>
<chapter id="iface-handling">
<title>Virtual interfaces</title>
<para>TBD</para>
<para>
This chapter should describe virtual interface basics
that are relevant to the driver (VLANs, MGMT etc are not.)
It should explain the use of the add_iface/remove_iface
callbacks as well as the interface configuration callbacks.
</para>
<para>Things related to AP mode should be discussed there.</para>
<para>
Things related to supporting multiple interfaces should be
in the appropriate chapter, a BIG FAT note should be here about
this though and the recommendation to allow only a single
interface in STA mode at first!
</para>
!Finclude/net/mac80211.h ieee80211_if_init_conf
</chapter>
<chapter id="rx-tx">
<title>Receive and transmit processing</title>
<sect1>
<title>what should be here</title>
<para>TBD</para>
<para>
This should describe the receive and transmit
paths in mac80211/the drivers as well as
transmit status handling.
</para>
</sect1>
<sect1>
<title>Frame format</title>
!Pinclude/net/mac80211.h Frame format
</sect1>
<sect1>
<title>Packet alignment</title>
!Pnet/mac80211/rx.c Packet alignment
</sect1>
<sect1>
<title>Calling into mac80211 from interrupts</title>
!Pinclude/net/mac80211.h Calling mac80211 from interrupts
</sect1>
<sect1>
<title>functions/definitions</title>
!Finclude/net/mac80211.h ieee80211_rx_status
!Finclude/net/mac80211.h mac80211_rx_flags
!Finclude/net/mac80211.h ieee80211_tx_info
!Finclude/net/mac80211.h ieee80211_rx
!Finclude/net/mac80211.h ieee80211_rx_irqsafe
!Finclude/net/mac80211.h ieee80211_tx_status
!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe
!Finclude/net/mac80211.h ieee80211_rts_get
!Finclude/net/mac80211.h ieee80211_rts_duration
!Finclude/net/mac80211.h ieee80211_ctstoself_get
!Finclude/net/mac80211.h ieee80211_ctstoself_duration
!Finclude/net/mac80211.h ieee80211_generic_frame_duration
!Finclude/net/mac80211.h ieee80211_get_hdrlen_from_skb
!Finclude/net/mac80211.h ieee80211_hdrlen
!Finclude/net/mac80211.h ieee80211_wake_queue
!Finclude/net/mac80211.h ieee80211_stop_queue
!Finclude/net/mac80211.h ieee80211_wake_queues
!Finclude/net/mac80211.h ieee80211_stop_queues
</sect1>
</chapter>
<chapter id="filters">
<title>Frame filtering</title>
!Pinclude/net/mac80211.h Frame filtering
!Finclude/net/mac80211.h ieee80211_filter_flags
</chapter>
</part>
<part id="advanced">
<title>Advanced driver interface</title>
<partintro>
<para>
Information contained within this part of the book is
of interest only for advanced interaction of mac80211
with drivers to exploit more hardware capabilities and
improve performance.
</para>
</partintro>
<chapter id="hardware-crypto-offload">
<title>Hardware crypto acceleration</title>
!Pinclude/net/mac80211.h Hardware crypto acceleration
<!-- intentionally multiple !F lines to get proper order -->
!Finclude/net/mac80211.h set_key_cmd
!Finclude/net/mac80211.h ieee80211_key_conf
!Finclude/net/mac80211.h ieee80211_key_alg
!Finclude/net/mac80211.h ieee80211_key_flags
</chapter>
<chapter id="powersave">
<title>Powersave support</title>
!Pinclude/net/mac80211.h Powersave support
</chapter>
<chapter id="beacon-filter">
<title>Beacon filter support</title>
!Pinclude/net/mac80211.h Beacon filter support
!Finclude/net/mac80211.h ieee80211_beacon_loss
</chapter>
<chapter id="qos">
<title>Multiple queues and QoS support</title>
<para>TBD</para>
!Finclude/net/mac80211.h ieee80211_tx_queue_params
!Finclude/net/mac80211.h ieee80211_tx_queue_stats
</chapter>
<chapter id="AP">
<title>Access point mode support</title>
<para>TBD</para>
<para>Some parts of the if_conf should be discussed here instead</para>
<para>
Insert notes about VLAN interfaces with hw crypto here or
in the hw crypto chapter.
</para>
!Finclude/net/mac80211.h ieee80211_get_buffered_bc
!Finclude/net/mac80211.h ieee80211_beacon_get
</chapter>
<chapter id="multi-iface">
<title>Supporting multiple virtual interfaces</title>
<para>TBD</para>
<para>
Note: WDS with identical MAC address should almost always be OK
</para>
<para>
Insert notes about having multiple virtual interfaces with
different MAC addresses here, note which configurations are
supported by mac80211, add notes about supporting hw crypto
with it.
</para>
</chapter>
<chapter id="hardware-scan-offload">
<title>Hardware scan offload</title>
<para>TBD</para>
!Finclude/net/mac80211.h ieee80211_scan_completed
</chapter>
</part>
<part id="rate-control">
<title>Rate control interface</title>
<partintro>
<para>TBD</para>
<para>
This part of the book describes the rate control algorithm
interface and how it relates to mac80211 and drivers.
</para>
</partintro>
<chapter id="dummy">
<title>dummy chapter</title>
<para>TBD</para>
</chapter>
</part>
<part id="internal">
<title>Internals</title>
<partintro>
<para>TBD</para>
<para>
This part of the book describes mac80211 internals.
</para>
</partintro>
<chapter id="key-handling">
<title>Key handling</title>
<sect1>
<title>Key handling basics</title>
!Pnet/mac80211/key.c Key handling basics
</sect1>
<sect1>
<title>MORE TBD</title>
<para>TBD</para>
</sect1>
</chapter>
<chapter id="rx-processing">
<title>Receive processing</title>
<para>TBD</para>
</chapter>
<chapter id="tx-processing">
<title>Transmit processing</title>
<para>TBD</para>
</chapter>
<chapter id="sta-info">
<title>Station info handling</title>
<sect1>
<title>Programming information</title>
!Fnet/mac80211/sta_info.h sta_info
!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags
</sect1>
<sect1>
<title>STA information lifetime rules</title>
!Pnet/mac80211/sta_info.c STA information lifetime rules
</sect1>
</chapter>
<chapter id="synchronisation">
<title>Synchronisation</title>
<para>TBD</para>
<para>Locking, lots of RCU</para>
</chapter>
</part>
</book>

View File

@@ -0,0 +1,401 @@
<!-- Generated file! Do not edit. -->
<!-- Functions -->
<!ENTITY func-close "<link linkend='func-close'><function>close()</function></link>">
<!ENTITY func-ioctl "<link linkend='func-ioctl'><function>ioctl()</function></link>">
<!ENTITY func-mmap "<link linkend='func-mmap'><function>mmap()</function></link>">
<!ENTITY func-munmap "<link linkend='func-munmap'><function>munmap()</function></link>">
<!ENTITY func-open "<link linkend='func-open'><function>open()</function></link>">
<!ENTITY func-poll "<link linkend='func-poll'><function>poll()</function></link>">
<!ENTITY func-read "<link linkend='func-read'><function>read()</function></link>">
<!ENTITY func-select "<link linkend='func-select'><function>select()</function></link>">
<!ENTITY func-write "<link linkend='func-write'><function>write()</function></link>">
<!-- Ioctls -->
<!ENTITY VIDIOC-CROPCAP "<link linkend='vidioc-cropcap'><constant>VIDIOC_CROPCAP</constant></link>">
<!ENTITY VIDIOC-DBG-G-CHIP-IDENT "<link linkend='vidioc-dbg-g-chip-ident'><constant>VIDIOC_DBG_G_CHIP_IDENT</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-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-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>">
<!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>">
<!ENTITY VIDIOC-ENUMINPUT "<link linkend='vidioc-enuminput'><constant>VIDIOC_ENUMINPUT</constant></link>">
<!ENTITY VIDIOC-ENUMOUTPUT "<link linkend='vidioc-enumoutput'><constant>VIDIOC_ENUMOUTPUT</constant></link>">
<!ENTITY VIDIOC-ENUMSTD "<link linkend='vidioc-enumstd'><constant>VIDIOC_ENUMSTD</constant></link>">
<!ENTITY VIDIOC-ENUM-DV-PRESETS "<link linkend='vidioc-enum-dv-presets'><constant>VIDIOC_ENUM_DV_PRESETS</constant></link>">
<!ENTITY VIDIOC-ENUM-FMT "<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>">
<!ENTITY VIDIOC-ENUM-FRAMEINTERVALS "<link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>">
<!ENTITY VIDIOC-ENUM-FRAMESIZES "<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>">
<!ENTITY VIDIOC-G-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_G_AUDIO</constant></link>">
<!ENTITY VIDIOC-G-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_G_AUDOUT</constant></link>">
<!ENTITY VIDIOC-G-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_G_CROP</constant></link>">
<!ENTITY VIDIOC-G-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_G_CTRL</constant></link>">
<!ENTITY VIDIOC-G-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_G_DV_PRESET</constant></link>">
<!ENTITY VIDIOC-G-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_G_DV_TIMINGS</constant></link>">
<!ENTITY VIDIOC-G-ENC-INDEX "<link linkend='vidioc-g-enc-index'><constant>VIDIOC_G_ENC_INDEX</constant></link>">
<!ENTITY VIDIOC-G-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_G_EXT_CTRLS</constant></link>">
<!ENTITY VIDIOC-G-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_G_FBUF</constant></link>">
<!ENTITY VIDIOC-G-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_G_FMT</constant></link>">
<!ENTITY VIDIOC-G-FREQUENCY "<link linkend='vidioc-g-frequency'><constant>VIDIOC_G_FREQUENCY</constant></link>">
<!ENTITY VIDIOC-G-INPUT "<link linkend='vidioc-g-input'><constant>VIDIOC_G_INPUT</constant></link>">
<!ENTITY VIDIOC-G-JPEGCOMP "<link linkend='vidioc-g-jpegcomp'><constant>VIDIOC_G_JPEGCOMP</constant></link>">
<!ENTITY VIDIOC-G-MPEGCOMP "<link linkend=''><constant>VIDIOC_G_MPEGCOMP</constant></link>">
<!ENTITY VIDIOC-G-MODULATOR "<link linkend='vidioc-g-modulator'><constant>VIDIOC_G_MODULATOR</constant></link>">
<!ENTITY VIDIOC-G-OUTPUT "<link linkend='vidioc-g-output'><constant>VIDIOC_G_OUTPUT</constant></link>">
<!ENTITY VIDIOC-G-PARM "<link linkend='vidioc-g-parm'><constant>VIDIOC_G_PARM</constant></link>">
<!ENTITY VIDIOC-G-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_G_PRIORITY</constant></link>">
<!ENTITY VIDIOC-G-SLICED-VBI-CAP "<link linkend='vidioc-g-sliced-vbi-cap'><constant>VIDIOC_G_SLICED_VBI_CAP</constant></link>">
<!ENTITY VIDIOC-G-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_G_STD</constant></link>">
<!ENTITY VIDIOC-G-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_G_TUNER</constant></link>">
<!ENTITY VIDIOC-LOG-STATUS "<link linkend='vidioc-log-status'><constant>VIDIOC_LOG_STATUS</constant></link>">
<!ENTITY VIDIOC-OVERLAY "<link linkend='vidioc-overlay'><constant>VIDIOC_OVERLAY</constant></link>">
<!ENTITY VIDIOC-QBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_QBUF</constant></link>">
<!ENTITY VIDIOC-QUERYBUF "<link linkend='vidioc-querybuf'><constant>VIDIOC_QUERYBUF</constant></link>">
<!ENTITY VIDIOC-QUERYCAP "<link linkend='vidioc-querycap'><constant>VIDIOC_QUERYCAP</constant></link>">
<!ENTITY VIDIOC-QUERYCTRL "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYCTRL</constant></link>">
<!ENTITY VIDIOC-QUERYMENU "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYMENU</constant></link>">
<!ENTITY VIDIOC-QUERYSTD "<link linkend='vidioc-querystd'><constant>VIDIOC_QUERYSTD</constant></link>">
<!ENTITY VIDIOC-QUERY-DV-PRESET "<link linkend='vidioc-query-dv-preset'><constant>VIDIOC_QUERY_DV_PRESET</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-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-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-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_S_CTRL</constant></link>">
<!ENTITY VIDIOC-S-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_S_DV_PRESET</constant></link>">
<!ENTITY VIDIOC-S-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_S_DV_TIMINGS</constant></link>">
<!ENTITY VIDIOC-S-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_S_EXT_CTRLS</constant></link>">
<!ENTITY VIDIOC-S-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_S_FBUF</constant></link>">
<!ENTITY VIDIOC-S-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>">
<!ENTITY VIDIOC-S-FREQUENCY "<link linkend='vidioc-g-frequency'><constant>VIDIOC_S_FREQUENCY</constant></link>">
<!ENTITY VIDIOC-S-HW-FREQ-SEEK "<link linkend='vidioc-s-hw-freq-seek'><constant>VIDIOC_S_HW_FREQ_SEEK</constant></link>">
<!ENTITY VIDIOC-S-INPUT "<link linkend='vidioc-g-input'><constant>VIDIOC_S_INPUT</constant></link>">
<!ENTITY VIDIOC-S-JPEGCOMP "<link linkend='vidioc-g-jpegcomp'><constant>VIDIOC_S_JPEGCOMP</constant></link>">
<!ENTITY VIDIOC-S-MPEGCOMP "<link linkend=''><constant>VIDIOC_S_MPEGCOMP</constant></link>">
<!ENTITY VIDIOC-S-MODULATOR "<link linkend='vidioc-g-modulator'><constant>VIDIOC_S_MODULATOR</constant></link>">
<!ENTITY VIDIOC-S-OUTPUT "<link linkend='vidioc-g-output'><constant>VIDIOC_S_OUTPUT</constant></link>">
<!ENTITY VIDIOC-S-PARM "<link linkend='vidioc-g-parm'><constant>VIDIOC_S_PARM</constant></link>">
<!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>">
<!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>">
<!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</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-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 -->
<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
<!-- Enums -->
<!ENTITY v4l2-buf-type "enum&nbsp;<link linkend='v4l2-buf-type'>v4l2_buf_type</link>">
<!ENTITY v4l2-colorspace "enum&nbsp;<link linkend='v4l2-colorspace'>v4l2_colorspace</link>">
<!ENTITY v4l2-ctrl-type "enum&nbsp;<link linkend='v4l2-ctrl-type'>v4l2_ctrl_type</link>">
<!ENTITY v4l2-exposure-auto-type "enum&nbsp;<link linkend='v4l2-exposure-auto-type'>v4l2_exposure_auto_type</link>">
<!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>">
<!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>">
<!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>">
<!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>">
<!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>">
<!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>">
<!ENTITY v4l2-mpeg-audio-emphasis "enum&nbsp;<link linkend='v4l2-mpeg-audio-emphasis'>v4l2_mpeg_audio_emphasis</link>">
<!ENTITY v4l2-mpeg-audio-encoding "enum&nbsp;<link linkend='v4l2-mpeg-audio-encoding'>v4l2_mpeg_audio_encoding</link>">
<!ENTITY v4l2-mpeg-audio-l1-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l1-bitrate'>v4l2_mpeg_audio_l1_bitrate</link>">
<!ENTITY v4l2-mpeg-audio-l2-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l2-bitrate'>v4l2_mpeg_audio_l2_bitrate</link>">
<!ENTITY v4l2-mpeg-audio-l3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l3-bitrate'>v4l2_mpeg_audio_l3_bitrate</link>">
<!ENTITY v4l2-mpeg-audio-mode "enum&nbsp;<link linkend='v4l2-mpeg-audio-mode'>v4l2_mpeg_audio_mode</link>">
<!ENTITY v4l2-mpeg-audio-mode-extension "enum&nbsp;<link linkend='v4l2-mpeg-audio-mode-extension'>v4l2_mpeg_audio_mode_extension</link>">
<!ENTITY v4l2-mpeg-audio-sampling-freq "enum&nbsp;<link linkend='v4l2-mpeg-audio-sampling-freq'>v4l2_mpeg_audio_sampling_freq</link>">
<!ENTITY chroma-spatial-filter-type "enum&nbsp;<link linkend='chroma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</link>">
<!ENTITY luma-spatial-filter-type "enum&nbsp;<link linkend='luma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</link>">
<!ENTITY v4l2-mpeg-cx2341x-video-median-filter-type "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-median-filter-type'>v4l2_mpeg_cx2341x_video_median_filter_type</link>">
<!ENTITY v4l2-mpeg-cx2341x-video-spatial-filter-mode "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-spatial-filter-mode'>v4l2_mpeg_cx2341x_video_spatial_filter_mode</link>">
<!ENTITY v4l2-mpeg-cx2341x-video-temporal-filter-mode "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-temporal-filter-mode'>v4l2_mpeg_cx2341x_video_temporal_filter_mode</link>">
<!ENTITY v4l2-mpeg-stream-type "enum&nbsp;<link linkend='v4l2-mpeg-stream-type'>v4l2_mpeg_stream_type</link>">
<!ENTITY v4l2-mpeg-stream-vbi-fmt "enum&nbsp;<link linkend='v4l2-mpeg-stream-vbi-fmt'>v4l2_mpeg_stream_vbi_fmt</link>">
<!ENTITY v4l2-mpeg-video-aspect "enum&nbsp;<link linkend='v4l2-mpeg-video-aspect'>v4l2_mpeg_video_aspect</link>">
<!ENTITY v4l2-mpeg-video-bitrate-mode "enum&nbsp;<link linkend='v4l2-mpeg-video-bitrate-mode'>v4l2_mpeg_video_bitrate_mode</link>">
<!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>">
<!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>">
<!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>">
<!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>">
<!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>">
<!-- Structures -->
<!ENTITY v4l2-audio "struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link>">
<!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>">
<!ENTITY v4l2-bt-timings "struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>">
<!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>">
<!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>">
<!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
<!ENTITY v4l2-clip "struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link>">
<!ENTITY v4l2-control "struct&nbsp;<link linkend='v4l2-control'>v4l2_control</link>">
<!ENTITY v4l2-crop "struct&nbsp;<link linkend='v4l2-crop'>v4l2_crop</link>">
<!ENTITY v4l2-cropcap "struct&nbsp;<link linkend='v4l2-cropcap'>v4l2_cropcap</link>">
<!ENTITY v4l2-dbg-chip-ident "struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link>">
<!ENTITY v4l2-dbg-match "struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link>">
<!ENTITY v4l2-dbg-register "struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link>">
<!ENTITY v4l2-dv-enum-preset "struct&nbsp;<link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link>">
<!ENTITY v4l2-dv-preset "struct&nbsp;<link linkend='v4l2-dv-preset'>v4l2_dv_preset</link>">
<!ENTITY v4l2-dv-timings "struct&nbsp;<link linkend='v4l2-dv-timings'>v4l2_dv_timings</link>">
<!ENTITY v4l2-enc-idx "struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
<!ENTITY v4l2-enc-idx-entry "struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
<!ENTITY v4l2-encoder-cmd "struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
<!ENTITY v4l2-event "struct&nbsp;<link linkend='v4l2-event'>v4l2_event</link>">
<!ENTITY v4l2-event-subscription "struct&nbsp;<link linkend='v4l2-event-subscription'>v4l2_event_subscription</link>">
<!ENTITY v4l2-event-vsync "struct&nbsp;<link linkend='v4l2-event-vsync'>v4l2_event_vsync</link>">
<!ENTITY v4l2-ext-control "struct&nbsp;<link linkend='v4l2-ext-control'>v4l2_ext_control</link>">
<!ENTITY v4l2-ext-controls "struct&nbsp;<link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>">
<!ENTITY v4l2-fmtdesc "struct&nbsp;<link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>">
<!ENTITY v4l2-format "struct&nbsp;<link linkend='v4l2-format'>v4l2_format</link>">
<!ENTITY v4l2-fract "struct&nbsp;<link linkend='v4l2-fract'>v4l2_fract</link>">
<!ENTITY v4l2-framebuffer "struct&nbsp;<link linkend='v4l2-framebuffer'>v4l2_framebuffer</link>">
<!ENTITY v4l2-frequency "struct&nbsp;<link linkend='v4l2-frequency'>v4l2_frequency</link>">
<!ENTITY v4l2-frmival-stepwise "struct&nbsp;<link linkend='v4l2-frmival-stepwise'>v4l2_frmival_stepwise</link>">
<!ENTITY v4l2-frmivalenum "struct&nbsp;<link linkend='v4l2-frmivalenum'>v4l2_frmivalenum</link>">
<!ENTITY v4l2-frmsize-discrete "struct&nbsp;<link linkend='v4l2-frmsize-discrete'>v4l2_frmsize_discrete</link>">
<!ENTITY v4l2-frmsize-stepwise "struct&nbsp;<link linkend='v4l2-frmsize-stepwise'>v4l2_frmsize_stepwise</link>">
<!ENTITY v4l2-frmsizeenum "struct&nbsp;<link linkend='v4l2-frmsizeenum'>v4l2_frmsizeenum</link>">
<!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>">
<!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>">
<!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>">
<!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>">
<!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>">
<!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>">
<!ENTITY v4l2-outputparm "struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link>">
<!ENTITY v4l2-pix-format "struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link>">
<!ENTITY v4l2-queryctrl "struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>">
<!ENTITY v4l2-querymenu "struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link>">
<!ENTITY v4l2-rect "struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link>">
<!ENTITY v4l2-requestbuffers "struct&nbsp;<link linkend='v4l2-requestbuffers'>v4l2_requestbuffers</link>">
<!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>">
<!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>">
<!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>">
<!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
<!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>">
<!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>">
<!ENTITY v4l2-tuner "struct&nbsp;<link linkend='v4l2-tuner'>v4l2_tuner</link>">
<!ENTITY v4l2-vbi-format "struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>">
<!ENTITY v4l2-window "struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link>">
<!-- Error Codes -->
<!ENTITY EACCES "<errorcode>EACCES</errorcode> error code">
<!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code">
<!ENTITY EBADF "<errorcode>EBADF</errorcode> error code">
<!ENTITY EBUSY "<errorcode>EBUSY</errorcode> error code">
<!ENTITY EFAULT "<errorcode>EFAULT</errorcode> error code">
<!ENTITY EIO "<errorcode>EIO</errorcode> error code">
<!ENTITY EINTR "<errorcode>EINTR</errorcode> error code">
<!ENTITY EINVAL "<errorcode>EINVAL</errorcode> error code">
<!ENTITY ENFILE "<errorcode>ENFILE</errorcode> error code">
<!ENTITY ENOMEM "<errorcode>ENOMEM</errorcode> error code">
<!ENTITY ENOSPC "<errorcode>ENOSPC</errorcode> error code">
<!ENTITY ENOTTY "<errorcode>ENOTTY</errorcode> error code">
<!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code">
<!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code">
<!ENTITY EPERM "<errorcode>EPERM</errorcode> error code">
<!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code">
<!-- Subsections -->
<!ENTITY sub-biblio SYSTEM "v4l/biblio.xml">
<!ENTITY sub-common SYSTEM "v4l/common.xml">
<!ENTITY sub-compat SYSTEM "v4l/compat.xml">
<!ENTITY sub-controls SYSTEM "v4l/controls.xml">
<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.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-osd SYSTEM "v4l/dev-osd.xml">
<!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml">
<!ENTITY sub-dev-overlay SYSTEM "v4l/dev-overlay.xml">
<!ENTITY sub-dev-radio SYSTEM "v4l/dev-radio.xml">
<!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml">
<!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml">
<!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml">
<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
<!ENTITY sub-driver SYSTEM "v4l/driver.xml">
<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
<!ENTITY sub-lirc_device_interface SYSTEM "v4l/lirc_device_interface.xml">
<!ENTITY sub-remote_controllers SYSTEM "v4l/remote_controllers.xml">
<!ENTITY sub-fdl-appendix SYSTEM "v4l/fdl-appendix.xml">
<!ENTITY sub-close SYSTEM "v4l/func-close.xml">
<!ENTITY sub-ioctl SYSTEM "v4l/func-ioctl.xml">
<!ENTITY sub-mmap SYSTEM "v4l/func-mmap.xml">
<!ENTITY sub-munmap SYSTEM "v4l/func-munmap.xml">
<!ENTITY sub-open SYSTEM "v4l/func-open.xml">
<!ENTITY sub-poll SYSTEM "v4l/func-poll.xml">
<!ENTITY sub-read SYSTEM "v4l/func-read.xml">
<!ENTITY sub-select SYSTEM "v4l/func-select.xml">
<!ENTITY sub-write SYSTEM "v4l/func-write.xml">
<!ENTITY sub-io SYSTEM "v4l/io.xml">
<!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml">
<!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml">
<!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml">
<!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
<!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
<!ENTITY sub-sbggr16 SYSTEM "v4l/pixfmt-sbggr16.xml">
<!ENTITY sub-sbggr8 SYSTEM "v4l/pixfmt-sbggr8.xml">
<!ENTITY sub-sgbrg8 SYSTEM "v4l/pixfmt-sgbrg8.xml">
<!ENTITY sub-sgrbg8 SYSTEM "v4l/pixfmt-sgrbg8.xml">
<!ENTITY sub-uyvy SYSTEM "v4l/pixfmt-uyvy.xml">
<!ENTITY sub-vyuy SYSTEM "v4l/pixfmt-vyuy.xml">
<!ENTITY sub-y16 SYSTEM "v4l/pixfmt-y16.xml">
<!ENTITY sub-y41p SYSTEM "v4l/pixfmt-y41p.xml">
<!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
<!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
<!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
<!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
<!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
<!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
<!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml">
<!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
<!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.xml">
<!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml">
<!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
<!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
<!ENTITY sub-encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml">
<!ENTITY sub-enum-fmt SYSTEM "v4l/vidioc-enum-fmt.xml">
<!ENTITY sub-enum-frameintervals SYSTEM "v4l/vidioc-enum-frameintervals.xml">
<!ENTITY sub-enum-framesizes SYSTEM "v4l/vidioc-enum-framesizes.xml">
<!ENTITY sub-enumaudio SYSTEM "v4l/vidioc-enumaudio.xml">
<!ENTITY sub-enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
<!ENTITY sub-enuminput SYSTEM "v4l/vidioc-enuminput.xml">
<!ENTITY sub-enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
<!ENTITY sub-enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml">
<!ENTITY sub-g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml">
<!ENTITY sub-query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml">
<!ENTITY sub-g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml">
<!ENTITY sub-enumstd SYSTEM "v4l/vidioc-enumstd.xml">
<!ENTITY sub-g-audio SYSTEM "v4l/vidioc-g-audio.xml">
<!ENTITY sub-g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
<!ENTITY sub-dbg-g-chip-ident SYSTEM "v4l/vidioc-dbg-g-chip-ident.xml">
<!ENTITY sub-g-crop SYSTEM "v4l/vidioc-g-crop.xml">
<!ENTITY sub-g-ctrl SYSTEM "v4l/vidioc-g-ctrl.xml">
<!ENTITY sub-g-enc-index SYSTEM "v4l/vidioc-g-enc-index.xml">
<!ENTITY sub-g-ext-ctrls SYSTEM "v4l/vidioc-g-ext-ctrls.xml">
<!ENTITY sub-g-fbuf SYSTEM "v4l/vidioc-g-fbuf.xml">
<!ENTITY sub-g-fmt SYSTEM "v4l/vidioc-g-fmt.xml">
<!ENTITY sub-g-frequency SYSTEM "v4l/vidioc-g-frequency.xml">
<!ENTITY sub-g-input SYSTEM "v4l/vidioc-g-input.xml">
<!ENTITY sub-g-jpegcomp SYSTEM "v4l/vidioc-g-jpegcomp.xml">
<!ENTITY sub-g-modulator SYSTEM "v4l/vidioc-g-modulator.xml">
<!ENTITY sub-g-output SYSTEM "v4l/vidioc-g-output.xml">
<!ENTITY sub-g-parm SYSTEM "v4l/vidioc-g-parm.xml">
<!ENTITY sub-g-priority SYSTEM "v4l/vidioc-g-priority.xml">
<!ENTITY sub-g-sliced-vbi-cap SYSTEM "v4l/vidioc-g-sliced-vbi-cap.xml">
<!ENTITY sub-g-std SYSTEM "v4l/vidioc-g-std.xml">
<!ENTITY sub-g-tuner SYSTEM "v4l/vidioc-g-tuner.xml">
<!ENTITY sub-log-status SYSTEM "v4l/vidioc-log-status.xml">
<!ENTITY sub-overlay SYSTEM "v4l/vidioc-overlay.xml">
<!ENTITY sub-qbuf SYSTEM "v4l/vidioc-qbuf.xml">
<!ENTITY sub-querybuf SYSTEM "v4l/vidioc-querybuf.xml">
<!ENTITY sub-querycap SYSTEM "v4l/vidioc-querycap.xml">
<!ENTITY sub-queryctrl SYSTEM "v4l/vidioc-queryctrl.xml">
<!ENTITY sub-querystd SYSTEM "v4l/vidioc-querystd.xml">
<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
<!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
<!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml">
<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml">
<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
<!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.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-frontend SYSTEM "dvb/frontend.xml">
<!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">
<!ENTITY sub-demux SYSTEM "dvb/demux.xml">
<!ENTITY sub-video SYSTEM "dvb/video.xml">
<!ENTITY sub-audio SYSTEM "dvb/audio.xml">
<!ENTITY sub-ca SYSTEM "dvb/ca.xml">
<!ENTITY sub-net SYSTEM "dvb/net.xml">
<!ENTITY sub-kdapi SYSTEM "dvb/kdapi.xml">
<!ENTITY sub-examples SYSTEM "dvb/examples.xml">
<!ENTITY sub-frontend-h SYSTEM "dvb/frontend.h.xml">
<!ENTITY sub-dvbapi SYSTEM "dvb/dvbapi.xml">
<!ENTITY sub-media SYSTEM "media.xml">
<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
<!ENTITY sub-media-indices SYSTEM "media-indices.tmpl">
<!-- Function Reference -->
<!ENTITY close SYSTEM "v4l/func-close.xml">
<!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml">
<!ENTITY mmap SYSTEM "v4l/func-mmap.xml">
<!ENTITY munmap SYSTEM "v4l/func-munmap.xml">
<!ENTITY open SYSTEM "v4l/func-open.xml">
<!ENTITY poll SYSTEM "v4l/func-poll.xml">
<!ENTITY read SYSTEM "v4l/func-read.xml">
<!ENTITY select SYSTEM "v4l/func-select.xml">
<!ENTITY write SYSTEM "v4l/func-write.xml">
<!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml">
<!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml">
<!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml">
<!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
<!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
<!ENTITY sbggr16 SYSTEM "v4l/pixfmt-sbggr16.xml">
<!ENTITY sbggr8 SYSTEM "v4l/pixfmt-sbggr8.xml">
<!ENTITY sgbrg8 SYSTEM "v4l/pixfmt-sgbrg8.xml">
<!ENTITY sgrbg8 SYSTEM "v4l/pixfmt-sgrbg8.xml">
<!ENTITY uyvy SYSTEM "v4l/pixfmt-uyvy.xml">
<!ENTITY vyuy SYSTEM "v4l/pixfmt-vyuy.xml">
<!ENTITY y16 SYSTEM "v4l/pixfmt-y16.xml">
<!ENTITY y41p SYSTEM "v4l/pixfmt-y41p.xml">
<!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
<!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
<!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
<!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
<!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
<!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
<!ENTITY srggb10 SYSTEM "v4l/pixfmt-srggb10.xml">
<!ENTITY srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
<!ENTITY y10 SYSTEM "v4l/pixfmt-y10.xml">
<!ENTITY cropcap SYSTEM "v4l/vidioc-cropcap.xml">
<!ENTITY dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
<!ENTITY encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml">
<!ENTITY enum-fmt SYSTEM "v4l/vidioc-enum-fmt.xml">
<!ENTITY enum-frameintervals SYSTEM "v4l/vidioc-enum-frameintervals.xml">
<!ENTITY enum-framesizes SYSTEM "v4l/vidioc-enum-framesizes.xml">
<!ENTITY enumaudio SYSTEM "v4l/vidioc-enumaudio.xml">
<!ENTITY enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
<!ENTITY enuminput SYSTEM "v4l/vidioc-enuminput.xml">
<!ENTITY enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
<!ENTITY enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml">
<!ENTITY g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml">
<!ENTITY query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml">
<!ENTITY g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml">
<!ENTITY enumstd SYSTEM "v4l/vidioc-enumstd.xml">
<!ENTITY g-audio SYSTEM "v4l/vidioc-g-audio.xml">
<!ENTITY g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
<!ENTITY dbg-g-chip-ident SYSTEM "v4l/vidioc-dbg-g-chip-ident.xml">
<!ENTITY g-crop SYSTEM "v4l/vidioc-g-crop.xml">
<!ENTITY g-ctrl SYSTEM "v4l/vidioc-g-ctrl.xml">
<!ENTITY g-enc-index SYSTEM "v4l/vidioc-g-enc-index.xml">
<!ENTITY g-ext-ctrls SYSTEM "v4l/vidioc-g-ext-ctrls.xml">
<!ENTITY g-fbuf SYSTEM "v4l/vidioc-g-fbuf.xml">
<!ENTITY g-fmt SYSTEM "v4l/vidioc-g-fmt.xml">
<!ENTITY g-frequency SYSTEM "v4l/vidioc-g-frequency.xml">
<!ENTITY g-input SYSTEM "v4l/vidioc-g-input.xml">
<!ENTITY g-jpegcomp SYSTEM "v4l/vidioc-g-jpegcomp.xml">
<!ENTITY g-modulator SYSTEM "v4l/vidioc-g-modulator.xml">
<!ENTITY g-output SYSTEM "v4l/vidioc-g-output.xml">
<!ENTITY g-parm SYSTEM "v4l/vidioc-g-parm.xml">
<!ENTITY g-priority SYSTEM "v4l/vidioc-g-priority.xml">
<!ENTITY g-sliced-vbi-cap SYSTEM "v4l/vidioc-g-sliced-vbi-cap.xml">
<!ENTITY g-std SYSTEM "v4l/vidioc-g-std.xml">
<!ENTITY g-tuner SYSTEM "v4l/vidioc-g-tuner.xml">
<!ENTITY log-status SYSTEM "v4l/vidioc-log-status.xml">
<!ENTITY overlay SYSTEM "v4l/vidioc-overlay.xml">
<!ENTITY qbuf SYSTEM "v4l/vidioc-qbuf.xml">
<!ENTITY querybuf SYSTEM "v4l/vidioc-querybuf.xml">
<!ENTITY querycap SYSTEM "v4l/vidioc-querycap.xml">
<!ENTITY queryctrl SYSTEM "v4l/vidioc-queryctrl.xml">
<!ENTITY querystd SYSTEM "v4l/vidioc-querystd.xml">
<!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
<!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
<!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml">
<!ENTITY dqevent SYSTEM "v4l/vidioc-dqevent.xml">
<!ENTITY subscribe_event SYSTEM "v4l/vidioc-subscribe-event.xml">

View File

@@ -0,0 +1,89 @@
<!-- Generated file! Do not edit. -->
<index><title>List of Types</title>
<indexentry><primaryie><link linkend='v4l2-std-id'>v4l2_std_id</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-buf-type'>v4l2_buf_type</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-colorspace'>v4l2_colorspace</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-ctrl-type'>v4l2_ctrl_type</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-exposure-auto-type'>v4l2_exposure_auto_type</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-emphasis'>v4l2_mpeg_audio_emphasis</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-encoding'>v4l2_mpeg_audio_encoding</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l1-bitrate'>v4l2_mpeg_audio_l1_bitrate</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l2-bitrate'>v4l2_mpeg_audio_l2_bitrate</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l3-bitrate'>v4l2_mpeg_audio_l3_bitrate</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-mode'>v4l2_mpeg_audio_mode</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-mode-extension'>v4l2_mpeg_audio_mode_extension</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-sampling-freq'>v4l2_mpeg_audio_sampling_freq</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='chroma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='luma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-median-filter-type'>v4l2_mpeg_cx2341x_video_median_filter_type</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-spatial-filter-mode'>v4l2_mpeg_cx2341x_video_spatial_filter_mode</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-temporal-filter-mode'>v4l2_mpeg_cx2341x_video_temporal_filter_mode</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-stream-type'>v4l2_mpeg_stream_type</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-stream-vbi-fmt'>v4l2_mpeg_stream_vbi_fmt</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-aspect'>v4l2_mpeg_video_aspect</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-bitrate-mode'>v4l2_mpeg_video_bitrate_mode</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link></primaryie></indexentry>
<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-control'>v4l2_control</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-crop'>v4l2_crop</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-cropcap'>v4l2_cropcap</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-preset'>v4l2_dv_preset</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-timings'>v4l2_dv_timings</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-ext-control'>v4l2_ext_control</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-ext-controls'>v4l2_ext_controls</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-format'>v4l2_format</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-fract'>v4l2_fract</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-framebuffer'>v4l2_framebuffer</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frequency'>v4l2_frequency</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmival-stepwise'>v4l2_frmival_stepwise</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmivalenum'>v4l2_frmivalenum</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsize-discrete'>v4l2_frmsize_discrete</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsize-stepwise'>v4l2_frmsize_stepwise</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsizeenum'>v4l2_frmsizeenum</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-requestbuffers'>v4l2_requestbuffers</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-tuner'>v4l2_tuner</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link></primaryie></indexentry>
<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link></primaryie></indexentry>
</index>

View File

@@ -0,0 +1,112 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities;
<!ENTITY media-indices SYSTEM "./media-indices.tmpl">
<!ENTITY eg "e.&nbsp;g.">
<!ENTITY ie "i.&nbsp;e.">
<!ENTITY fd "File descriptor returned by <link linkend='func-open'><function>open()</function></link>.">
<!ENTITY i2c "I<superscript>2</superscript>C">
<!ENTITY return-value "<title>Return Value</title><para>On success <returnvalue>0</returnvalue> is returned, on error <returnvalue>-1</returnvalue> and the <varname>errno</varname> variable is set appropriately:</para>">
<!ENTITY manvol "<manvolnum>2</manvolnum>">
<!-- Table templates: structs, structs w/union, defines. -->
<!ENTITY cs-str "<colspec colname='c1' colwidth='1*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='2*' /><spanspec spanname='hspan' namest='c1' nameend='c3' />">
<!ENTITY cs-ustr "<colspec colname='c1' colwidth='1*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='1*' /><colspec colname='c4' colwidth='2*' /><spanspec spanname='hspan' namest='c1' nameend='c4' />">
<!ENTITY cs-def "<colspec colname='c1' colwidth='3*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='4*' /><spanspec spanname='hspan' namest='c1' nameend='c3' />">
<!-- Video for Linux mailing list address. -->
<!ENTITY v4l-ml "<ulink url='http://www.linuxtv.org/lists.php'>http://www.linuxtv.org/lists.php</ulink>">
<!-- LinuxTV v4l-dvb repository. -->
<!ENTITY v4l-dvb "<ulink url='http://linuxtv.org/repo/'>http://linuxtv.org/repo/</ulink>">
]>
<book id="media_api">
<bookinfo>
<title>LINUX MEDIA INFRASTRUCTURE API</title>
<copyright>
<year>2009-2010</year>
<holder>LinuxTV Developers</holder>
</copyright>
<legalnotice>
<para>Permission is granted to copy, distribute and/or modify
this document under the terms of the GNU Free Documentation License,
Version 1.1 or any later version published by the Free Software
Foundation. A copy of the license is included in the chapter entitled
"GNU Free Documentation License"</para>
</legalnotice>
</bookinfo>
<toc></toc> <!-- autogenerated -->
<preface>
<title>Introduction</title>
<para>This document covers the Linux Kernel to Userspace API's used by
video and radio straming devices, including video cameras,
analog and digital TV receiver cards, AM/FM receiver cards,
streaming capture devices.</para>
<para>It is divided into three parts.</para>
<para>The first part covers radio, capture,
cameras and analog TV devices.</para>
<para>The second part covers the
API used for digital TV and Internet reception via one of the
several digital tv standards. While it is called as DVB API,
in fact it covers several different video standards including
DVB-T, DVB-S, DVB-C and ATSC. The API is currently being updated
to documment support also for DVB-S2, ISDB-T and ISDB-S.</para>
<para>The third part covers Remote Controller API</para>
<para>For additional information and for the latest development code,
see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
<para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
</preface>
<part id="v4l2spec">
&sub-v4l2;
</part>
<part id="dvbapi">
&sub-dvbapi;
</part>
<part id="v4ldvb_common">
<partinfo>
<authorgroup>
<author>
<firstname>Mauro</firstname>
<surname>Chehab</surname>
<othername role="mi">Carvalho</othername>
<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
<contrib>Initial version.</contrib>
</author>
</authorgroup>
<copyright>
<year>2009-2010</year>
<holder>Mauro Carvalho Chehab</holder>
</copyright>
<revhistory>
<!-- Put document revisions here, newest first. -->
<revision>
<revnumber>1.0.0</revnumber>
<date>2009-09-06</date>
<authorinitials>mcc</authorinitials>
<revremark>Initial revision</revremark>
</revision>
</revhistory>
</partinfo>
<title>Remote Controller API</title>
<chapter id="remote_controllers">
&sub-remote_controllers;
</chapter>
</part>
&sub-fdl-appendix;
</book>

View File

@@ -174,7 +174,7 @@
</para>
<programlisting>
static struct mtd_info *board_mtd;
static unsigned long baseaddr;
static void __iomem *baseaddr;
</programlisting>
<para>
Static example
@@ -182,7 +182,7 @@ static unsigned long baseaddr;
<programlisting>
static struct mtd_info board_mtd;
static struct nand_chip board_chip;
static unsigned long baseaddr;
static void __iomem *baseaddr;
</programlisting>
</sect1>
<sect1 id="Partition_defines">
@@ -269,7 +269,7 @@ static void board_hwcontrol(struct mtd_info *mtd, int cmd)
information about the device.
</para>
<programlisting>
int __init board_init (void)
static int __init board_init (void)
{
struct nand_chip *this;
int err = 0;
@@ -283,8 +283,8 @@ int __init board_init (void)
}
/* map physical address */
baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
if(!baseaddr){
baseaddr = ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
if (!baseaddr) {
printk("Ioremap to access NAND chip failed\n");
err = -EIO;
goto out_mtd;
@@ -316,7 +316,7 @@ int __init board_init (void)
goto out;
out_ior:
iounmap((void *)baseaddr);
iounmap(baseaddr);
out_mtd:
kfree (board_mtd);
out:
@@ -341,7 +341,7 @@ static void __exit board_cleanup (void)
nand_release (board_mtd);
/* unmap physical address */
iounmap((void *)baseaddr);
iounmap(baseaddr);
/* Free the MTD device structure */
kfree (board_mtd);
@@ -362,7 +362,7 @@ module_exit(board_cleanup);
<sect1 id="Multiple_chip_control">
<title>Multiple chip control</title>
<para>
The nand driver can control chip arrays. Therefor the
The nand driver can control chip arrays. Therefore the
board driver must provide an own select_chip function. This
function must (de)select the requested chip.
The function pointer in the nand_chip structure must
@@ -488,7 +488,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip)
The ECC bytes must be placed immidiately after the data
bytes in order to make the syndrome generator work. This
is contrary to the usual layout used by software ECC. The
seperation of data and out of band area is not longer
separation of data and out of band area is not longer
possible. The nand driver code handles this layout and
the remaining free bytes in the oob area are managed by
the autoplacement code. Provide a matching oob-layout
@@ -560,7 +560,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip)
bad blocks. They have factory marked good blocks. The marker pattern
is erased when the block is erased to be reused. So in case of
powerloss before writing the pattern back to the chip this block
would be lost and added to the bad blocks. Therefor we scan the
would be lost and added to the bad blocks. Therefore we scan the
chip(s) when we detect them the first time for good blocks and
store this information in a bad block table before erasing any
of the blocks.
@@ -568,7 +568,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip)
<para>
The blocks in which the tables are stored are procteted against
accidental access by marking them bad in the memory bad block
table. The bad block table managment functions are allowed
table. The bad block table management functions are allowed
to circumvernt this protection.
</para>
<para>
@@ -1094,7 +1094,7 @@ in this page</entry>
manufacturers specifications. This applies similar to the spare area.
</para>
<para>
Therefor NAND aware filesystems must either write in page size chunks
Therefore NAND aware filesystems must either write in page size chunks
or hold a writebuffer to collect smaller writes until they sum up to
pagesize. Available NAND aware filesystems: JFFS2, YAFFS.
</para>

View File

@@ -1,626 +0,0 @@
<?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" [
<!ENTITY procfsexample SYSTEM "procfs_example.xml">
]>
<book id="LKProcfsGuide">
<bookinfo>
<title>Linux Kernel Procfs Guide</title>
<authorgroup>
<author>
<firstname>Erik</firstname>
<othername>(J.A.K.)</othername>
<surname>Mouw</surname>
<affiliation>
<address>
<email>mouw@nl.linux.org</email>
</address>
</affiliation>
</author>
<othercredit>
<contrib>
This software and documentation were written while working on the
LART computing board
(<ulink url="http://www.lartmaker.nl/">http://www.lartmaker.nl/</ulink>),
which was sponsored by the Delt University of Technology projects
Mobile Multi-media Communications and Ubiquitous Communications.
</contrib>
</othercredit>
</authorgroup>
<revhistory>
<revision>
<revnumber>1.0</revnumber>
<date>May 30, 2001</date>
<revremark>Initial revision posted to linux-kernel</revremark>
</revision>
<revision>
<revnumber>1.1</revnumber>
<date>June 3, 2001</date>
<revremark>Revised after comments from linux-kernel</revremark>
</revision>
</revhistory>
<copyright>
<year>2001</year>
<holder>Erik Mouw</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
</para>
<para>
This documentation is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc>
</toc>
<preface id="Preface">
<title>Preface</title>
<para>
This guide describes the use of the procfs file system from
within the Linux kernel. The idea to write this guide came up on
the #kernelnewbies IRC channel (see <ulink
url="http://www.kernelnewbies.org/">http://www.kernelnewbies.org/</ulink>),
when Jeff Garzik explained the use of procfs and forwarded me a
message Alexander Viro wrote to the linux-kernel mailing list. I
agreed to write it up nicely, so here it is.
</para>
<para>
I'd like to thank Jeff Garzik
<email>jgarzik@pobox.com</email> and Alexander Viro
<email>viro@parcelfarce.linux.theplanet.co.uk</email> for their input,
Tim Waugh <email>twaugh@redhat.com</email> for his <ulink
url="http://people.redhat.com/twaugh/docbook/selfdocbook/">Selfdocbook</ulink>,
and Marc Joosen <email>marcj@historia.et.tudelft.nl</email> for
proofreading.
</para>
<para>
Erik
</para>
</preface>
<chapter id="intro">
<title>Introduction</title>
<para>
The <filename class="directory">/proc</filename> file system
(procfs) is a special file system in the linux kernel. It's a
virtual file system: it is not associated with a block device
but exists only in memory. The files in the procfs are there to
allow userland programs access to certain information from the
kernel (like process information in <filename
class="directory">/proc/[0-9]+/</filename>), but also for debug
purposes (like <filename>/proc/ksyms</filename>).
</para>
<para>
This guide describes the use of the procfs file system from
within the Linux kernel. It starts by introducing all relevant
functions to manage the files within the file system. After that
it shows how to communicate with userland, and some tips and
tricks will be pointed out. Finally a complete example will be
shown.
</para>
<para>
Note that the files in <filename
class="directory">/proc/sys</filename> are sysctl files: they
don't belong to procfs and are governed by a completely
different API described in the Kernel API book.
</para>
</chapter>
<chapter id="managing">
<title>Managing procfs entries</title>
<para>
This chapter describes the functions that various kernel
components use to populate the procfs with files, symlinks,
device nodes, and directories.
</para>
<para>
A minor note before we start: if you want to use any of the
procfs functions, be sure to include the correct header file!
This should be one of the first lines in your code:
</para>
<programlisting>
#include &lt;linux/proc_fs.h&gt;
</programlisting>
<sect1 id="regularfile">
<title>Creating a regular file</title>
<funcsynopsis>
<funcprototype>
<funcdef>struct proc_dir_entry* <function>create_proc_entry</function></funcdef>
<paramdef>const char* <parameter>name</parameter></paramdef>
<paramdef>mode_t <parameter>mode</parameter></paramdef>
<paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This function creates a regular file with the name
<parameter>name</parameter>, file mode
<parameter>mode</parameter> in the directory
<parameter>parent</parameter>. To create a file in the root of
the procfs, use <constant>NULL</constant> as
<parameter>parent</parameter> parameter. When successful, the
function will return a pointer to the freshly created
<structname>struct proc_dir_entry</structname>; otherwise it
will return <constant>NULL</constant>. <xref
linkend="userland"/> describes how to do something useful with
regular files.
</para>
<para>
Note that it is specifically supported that you can pass a
path that spans multiple directories. For example
<function>create_proc_entry</function>(<parameter>"drivers/via0/info"</parameter>)
will create the <filename class="directory">via0</filename>
directory if necessary, with standard
<constant>0755</constant> permissions.
</para>
<para>
If you only want to be able to read the file, the function
<function>create_proc_read_entry</function> described in <xref
linkend="convenience"/> may be used to create and initialise
the procfs entry in one single call.
</para>
</sect1>
<sect1 id="Creating_a_symlink">
<title>Creating a symlink</title>
<funcsynopsis>
<funcprototype>
<funcdef>struct proc_dir_entry*
<function>proc_symlink</function></funcdef> <paramdef>const
char* <parameter>name</parameter></paramdef>
<paramdef>struct proc_dir_entry*
<parameter>parent</parameter></paramdef> <paramdef>const
char* <parameter>dest</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This creates a symlink in the procfs directory
<parameter>parent</parameter> that points from
<parameter>name</parameter> to
<parameter>dest</parameter>. This translates in userland to
<literal>ln -s</literal> <parameter>dest</parameter>
<parameter>name</parameter>.
</para>
</sect1>
<sect1 id="Creating_a_directory">
<title>Creating a directory</title>
<funcsynopsis>
<funcprototype>
<funcdef>struct proc_dir_entry* <function>proc_mkdir</function></funcdef>
<paramdef>const char* <parameter>name</parameter></paramdef>
<paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Create a directory <parameter>name</parameter> in the procfs
directory <parameter>parent</parameter>.
</para>
</sect1>
<sect1 id="Removing_an_entry">
<title>Removing an entry</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>remove_proc_entry</function></funcdef>
<paramdef>const char* <parameter>name</parameter></paramdef>
<paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Removes the entry <parameter>name</parameter> in the directory
<parameter>parent</parameter> from the procfs. Entries are
removed by their <emphasis>name</emphasis>, not by the
<structname>struct proc_dir_entry</structname> returned by the
various create functions. Note that this function doesn't
recursively remove entries.
</para>
<para>
Be sure to free the <structfield>data</structfield> entry from
the <structname>struct proc_dir_entry</structname> before
<function>remove_proc_entry</function> is called (that is: if
there was some <structfield>data</structfield> allocated, of
course). See <xref linkend="usingdata"/> for more information
on using the <structfield>data</structfield> entry.
</para>
</sect1>
</chapter>
<chapter id="userland">
<title>Communicating with userland</title>
<para>
Instead of reading (or writing) information directly from
kernel memory, procfs works with <emphasis>call back
functions</emphasis> for files: functions that are called when
a specific file is being read or written. Such functions have
to be initialised after the procfs file is created by setting
the <structfield>read_proc</structfield> and/or
<structfield>write_proc</structfield> fields in the
<structname>struct proc_dir_entry*</structname> that the
function <function>create_proc_entry</function> returned:
</para>
<programlisting>
struct proc_dir_entry* entry;
entry->read_proc = read_proc_foo;
entry->write_proc = write_proc_foo;
</programlisting>
<para>
If you only want to use a the
<structfield>read_proc</structfield>, the function
<function>create_proc_read_entry</function> described in <xref
linkend="convenience"/> may be used to create and initialise the
procfs entry in one single call.
</para>
<sect1 id="Reading_data">
<title>Reading data</title>
<para>
The read function is a call back function that allows userland
processes to read data from the kernel. The read function
should have the following format:
</para>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>read_func</function></funcdef>
<paramdef>char* <parameter>buffer</parameter></paramdef>
<paramdef>char** <parameter>start</parameter></paramdef>
<paramdef>off_t <parameter>off</parameter></paramdef>
<paramdef>int <parameter>count</parameter></paramdef>
<paramdef>int* <parameter>peof</parameter></paramdef>
<paramdef>void* <parameter>data</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
The read function should write its information into the
<parameter>buffer</parameter>, which will be exactly
<literal>PAGE_SIZE</literal> bytes long.
</para>
<para>
The parameter
<parameter>peof</parameter> should be used to signal that the
end of the file has been reached by writing
<literal>1</literal> to the memory location
<parameter>peof</parameter> points to.
</para>
<para>
The <parameter>data</parameter>
parameter can be used to create a single call back function for
several files, see <xref linkend="usingdata"/>.
</para>
<para>
The rest of the parameters and the return value are described
by a comment in <filename>fs/proc/generic.c</filename> as follows:
</para>
<blockquote>
<para>
You have three ways to return data:
</para>
<orderedlist>
<listitem>
<para>
Leave <literal>*start = NULL</literal>. (This is the default.)
Put the data of the requested offset at that
offset within the buffer. Return the number (<literal>n</literal>)
of bytes there are from the beginning of the
buffer up to the last byte of data. If the
number of supplied bytes (<literal>= n - offset</literal>) is
greater than zero and you didn't signal eof
and the reader is prepared to take more data
you will be called again with the requested
offset advanced by the number of bytes
absorbed. This interface is useful for files
no larger than the buffer.
</para>
</listitem>
<listitem>
<para>
Set <literal>*start</literal> to an unsigned long value less than
the buffer address but greater than zero.
Put the data of the requested offset at the
beginning of the buffer. Return the number of
bytes of data placed there. If this number is
greater than zero and you didn't signal eof
and the reader is prepared to take more data
you will be called again with the requested
offset advanced by <literal>*start</literal>. This interface is
useful when you have a large file consisting
of a series of blocks which you want to count
and return as wholes.
(Hack by Paul.Russell@rustcorp.com.au)
</para>
</listitem>
<listitem>
<para>
Set <literal>*start</literal> to an address within the buffer.
Put the data of the requested offset at <literal>*start</literal>.
Return the number of bytes of data placed there.
If this number is greater than zero and you
didn't signal eof and the reader is prepared to
take more data you will be called again with the
requested offset advanced by the number of bytes
absorbed.
</para>
</listitem>
</orderedlist>
</blockquote>
<para>
<xref linkend="example"/> shows how to use a read call back
function.
</para>
</sect1>
<sect1 id="Writing_data">
<title>Writing data</title>
<para>
The write call back function allows a userland process to write
data to the kernel, so it has some kind of control over the
kernel. The write function should have the following format:
</para>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>write_func</function></funcdef>
<paramdef>struct file* <parameter>file</parameter></paramdef>
<paramdef>const char* <parameter>buffer</parameter></paramdef>
<paramdef>unsigned long <parameter>count</parameter></paramdef>
<paramdef>void* <parameter>data</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
The write function should read <parameter>count</parameter>
bytes at maximum from the <parameter>buffer</parameter>. Note
that the <parameter>buffer</parameter> doesn't live in the
kernel's memory space, so it should first be copied to kernel
space with <function>copy_from_user</function>. The
<parameter>file</parameter> parameter is usually
ignored. <xref linkend="usingdata"/> shows how to use the
<parameter>data</parameter> parameter.
</para>
<para>
Again, <xref linkend="example"/> shows how to use this call back
function.
</para>
</sect1>
<sect1 id="usingdata">
<title>A single call back for many files</title>
<para>
When a large number of almost identical files is used, it's
quite inconvenient to use a separate call back function for
each file. A better approach is to have a single call back
function that distinguishes between the files by using the
<structfield>data</structfield> field in <structname>struct
proc_dir_entry</structname>. First of all, the
<structfield>data</structfield> field has to be initialised:
</para>
<programlisting>
struct proc_dir_entry* entry;
struct my_file_data *file_data;
file_data = kmalloc(sizeof(struct my_file_data), GFP_KERNEL);
entry->data = file_data;
</programlisting>
<para>
The <structfield>data</structfield> field is a <type>void
*</type>, so it can be initialised with anything.
</para>
<para>
Now that the <structfield>data</structfield> field is set, the
<function>read_proc</function> and
<function>write_proc</function> can use it to distinguish
between files because they get it passed into their
<parameter>data</parameter> parameter:
</para>
<programlisting>
int foo_read_func(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
if(data == file_data) {
/* special case for this file */
} else {
/* normal processing */
}
return len;
}
</programlisting>
<para>
Be sure to free the <structfield>data</structfield> data field
when removing the procfs entry.
</para>
</sect1>
</chapter>
<chapter id="tips">
<title>Tips and tricks</title>
<sect1 id="convenience">
<title>Convenience functions</title>
<funcsynopsis>
<funcprototype>
<funcdef>struct proc_dir_entry* <function>create_proc_read_entry</function></funcdef>
<paramdef>const char* <parameter>name</parameter></paramdef>
<paramdef>mode_t <parameter>mode</parameter></paramdef>
<paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>
<paramdef>read_proc_t* <parameter>read_proc</parameter></paramdef>
<paramdef>void* <parameter>data</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This function creates a regular file in exactly the same way
as <function>create_proc_entry</function> from <xref
linkend="regularfile"/> does, but also allows to set the read
function <parameter>read_proc</parameter> in one call. This
function can set the <parameter>data</parameter> as well, like
explained in <xref linkend="usingdata"/>.
</para>
</sect1>
<sect1 id="Modules">
<title>Modules</title>
<para>
If procfs is being used from within a module, be sure to set
the <structfield>owner</structfield> field in the
<structname>struct proc_dir_entry</structname> to
<constant>THIS_MODULE</constant>.
</para>
<programlisting>
struct proc_dir_entry* entry;
entry->owner = THIS_MODULE;
</programlisting>
</sect1>
<sect1 id="Mode_and_ownership">
<title>Mode and ownership</title>
<para>
Sometimes it is useful to change the mode and/or ownership of
a procfs entry. Here is an example that shows how to achieve
that:
</para>
<programlisting>
struct proc_dir_entry* entry;
entry->mode = S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH;
entry->uid = 0;
entry->gid = 100;
</programlisting>
</sect1>
</chapter>
<chapter id="example">
<title>Example</title>
<!-- be careful with the example code: it shouldn't be wider than
approx. 60 columns, or otherwise it won't fit properly on a page
-->
&procfsexample;
</chapter>
</book>

View File

@@ -1,201 +0,0 @@
/*
* procfs_example.c: an example proc interface
*
* Copyright (C) 2001, Erik Mouw (mouw@nl.linux.org)
*
* This file accompanies the procfs-guide in the Linux kernel
* source. Its main use is to demonstrate the concepts and
* functions described in the guide.
*
* This software has been developed while working on the LART
* computing board (http://www.lartmaker.nl), which was sponsored
* by the Delt University of Technology projects Mobile Multi-media
* Communications and Ubiquitous Communications.
*
* This program is free software; you can redistribute
* it and/or modify it under the terms of the GNU General
* Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/jiffies.h>
#include <asm/uaccess.h>
#define MODULE_VERS "1.0"
#define MODULE_NAME "procfs_example"
#define FOOBAR_LEN 8
struct fb_data_t {
char name[FOOBAR_LEN + 1];
char value[FOOBAR_LEN + 1];
};
static struct proc_dir_entry *example_dir, *foo_file,
*bar_file, *jiffies_file, *symlink;
struct fb_data_t foo_data, bar_data;
static int proc_read_jiffies(char *page, char **start,
off_t off, int count,
int *eof, void *data)
{
int len;
len = sprintf(page, "jiffies = %ld\n",
jiffies);
return len;
}
static int proc_read_foobar(char *page, char **start,
off_t off, int count,
int *eof, void *data)
{
int len;
struct fb_data_t *fb_data = (struct fb_data_t *)data;
/* DON'T DO THAT - buffer overruns are bad */
len = sprintf(page, "%s = '%s'\n",
fb_data->name, fb_data->value);
return len;
}
static int proc_write_foobar(struct file *file,
const char *buffer,
unsigned long count,
void *data)
{
int len;
struct fb_data_t *fb_data = (struct fb_data_t *)data;
if(count > FOOBAR_LEN)
len = FOOBAR_LEN;
else
len = count;
if(copy_from_user(fb_data->value, buffer, len))
return -EFAULT;
fb_data->value[len] = '\0';
return len;
}
static int __init init_procfs_example(void)
{
int rv = 0;
/* create directory */
example_dir = proc_mkdir(MODULE_NAME, NULL);
if(example_dir == NULL) {
rv = -ENOMEM;
goto out;
}
/* create jiffies using convenience function */
jiffies_file = create_proc_read_entry("jiffies",
0444, example_dir,
proc_read_jiffies,
NULL);
if(jiffies_file == NULL) {
rv = -ENOMEM;
goto no_jiffies;
}
/* create foo and bar files using same callback
* functions
*/
foo_file = create_proc_entry("foo", 0644, example_dir);
if(foo_file == NULL) {
rv = -ENOMEM;
goto no_foo;
}
strcpy(foo_data.name, "foo");
strcpy(foo_data.value, "foo");
foo_file->data = &foo_data;
foo_file->read_proc = proc_read_foobar;
foo_file->write_proc = proc_write_foobar;
bar_file = create_proc_entry("bar", 0644, example_dir);
if(bar_file == NULL) {
rv = -ENOMEM;
goto no_bar;
}
strcpy(bar_data.name, "bar");
strcpy(bar_data.value, "bar");
bar_file->data = &bar_data;
bar_file->read_proc = proc_read_foobar;
bar_file->write_proc = proc_write_foobar;
/* create symlink */
symlink = proc_symlink("jiffies_too", example_dir,
"jiffies");
if(symlink == NULL) {
rv = -ENOMEM;
goto no_symlink;
}
/* everything OK */
printk(KERN_INFO "%s %s initialised\n",
MODULE_NAME, MODULE_VERS);
return 0;
no_symlink:
remove_proc_entry("bar", example_dir);
no_bar:
remove_proc_entry("foo", example_dir);
no_foo:
remove_proc_entry("jiffies", example_dir);
no_jiffies:
remove_proc_entry(MODULE_NAME, NULL);
out:
return rv;
}
static void __exit cleanup_procfs_example(void)
{
remove_proc_entry("jiffies_too", example_dir);
remove_proc_entry("bar", example_dir);
remove_proc_entry("foo", example_dir);
remove_proc_entry("jiffies", example_dir);
remove_proc_entry(MODULE_NAME, NULL);
printk(KERN_INFO "%s %s removed\n",
MODULE_NAME, MODULE_VERS);
}
module_init(init_procfs_example);
module_exit(cleanup_procfs_example);
MODULE_AUTHOR("Erik Mouw");
MODULE_DESCRIPTION("procfs examples");
MODULE_LICENSE("GPL");

View File

@@ -317,7 +317,7 @@
<para>
The SAS transport class contains common code to deal with SAS HBAs,
an aproximated representation of SAS topologies in the driver model,
and various sysfs attributes to expose these topologies and managment
and various sysfs attributes to expose these topologies and management
interfaces to userspace.
</para>
<para>
@@ -393,7 +393,7 @@
</para>
<para>
For documentation see
<ulink url='http://www.torque.net/sg/sdebug26.html'>http://www.torque.net/sg/sdebug26.html</ulink>
<ulink url='http://sg.danny.cz/sg/sdebug26.html'>http://sg.danny.cz/sg/sdebug26.html</ulink>
</para>
<!-- !Edrivers/scsi/scsi_debug.c -->
</sect2>

View File

@@ -19,13 +19,17 @@
</authorgroup>
<copyright>
<year>2008</year>
<year>2008-2010</year>
<holder>Paul Mundt</holder>
</copyright>
<copyright>
<year>2008</year>
<year>2008-2010</year>
<holder>Renesas Technology Corp.</holder>
</copyright>
<copyright>
<year>2010</year>
<holder>Renesas Electronics Corp.</holder>
</copyright>
<legalnotice>
<para>
@@ -75,10 +79,6 @@
</sect2>
</sect1>
</chapter>
<chapter id="clk">
<title>Clock Framework Extensions</title>
!Iarch/sh/include/asm/clock.h
</chapter>
<chapter id="mach">
<title>Machine Specific Interfaces</title>
<sect1 id="dreamcast">

Some files were not shown because too many files have changed in this diff Show More