Merge branch 'linus' into x86/urgent
Merge needed to go past commit 7ca43e756
(mm: use debug_kmap_atomic)
and fix it.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
commit
83f2f0ed71
9
CREDITS
9
CREDITS
|
@ -495,6 +495,11 @@ S: Kopmansg 2
|
||||||
S: 411 13 Goteborg
|
S: 411 13 Goteborg
|
||||||
S: Sweden
|
S: Sweden
|
||||||
|
|
||||||
|
N: Paul Bristow
|
||||||
|
E: paul@paulbristow.net
|
||||||
|
W: http://paulbristow.net/linux/idefloppy.html
|
||||||
|
D: Maintainer of IDE/ATAPI floppy driver
|
||||||
|
|
||||||
N: Dominik Brodowski
|
N: Dominik Brodowski
|
||||||
E: linux@brodo.de
|
E: linux@brodo.de
|
||||||
W: http://www.brodo.de/
|
W: http://www.brodo.de/
|
||||||
|
@ -2642,6 +2647,10 @@ S: C/ Mieses 20, 9-B
|
||||||
S: Valladolid 47009
|
S: Valladolid 47009
|
||||||
S: Spain
|
S: Spain
|
||||||
|
|
||||||
|
N: Gadi Oxman
|
||||||
|
E: gadio@netvision.net.il
|
||||||
|
D: Original author and maintainer of IDE/ATAPI floppy/tape drivers
|
||||||
|
|
||||||
N: Greg Page
|
N: Greg Page
|
||||||
E: gpage@sovereign.org
|
E: gpage@sovereign.org
|
||||||
D: IPX development and support
|
D: IPX development and support
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
What: security/ima/policy
|
||||||
|
Date: May 2008
|
||||||
|
Contact: Mimi Zohar <zohar@us.ibm.com>
|
||||||
|
Description:
|
||||||
|
The Trusted Computing Group(TCG) runtime Integrity
|
||||||
|
Measurement Architecture(IMA) maintains a list of hash
|
||||||
|
values of executables and other sensitive system files
|
||||||
|
loaded into the run-time of this system. At runtime,
|
||||||
|
the policy can be constrained based on LSM specific data.
|
||||||
|
Policies are loaded into the securityfs file ima/policy
|
||||||
|
by opening the file, writing the rules one at a time and
|
||||||
|
then closing the file. The new policy takes effect after
|
||||||
|
the file ima/policy is closed.
|
||||||
|
|
||||||
|
rule format: action [condition ...]
|
||||||
|
|
||||||
|
action: measure | dont_measure
|
||||||
|
condition:= base | lsm
|
||||||
|
base: [[func=] [mask=] [fsmagic=] [uid=]]
|
||||||
|
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
||||||
|
[obj_user=] [obj_role=] [obj_type=]]
|
||||||
|
|
||||||
|
base: func:= [BPRM_CHECK][FILE_MMAP][INODE_PERMISSION]
|
||||||
|
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
|
||||||
|
fsmagic:= hex value
|
||||||
|
uid:= decimal value
|
||||||
|
lsm: are LSM specific
|
||||||
|
|
||||||
|
default policy:
|
||||||
|
# PROC_SUPER_MAGIC
|
||||||
|
dont_measure fsmagic=0x9fa0
|
||||||
|
# SYSFS_MAGIC
|
||||||
|
dont_measure fsmagic=0x62656572
|
||||||
|
# DEBUGFS_MAGIC
|
||||||
|
dont_measure fsmagic=0x64626720
|
||||||
|
# TMPFS_MAGIC
|
||||||
|
dont_measure fsmagic=0x01021994
|
||||||
|
# SECURITYFS_MAGIC
|
||||||
|
dont_measure fsmagic=0x73636673
|
||||||
|
|
||||||
|
measure func=BPRM_CHECK
|
||||||
|
measure func=FILE_MMAP mask=MAY_EXEC
|
||||||
|
measure func=INODE_PERM 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.
|
||||||
|
|
||||||
|
Examples of LSM specific definitions:
|
||||||
|
|
||||||
|
SELinux:
|
||||||
|
# SELINUX_MAGIC
|
||||||
|
dont_measure fsmagic=0xF97CFF8C
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Smack:
|
||||||
|
measure subj_user=_ func=INODE_PERM mask=MAY_READ
|
|
@ -41,6 +41,49 @@ Description:
|
||||||
for the device and attempt to bind to it. For example:
|
for the device and attempt to bind to it. For example:
|
||||||
# echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id
|
# echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id
|
||||||
|
|
||||||
|
What: /sys/bus/pci/drivers/.../remove_id
|
||||||
|
Date: February 2009
|
||||||
|
Contact: Chris Wright <chrisw@sous-sol.org>
|
||||||
|
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:
|
||||||
|
VVVV DDDD SVVV SDDD CCCC MMMM. That is Vendor ID, Device
|
||||||
|
ID, Subsystem Vendor ID, Subsystem Device ID, Class,
|
||||||
|
and Class Mask. The Vendor ID and Device ID fields are
|
||||||
|
required, the rest are optional. 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 "8086 10f5" > /sys/bus/pci/drivers/foo/remove_id
|
||||||
|
|
||||||
|
What: /sys/bus/pci/rescan
|
||||||
|
Date: January 2009
|
||||||
|
Contact: Linux PCI developers <linux-pci@vger.kernel.org>
|
||||||
|
Description:
|
||||||
|
Writing a non-zero value to this attribute will
|
||||||
|
force a rescan of all PCI buses in the system, and
|
||||||
|
re-discover previously removed devices.
|
||||||
|
Depends on CONFIG_HOTPLUG.
|
||||||
|
|
||||||
|
What: /sys/bus/pci/devices/.../remove
|
||||||
|
Date: January 2009
|
||||||
|
Contact: Linux PCI developers <linux-pci@vger.kernel.org>
|
||||||
|
Description:
|
||||||
|
Writing a non-zero value to this attribute will
|
||||||
|
hot-remove the PCI device and any of its children.
|
||||||
|
Depends on CONFIG_HOTPLUG.
|
||||||
|
|
||||||
|
What: /sys/bus/pci/devices/.../rescan
|
||||||
|
Date: January 2009
|
||||||
|
Contact: Linux PCI developers <linux-pci@vger.kernel.org>
|
||||||
|
Description:
|
||||||
|
Writing a non-zero value to this attribute will
|
||||||
|
force a rescan of the device's parent bus and all
|
||||||
|
child buses, and re-discover devices removed earlier
|
||||||
|
from this part of the device tree.
|
||||||
|
Depends on CONFIG_HOTPLUG.
|
||||||
|
|
||||||
What: /sys/bus/pci/devices/.../vpd
|
What: /sys/bus/pci/devices/.../vpd
|
||||||
Date: February 2008
|
Date: February 2008
|
||||||
Contact: Ben Hutchings <bhutchings@solarflare.com>
|
Contact: Ben Hutchings <bhutchings@solarflare.com>
|
||||||
|
@ -52,3 +95,30 @@ Description:
|
||||||
that some devices may have malformatted data. If the
|
that some devices may have malformatted data. If the
|
||||||
underlying VPD has a writable section then the
|
underlying VPD has a writable section then the
|
||||||
corresponding section of this file will be writable.
|
corresponding section of this file will be writable.
|
||||||
|
|
||||||
|
What: /sys/bus/pci/devices/.../virtfnN
|
||||||
|
Date: March 2009
|
||||||
|
Contact: Yu Zhao <yu.zhao@intel.com>
|
||||||
|
Description:
|
||||||
|
This symbolic link appears when hardware supports the SR-IOV
|
||||||
|
capability and the Physical Function driver has enabled it.
|
||||||
|
The symbolic link points to the PCI device sysfs entry of the
|
||||||
|
Virtual Function whose index is N (0...MaxVFs-1).
|
||||||
|
|
||||||
|
What: /sys/bus/pci/devices/.../dep_link
|
||||||
|
Date: March 2009
|
||||||
|
Contact: Yu Zhao <yu.zhao@intel.com>
|
||||||
|
Description:
|
||||||
|
This symbolic link appears when hardware supports the SR-IOV
|
||||||
|
capability and the Physical Function driver has enabled it,
|
||||||
|
and this device has vendor specific dependencies with others.
|
||||||
|
The symbolic link points to the PCI device sysfs entry of
|
||||||
|
Physical Function this device depends on.
|
||||||
|
|
||||||
|
What: /sys/bus/pci/devices/.../physfn
|
||||||
|
Date: March 2009
|
||||||
|
Contact: Yu Zhao <yu.zhao@intel.com>
|
||||||
|
Description:
|
||||||
|
This symbolic link appears when a device is a Virtual Function.
|
||||||
|
The symbolic link points to the PCI device sysfs entry of the
|
||||||
|
Physical Function this device associates with.
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
What: /sys/fs/ext4/<disk>/mb_stats
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
Controls whether the multiblock allocator should
|
||||||
|
collect statistics, which are shown during the unmount.
|
||||||
|
1 means to collect statistics, 0 means not to collect
|
||||||
|
statistics
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/mb_group_prealloc
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
The multiblock allocator will round up allocation
|
||||||
|
requests to a multiple of this tuning parameter if the
|
||||||
|
stripe size is not set in the ext4 superblock
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/mb_max_to_scan
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
The maximum number of extents the multiblock allocator
|
||||||
|
will search to find the best extent
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/mb_min_to_scan
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
The minimum number of extents the multiblock allocator
|
||||||
|
will search to find the best extent
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/mb_order2_req
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
Tuning parameter which controls the minimum size for
|
||||||
|
requests (as a power of 2) where the buddy cache is
|
||||||
|
used
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/mb_stream_req
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
Files which have fewer blocks than this tunable
|
||||||
|
parameter will have their blocks allocated out of a
|
||||||
|
block group specific preallocation pool, so that small
|
||||||
|
files are packed closely together. Each large file
|
||||||
|
will have its blocks allocated out of its own unique
|
||||||
|
preallocation pool.
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/inode_readahead
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
Tuning parameter which controls the maximum number of
|
||||||
|
inode table blocks that ext4's inode table readahead
|
||||||
|
algorithm will pre-read into the buffer cache
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/delayed_allocation_blocks
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
This file is read-only and shows the number of blocks
|
||||||
|
that are dirty in the page cache, but which do not
|
||||||
|
have their location in the filesystem allocated yet.
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/lifetime_write_kbytes
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
This file is read-only and shows the number of kilobytes
|
||||||
|
of data that have been written to this filesystem since it was
|
||||||
|
created.
|
||||||
|
|
||||||
|
What: /sys/fs/ext4/<disk>/session_write_kbytes
|
||||||
|
Date: March 2008
|
||||||
|
Contact: "Theodore Ts'o" <tytso@mit.edu>
|
||||||
|
Description:
|
||||||
|
This file is read-only and shows the number of
|
||||||
|
kilobytes of data that have been written to this
|
||||||
|
filesystem since it was mounted.
|
|
@ -609,3 +609,109 @@ size is the size (and should be a page-sized multiple).
|
||||||
The return value will be either a pointer to the processor virtual
|
The return value will be either a pointer to the processor virtual
|
||||||
address of the memory, or an error (via PTR_ERR()) if any part of the
|
address of the memory, or an error (via PTR_ERR()) if any part of the
|
||||||
region is occupied.
|
region is occupied.
|
||||||
|
|
||||||
|
Part III - Debug drivers use of the DMA-API
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
The DMA-API as described above as some constraints. DMA addresses must be
|
||||||
|
released with the corresponding function with the same size for example. With
|
||||||
|
the advent of hardware IOMMUs it becomes more and more important that drivers
|
||||||
|
do not violate those constraints. In the worst case such a violation can
|
||||||
|
result in data corruption up to destroyed filesystems.
|
||||||
|
|
||||||
|
To debug drivers and find bugs in the usage of the DMA-API checking code can
|
||||||
|
be compiled into the kernel which will tell the developer about those
|
||||||
|
violations. If your architecture supports it you can select the "Enable
|
||||||
|
debugging of DMA-API usage" option in your kernel configuration. Enabling this
|
||||||
|
option has a performance impact. Do not enable it in production kernels.
|
||||||
|
|
||||||
|
If you boot the resulting kernel will contain code which does some bookkeeping
|
||||||
|
about what DMA memory was allocated for which device. If this code detects an
|
||||||
|
error it prints a warning message with some details into your kernel log. An
|
||||||
|
example warning message may look like this:
|
||||||
|
|
||||||
|
------------[ cut here ]------------
|
||||||
|
WARNING: at /data2/repos/linux-2.6-iommu/lib/dma-debug.c:448
|
||||||
|
check_unmap+0x203/0x490()
|
||||||
|
Hardware name:
|
||||||
|
forcedeth 0000:00:08.0: DMA-API: device driver frees DMA memory with wrong
|
||||||
|
function [device address=0x00000000640444be] [size=66 bytes] [mapped as
|
||||||
|
single] [unmapped as page]
|
||||||
|
Modules linked in: nfsd exportfs bridge stp llc r8169
|
||||||
|
Pid: 0, comm: swapper Tainted: G W 2.6.28-dmatest-09289-g8bb99c0 #1
|
||||||
|
Call Trace:
|
||||||
|
<IRQ> [<ffffffff80240b22>] warn_slowpath+0xf2/0x130
|
||||||
|
[<ffffffff80647b70>] _spin_unlock+0x10/0x30
|
||||||
|
[<ffffffff80537e75>] usb_hcd_link_urb_to_ep+0x75/0xc0
|
||||||
|
[<ffffffff80647c22>] _spin_unlock_irqrestore+0x12/0x40
|
||||||
|
[<ffffffff8055347f>] ohci_urb_enqueue+0x19f/0x7c0
|
||||||
|
[<ffffffff80252f96>] queue_work+0x56/0x60
|
||||||
|
[<ffffffff80237e10>] enqueue_task_fair+0x20/0x50
|
||||||
|
[<ffffffff80539279>] usb_hcd_submit_urb+0x379/0xbc0
|
||||||
|
[<ffffffff803b78c3>] cpumask_next_and+0x23/0x40
|
||||||
|
[<ffffffff80235177>] find_busiest_group+0x207/0x8a0
|
||||||
|
[<ffffffff8064784f>] _spin_lock_irqsave+0x1f/0x50
|
||||||
|
[<ffffffff803c7ea3>] check_unmap+0x203/0x490
|
||||||
|
[<ffffffff803c8259>] debug_dma_unmap_page+0x49/0x50
|
||||||
|
[<ffffffff80485f26>] nv_tx_done_optimized+0xc6/0x2c0
|
||||||
|
[<ffffffff80486c13>] nv_nic_irq_optimized+0x73/0x2b0
|
||||||
|
[<ffffffff8026df84>] handle_IRQ_event+0x34/0x70
|
||||||
|
[<ffffffff8026ffe9>] handle_edge_irq+0xc9/0x150
|
||||||
|
[<ffffffff8020e3ab>] do_IRQ+0xcb/0x1c0
|
||||||
|
[<ffffffff8020c093>] ret_from_intr+0x0/0xa
|
||||||
|
<EOI> <4>---[ end trace f6435a98e2a38c0e ]---
|
||||||
|
|
||||||
|
The driver developer can find the driver and the device including a stacktrace
|
||||||
|
of the DMA-API call which caused this warning.
|
||||||
|
|
||||||
|
Per default only the first error will result in a warning message. All other
|
||||||
|
errors will only silently counted. This limitation exist to prevent the code
|
||||||
|
from flooding your kernel log. To support debugging a device driver this can
|
||||||
|
be disabled via debugfs. See the debugfs interface documentation below for
|
||||||
|
details.
|
||||||
|
|
||||||
|
The debugfs directory for the DMA-API debugging code is called dma-api/. In
|
||||||
|
this directory the following files can currently be found:
|
||||||
|
|
||||||
|
dma-api/all_errors This file contains a numeric value. If this
|
||||||
|
value is not equal to zero the debugging code
|
||||||
|
will print a warning for every error it finds
|
||||||
|
into the kernel log. Be carefull with this
|
||||||
|
option. It can easily flood your logs.
|
||||||
|
|
||||||
|
dma-api/disabled This read-only file contains the character 'Y'
|
||||||
|
if the debugging code is disabled. This can
|
||||||
|
happen when it runs out of memory or if it was
|
||||||
|
disabled at boot time
|
||||||
|
|
||||||
|
dma-api/error_count This file is read-only and shows the total
|
||||||
|
numbers of errors found.
|
||||||
|
|
||||||
|
dma-api/num_errors The number in this file shows how many
|
||||||
|
warnings will be printed to the kernel log
|
||||||
|
before it stops. This number is initialized to
|
||||||
|
one at system boot and be set by writing into
|
||||||
|
this file
|
||||||
|
|
||||||
|
dma-api/min_free_entries
|
||||||
|
This read-only file can be read to get the
|
||||||
|
minimum number of free dma_debug_entries the
|
||||||
|
allocator has ever seen. If this value goes
|
||||||
|
down to zero the code will disable itself
|
||||||
|
because it is not longer reliable.
|
||||||
|
|
||||||
|
dma-api/num_free_entries
|
||||||
|
The current number of free dma_debug_entries
|
||||||
|
in the allocator.
|
||||||
|
|
||||||
|
If you have this code compiled into your kernel it will be enabled by default.
|
||||||
|
If you want to boot without the bookkeeping anyway you can provide
|
||||||
|
'dma_debug=off' as a boot parameter. This will disable DMA-API debugging.
|
||||||
|
Notice that you can not enable it again at runtime. You have to reboot to do
|
||||||
|
so.
|
||||||
|
|
||||||
|
When the code disables itself at runtime this is most likely because it ran
|
||||||
|
out of dma_debug_entries. These entries are preallocated at boot. The number
|
||||||
|
of preallocated entries is defined per architecture. If it is too low for you
|
||||||
|
boot with 'dma_debug_entries=<your_desired_number>' to overwrite the
|
||||||
|
architectural default.
|
||||||
|
|
|
@ -12,7 +12,8 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
|
||||||
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
|
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
|
||||||
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
||||||
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
|
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
|
||||||
mac80211.xml debugobjects.xml sh.xml regulator.xml
|
mac80211.xml debugobjects.xml sh.xml regulator.xml \
|
||||||
|
alsa-driver-api.xml writing-an-alsa-driver.xml
|
||||||
|
|
||||||
###
|
###
|
||||||
# The build process is as follows (targets):
|
# The build process is as follows (targets):
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||||
<book>
|
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||||
<?dbhtml filename="index.html">
|
|
||||||
|
|
||||||
<!-- ****************************************************** -->
|
<!-- ****************************************************** -->
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<!-- ****************************************************** -->
|
<!-- ****************************************************** -->
|
||||||
|
<book id="ALSA-Driver-API">
|
||||||
<bookinfo>
|
<bookinfo>
|
||||||
<title>The ALSA Driver API</title>
|
<title>The ALSA Driver API</title>
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
</bookinfo>
|
</bookinfo>
|
||||||
|
|
||||||
|
<toc></toc>
|
||||||
|
|
||||||
<chapter><title>Management of Cards and Devices</title>
|
<chapter><title>Management of Cards and Devices</title>
|
||||||
<sect1><title>Card Management</title>
|
<sect1><title>Card Management</title>
|
||||||
!Esound/core/init.c
|
!Esound/core/init.c
|
||||||
|
@ -71,6 +73,10 @@
|
||||||
!Esound/pci/ac97/ac97_codec.c
|
!Esound/pci/ac97/ac97_codec.c
|
||||||
!Esound/pci/ac97/ac97_pcm.c
|
!Esound/pci/ac97/ac97_pcm.c
|
||||||
</sect1>
|
</sect1>
|
||||||
|
<sect1><title>Virtual Master Control API</title>
|
||||||
|
!Esound/core/vmaster.c
|
||||||
|
!Iinclude/sound/control.h
|
||||||
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter><title>MIDI API</title>
|
<chapter><title>MIDI API</title>
|
||||||
<sect1><title>Raw MIDI API</title>
|
<sect1><title>Raw MIDI API</title>
|
||||||
|
@ -88,6 +94,9 @@
|
||||||
<chapter><title>Miscellaneous Functions</title>
|
<chapter><title>Miscellaneous Functions</title>
|
||||||
<sect1><title>Hardware-Dependent Devices API</title>
|
<sect1><title>Hardware-Dependent Devices API</title>
|
||||||
!Esound/core/hwdep.c
|
!Esound/core/hwdep.c
|
||||||
|
</sect1>
|
||||||
|
<sect1><title>Jack Abstraction Layer API</title>
|
||||||
|
!Esound/core/jack.c
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1><title>ISA DMA Helpers</title>
|
<sect1><title>ISA DMA Helpers</title>
|
||||||
!Esound/core/isadma.c
|
!Esound/core/isadma.c
|
|
@ -440,6 +440,7 @@ desc->chip->end();
|
||||||
used in the generic IRQ layer.
|
used in the generic IRQ layer.
|
||||||
</para>
|
</para>
|
||||||
!Iinclude/linux/irq.h
|
!Iinclude/linux/irq.h
|
||||||
|
!Iinclude/linux/interrupt.h
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="pubfunctions">
|
<chapter id="pubfunctions">
|
||||||
|
|
|
@ -199,6 +199,7 @@ X!Edrivers/pci/hotplug.c
|
||||||
-->
|
-->
|
||||||
!Edrivers/pci/probe.c
|
!Edrivers/pci/probe.c
|
||||||
!Edrivers/pci/rom.c
|
!Edrivers/pci/rom.c
|
||||||
|
!Edrivers/pci/iov.c
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1><title>PCI Hotplug Support Library</title>
|
<sect1><title>PCI Hotplug Support Library</title>
|
||||||
!Edrivers/pci/hotplug/pci_hotplug_core.c
|
!Edrivers/pci/hotplug/pci_hotplug_core.c
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2007</year>
|
<year>2007-2009</year>
|
||||||
<year>2008</year>
|
|
||||||
<holder>Johannes Berg</holder>
|
<holder>Johannes Berg</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
|
@ -165,8 +164,8 @@ usage should require reading the full document.
|
||||||
!Pinclude/net/mac80211.h Frame format
|
!Pinclude/net/mac80211.h Frame format
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1>
|
<sect1>
|
||||||
<title>Alignment issues</title>
|
<title>Packet alignment</title>
|
||||||
<para>TBD</para>
|
!Pnet/mac80211/rx.c Packet alignment
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1>
|
<sect1>
|
||||||
<title>Calling into mac80211 from interrupts</title>
|
<title>Calling into mac80211 from interrupts</title>
|
||||||
|
@ -223,6 +222,17 @@ usage should require reading the full document.
|
||||||
!Finclude/net/mac80211.h ieee80211_key_flags
|
!Finclude/net/mac80211.h ieee80211_key_flags
|
||||||
</chapter>
|
</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">
|
<chapter id="qos">
|
||||||
<title>Multiple queues and QoS support</title>
|
<title>Multiple queues and QoS support</title>
|
||||||
<para>TBD</para>
|
<para>TBD</para>
|
||||||
|
|
|
@ -117,9 +117,6 @@ static int __init init_procfs_example(void)
|
||||||
rv = -ENOMEM;
|
rv = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
example_dir->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
/* create jiffies using convenience function */
|
/* create jiffies using convenience function */
|
||||||
jiffies_file = create_proc_read_entry("jiffies",
|
jiffies_file = create_proc_read_entry("jiffies",
|
||||||
0444, example_dir,
|
0444, example_dir,
|
||||||
|
@ -130,8 +127,6 @@ static int __init init_procfs_example(void)
|
||||||
goto no_jiffies;
|
goto no_jiffies;
|
||||||
}
|
}
|
||||||
|
|
||||||
jiffies_file->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
/* create foo and bar files using same callback
|
/* create foo and bar files using same callback
|
||||||
* functions
|
* functions
|
||||||
*/
|
*/
|
||||||
|
@ -146,7 +141,6 @@ static int __init init_procfs_example(void)
|
||||||
foo_file->data = &foo_data;
|
foo_file->data = &foo_data;
|
||||||
foo_file->read_proc = proc_read_foobar;
|
foo_file->read_proc = proc_read_foobar;
|
||||||
foo_file->write_proc = proc_write_foobar;
|
foo_file->write_proc = proc_write_foobar;
|
||||||
foo_file->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
bar_file = create_proc_entry("bar", 0644, example_dir);
|
bar_file = create_proc_entry("bar", 0644, example_dir);
|
||||||
if(bar_file == NULL) {
|
if(bar_file == NULL) {
|
||||||
|
@ -159,7 +153,6 @@ static int __init init_procfs_example(void)
|
||||||
bar_file->data = &bar_data;
|
bar_file->data = &bar_data;
|
||||||
bar_file->read_proc = proc_read_foobar;
|
bar_file->read_proc = proc_read_foobar;
|
||||||
bar_file->write_proc = proc_write_foobar;
|
bar_file->write_proc = proc_write_foobar;
|
||||||
bar_file->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
/* create symlink */
|
/* create symlink */
|
||||||
symlink = proc_symlink("jiffies_too", example_dir,
|
symlink = proc_symlink("jiffies_too", example_dir,
|
||||||
|
@ -169,8 +162,6 @@ static int __init init_procfs_example(void)
|
||||||
goto no_symlink;
|
goto no_symlink;
|
||||||
}
|
}
|
||||||
|
|
||||||
symlink->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
/* everything OK */
|
/* everything OK */
|
||||||
printk(KERN_INFO "%s %s initialised\n",
|
printk(KERN_INFO "%s %s initialised\n",
|
||||||
MODULE_NAME, MODULE_VERS);
|
MODULE_NAME, MODULE_VERS);
|
||||||
|
|
|
@ -41,6 +41,13 @@ GPL version 2.
|
||||||
</abstract>
|
</abstract>
|
||||||
|
|
||||||
<revhistory>
|
<revhistory>
|
||||||
|
<revision>
|
||||||
|
<revnumber>0.8</revnumber>
|
||||||
|
<date>2008-12-24</date>
|
||||||
|
<authorinitials>hjk</authorinitials>
|
||||||
|
<revremark>Added name attributes in mem and portio sysfs directories.
|
||||||
|
</revremark>
|
||||||
|
</revision>
|
||||||
<revision>
|
<revision>
|
||||||
<revnumber>0.7</revnumber>
|
<revnumber>0.7</revnumber>
|
||||||
<date>2008-12-23</date>
|
<date>2008-12-23</date>
|
||||||
|
@ -303,10 +310,17 @@ interested in translating it, please email me
|
||||||
appear if the size of the mapping is not 0.
|
appear if the size of the mapping is not 0.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Each <filename>mapX/</filename> directory contains two read-only files
|
Each <filename>mapX/</filename> directory contains four read-only files
|
||||||
that show start address and size of the memory:
|
that show attributes of the memory:
|
||||||
</para>
|
</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<filename>name</filename>: A string identifier for this mapping. This
|
||||||
|
is optional, the string can be empty. Drivers can set this to make it
|
||||||
|
easier for userspace to find the correct mapping.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<filename>addr</filename>: The address of memory that can be mapped.
|
<filename>addr</filename>: The address of memory that can be mapped.
|
||||||
|
@ -366,10 +380,17 @@ offset = N * getpagesize();
|
||||||
<filename>/sys/class/uio/uioX/portio/</filename>.
|
<filename>/sys/class/uio/uioX/portio/</filename>.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Each <filename>portX/</filename> directory contains three read-only
|
Each <filename>portX/</filename> directory contains four read-only
|
||||||
files that show start, size, and type of the port region:
|
files that show name, start, size, and type of the port region:
|
||||||
</para>
|
</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<filename>name</filename>: A string identifier for this port region.
|
||||||
|
The string is optional and can be empty. Drivers can set it to make it
|
||||||
|
easier for userspace to find a certain port region.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<filename>start</filename>: The first port of this region.
|
<filename>start</filename>: The first port of this region.
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||||
<book>
|
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||||
<?dbhtml filename="index.html">
|
|
||||||
|
|
||||||
<!-- ****************************************************** -->
|
<!-- ****************************************************** -->
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<!-- ****************************************************** -->
|
<!-- ****************************************************** -->
|
||||||
|
<book id="Writing-an-ALSA-Driver">
|
||||||
<bookinfo>
|
<bookinfo>
|
||||||
<title>Writing an ALSA Driver</title>
|
<title>Writing an ALSA Driver</title>
|
||||||
<author>
|
<author>
|
||||||
|
@ -492,9 +492,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (2) */
|
/* (2) */
|
||||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
|
||||||
if (card == NULL)
|
if (err < 0)
|
||||||
return -ENOMEM;
|
return err;
|
||||||
|
|
||||||
/* (3) */
|
/* (3) */
|
||||||
err = snd_mychip_create(card, pci, &chip);
|
err = snd_mychip_create(card, pci, &chip);
|
||||||
|
@ -590,8 +590,9 @@
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
|
int err;
|
||||||
....
|
....
|
||||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
|
||||||
]]>
|
]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</informalexample>
|
</informalexample>
|
||||||
|
@ -809,26 +810,28 @@
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
As mentioned above, to create a card instance, call
|
As mentioned above, to create a card instance, call
|
||||||
<function>snd_card_new()</function>.
|
<function>snd_card_create()</function>.
|
||||||
|
|
||||||
<informalexample>
|
<informalexample>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
card = snd_card_new(index, id, module, extra_size);
|
int err;
|
||||||
|
err = snd_card_create(index, id, module, extra_size, &card);
|
||||||
]]>
|
]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</informalexample>
|
</informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The function takes four arguments, the card-index number, the
|
The function takes five arguments, the card-index number, the
|
||||||
id string, the module pointer (usually
|
id string, the module pointer (usually
|
||||||
<constant>THIS_MODULE</constant>),
|
<constant>THIS_MODULE</constant>),
|
||||||
and the size of extra-data space. The last argument is used to
|
the size of extra-data space, and the pointer to return the
|
||||||
|
card instance. The extra_size argument is used to
|
||||||
allocate card->private_data for the
|
allocate card->private_data for the
|
||||||
chip-specific data. Note that these data
|
chip-specific data. Note that these data
|
||||||
are allocated by <function>snd_card_new()</function>.
|
are allocated by <function>snd_card_create()</function>.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -915,15 +918,16 @@
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section id="card-management-chip-specific-snd-card-new">
|
<section id="card-management-chip-specific-snd-card-new">
|
||||||
<title>1. Allocating via <function>snd_card_new()</function>.</title>
|
<title>1. Allocating via <function>snd_card_create()</function>.</title>
|
||||||
<para>
|
<para>
|
||||||
As mentioned above, you can pass the extra-data-length
|
As mentioned above, you can pass the extra-data-length
|
||||||
to the 4th argument of <function>snd_card_new()</function>, i.e.
|
to the 4th argument of <function>snd_card_create()</function>, i.e.
|
||||||
|
|
||||||
<informalexample>
|
<informalexample>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct mychip));
|
err = snd_card_create(index[dev], id[dev], THIS_MODULE,
|
||||||
|
sizeof(struct mychip), &card);
|
||||||
]]>
|
]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</informalexample>
|
</informalexample>
|
||||||
|
@ -952,8 +956,8 @@
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
After allocating a card instance via
|
After allocating a card instance via
|
||||||
<function>snd_card_new()</function> (with
|
<function>snd_card_create()</function> (with
|
||||||
<constant>NULL</constant> on the 4th arg), call
|
<constant>0</constant> on the 4th arg), call
|
||||||
<function>kzalloc()</function>.
|
<function>kzalloc()</function>.
|
||||||
|
|
||||||
<informalexample>
|
<informalexample>
|
||||||
|
@ -961,7 +965,7 @@
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct mychip *chip;
|
struct mychip *chip;
|
||||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
|
err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
|
||||||
.....
|
.....
|
||||||
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
||||||
]]>
|
]]>
|
||||||
|
@ -5750,8 +5754,9 @@ struct _snd_pcm_runtime {
|
||||||
....
|
....
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct mychip *chip;
|
struct mychip *chip;
|
||||||
|
int err;
|
||||||
....
|
....
|
||||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
|
err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
|
||||||
....
|
....
|
||||||
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
||||||
....
|
....
|
||||||
|
@ -5763,7 +5768,7 @@ struct _snd_pcm_runtime {
|
||||||
</informalexample>
|
</informalexample>
|
||||||
|
|
||||||
When you created the chip data with
|
When you created the chip data with
|
||||||
<function>snd_card_new()</function>, it's anyway accessible
|
<function>snd_card_create()</function>, it's anyway accessible
|
||||||
via <structfield>private_data</structfield> field.
|
via <structfield>private_data</structfield> field.
|
||||||
|
|
||||||
<informalexample>
|
<informalexample>
|
||||||
|
@ -5775,9 +5780,10 @@ struct _snd_pcm_runtime {
|
||||||
....
|
....
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct mychip *chip;
|
struct mychip *chip;
|
||||||
|
int err;
|
||||||
....
|
....
|
||||||
card = snd_card_new(index[dev], id[dev], THIS_MODULE,
|
err = snd_card_create(index[dev], id[dev], THIS_MODULE,
|
||||||
sizeof(struct mychip));
|
sizeof(struct mychip), &card);
|
||||||
....
|
....
|
||||||
chip = card->private_data;
|
chip = card->private_data;
|
||||||
....
|
....
|
|
@ -4,506 +4,356 @@
|
||||||
Revised Feb 12, 2004 by Martine Silbermann
|
Revised Feb 12, 2004 by Martine Silbermann
|
||||||
email: Martine.Silbermann@hp.com
|
email: Martine.Silbermann@hp.com
|
||||||
Revised Jun 25, 2004 by Tom L Nguyen
|
Revised Jun 25, 2004 by Tom L Nguyen
|
||||||
|
Revised Jul 9, 2008 by Matthew Wilcox <willy@linux.intel.com>
|
||||||
|
Copyright 2003, 2008 Intel Corporation
|
||||||
|
|
||||||
1. About this guide
|
1. About this guide
|
||||||
|
|
||||||
This guide describes the basics of Message Signaled Interrupts (MSI),
|
This guide describes the basics of Message Signaled Interrupts (MSIs),
|
||||||
the advantages of using MSI over traditional interrupt mechanisms,
|
the advantages of using MSI over traditional interrupt mechanisms, how
|
||||||
and how to enable your driver to use MSI or MSI-X. Also included is
|
to change your driver to use MSI or MSI-X and some basic diagnostics to
|
||||||
a Frequently Asked Questions (FAQ) section.
|
try if a device doesn't support MSIs.
|
||||||
|
|
||||||
1.1 Terminology
|
|
||||||
|
|
||||||
PCI devices can be single-function or multi-function. In either case,
|
2. What are MSIs?
|
||||||
when this text talks about enabling or disabling MSI on a "device
|
|
||||||
function," it is referring to one specific PCI device and function and
|
|
||||||
not to all functions on a PCI device (unless the PCI device has only
|
|
||||||
one function).
|
|
||||||
|
|
||||||
2. Copyright 2003 Intel Corporation
|
A Message Signaled Interrupt is a write from the device to a special
|
||||||
|
address which causes an interrupt to be received by the CPU.
|
||||||
|
|
||||||
3. What is MSI/MSI-X?
|
The MSI capability was first specified in PCI 2.2 and was later enhanced
|
||||||
|
in PCI 3.0 to allow each interrupt to be masked individually. The MSI-X
|
||||||
|
capability was also introduced with PCI 3.0. It supports more interrupts
|
||||||
|
per device than MSI and allows interrupts to be independently configured.
|
||||||
|
|
||||||
Message Signaled Interrupt (MSI), as described in the PCI Local Bus
|
Devices may support both MSI and MSI-X, but only one can be enabled at
|
||||||
Specification Revision 2.3 or later, is an optional feature, and a
|
a time.
|
||||||
required feature for PCI Express devices. MSI enables a device function
|
|
||||||
to request service by sending an Inbound Memory Write on its PCI bus to
|
|
||||||
the FSB as a Message Signal Interrupt transaction. Because MSI is
|
|
||||||
generated in the form of a Memory Write, all transaction conditions,
|
|
||||||
such as a Retry, Master-Abort, Target-Abort or normal completion, are
|
|
||||||
supported.
|
|
||||||
|
|
||||||
A PCI device that supports MSI must also support pin IRQ assertion
|
|
||||||
interrupt mechanism to provide backward compatibility for systems that
|
|
||||||
do not support MSI. In systems which support MSI, the bus driver is
|
|
||||||
responsible for initializing the message address and message data of
|
|
||||||
the device function's MSI/MSI-X capability structure during device
|
|
||||||
initial configuration.
|
|
||||||
|
|
||||||
An MSI capable device function indicates MSI support by implementing
|
3. Why use MSIs?
|
||||||
the MSI/MSI-X capability structure in its PCI capability list. The
|
|
||||||
device function may implement both the MSI capability structure and
|
|
||||||
the MSI-X capability structure; however, the bus driver should not
|
|
||||||
enable both.
|
|
||||||
|
|
||||||
The MSI capability structure contains Message Control register,
|
There are three reasons why using MSIs can give an advantage over
|
||||||
Message Address register and Message Data register. These registers
|
traditional pin-based interrupts.
|
||||||
provide the bus driver control over MSI. The Message Control register
|
|
||||||
indicates the MSI capability supported by the device. The Message
|
|
||||||
Address register specifies the target address and the Message Data
|
|
||||||
register specifies the characteristics of the message. To request
|
|
||||||
service, the device function writes the content of the Message Data
|
|
||||||
register to the target address. The device and its software driver
|
|
||||||
are prohibited from writing to these registers.
|
|
||||||
|
|
||||||
The MSI-X capability structure is an optional extension to MSI. It
|
Pin-based PCI interrupts are often shared amongst several devices.
|
||||||
uses an independent and separate capability structure. There are
|
To support this, the kernel must call each interrupt handler associated
|
||||||
some key advantages to implementing the MSI-X capability structure
|
with an interrupt, which leads to reduced performance for the system as
|
||||||
over the MSI capability structure as described below.
|
a whole. MSIs are never shared, so this problem cannot arise.
|
||||||
|
|
||||||
- Support a larger maximum number of vectors per function.
|
When a device writes data to memory, then raises a pin-based interrupt,
|
||||||
|
it is possible that the interrupt may arrive before all the data has
|
||||||
|
arrived in memory (this becomes more likely with devices behind PCI-PCI
|
||||||
|
bridges). In order to ensure that all the data has arrived in memory,
|
||||||
|
the interrupt handler must read a register on the device which raised
|
||||||
|
the interrupt. PCI transaction ordering rules require that all the data
|
||||||
|
arrives in memory before the value can be returned from the register.
|
||||||
|
Using MSIs avoids this problem as the interrupt-generating write cannot
|
||||||
|
pass the data writes, so by the time the interrupt is raised, the driver
|
||||||
|
knows that all the data has arrived in memory.
|
||||||
|
|
||||||
- Provide the ability for system software to configure
|
PCI devices can only support a single pin-based interrupt per function.
|
||||||
each vector with an independent message address and message
|
Often drivers have to query the device to find out what event has
|
||||||
data, specified by a table that resides in Memory Space.
|
occurred, slowing down interrupt handling for the common case. With
|
||||||
|
MSIs, a device can support more interrupts, allowing each interrupt
|
||||||
|
to be specialised to a different purpose. One possible design gives
|
||||||
|
infrequent conditions (such as errors) their own interrupt which allows
|
||||||
|
the driver to handle the normal interrupt handling path more efficiently.
|
||||||
|
Other possible designs include giving one interrupt to each packet queue
|
||||||
|
in a network card or each port in a storage controller.
|
||||||
|
|
||||||
- MSI and MSI-X both support per-vector masking. Per-vector
|
|
||||||
masking is an optional extension of MSI but a required
|
|
||||||
feature for MSI-X. Per-vector masking provides the kernel the
|
|
||||||
ability to mask/unmask a single MSI while running its
|
|
||||||
interrupt service routine. If per-vector masking is
|
|
||||||
not supported, then the device driver should provide the
|
|
||||||
hardware/software synchronization to ensure that the device
|
|
||||||
generates MSI when the driver wants it to do so.
|
|
||||||
|
|
||||||
4. Why use MSI?
|
4. How to use MSIs
|
||||||
|
|
||||||
As a benefit to the simplification of board design, MSI allows board
|
PCI devices are initialised to use pin-based interrupts. The device
|
||||||
designers to remove out-of-band interrupt routing. MSI is another
|
driver has to set up the device to use MSI or MSI-X. Not all machines
|
||||||
step towards a legacy-free environment.
|
support MSIs correctly, and for those machines, the APIs described below
|
||||||
|
will simply fail and the device will continue to use pin-based interrupts.
|
||||||
|
|
||||||
Due to increasing pressure on chipset and processor packages to
|
4.1 Include kernel support for MSIs
|
||||||
reduce pin count, the need for interrupt pins is expected to
|
|
||||||
diminish over time. Devices, due to pin constraints, may implement
|
|
||||||
messages to increase performance.
|
|
||||||
|
|
||||||
PCI Express endpoints uses INTx emulation (in-band messages) instead
|
To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI
|
||||||
of IRQ pin assertion. Using INTx emulation requires interrupt
|
option enabled. This option is only available on some architectures,
|
||||||
sharing among devices connected to the same node (PCI bridge) while
|
and it may depend on some other options also being set. For example,
|
||||||
MSI is unique (non-shared) and does not require BIOS configuration
|
on x86, you must also enable X86_UP_APIC or SMP in order to see the
|
||||||
support. As a result, the PCI Express technology requires MSI
|
CONFIG_PCI_MSI option.
|
||||||
support for better interrupt performance.
|
|
||||||
|
|
||||||
Using MSI enables the device functions to support two or more
|
4.2 Using MSI
|
||||||
vectors, which can be configured to target different CPUs to
|
|
||||||
increase scalability.
|
|
||||||
|
|
||||||
5. Configuring a driver to use MSI/MSI-X
|
Most of the hard work is done for the driver in the PCI layer. It simply
|
||||||
|
has to request that the PCI layer set up the MSI capability for this
|
||||||
|
device.
|
||||||
|
|
||||||
By default, the kernel will not enable MSI/MSI-X on all devices that
|
4.2.1 pci_enable_msi
|
||||||
support this capability. The CONFIG_PCI_MSI kernel option
|
|
||||||
must be selected to enable MSI/MSI-X support.
|
|
||||||
|
|
||||||
5.1 Including MSI/MSI-X support into the kernel
|
|
||||||
|
|
||||||
To allow MSI/MSI-X capable device drivers to selectively enable
|
|
||||||
MSI/MSI-X (using pci_enable_msi()/pci_enable_msix() as described
|
|
||||||
below), the VECTOR based scheme needs to be enabled by setting
|
|
||||||
CONFIG_PCI_MSI during kernel config.
|
|
||||||
|
|
||||||
Since the target of the inbound message is the local APIC, providing
|
|
||||||
CONFIG_X86_LOCAL_APIC must be enabled as well as CONFIG_PCI_MSI.
|
|
||||||
|
|
||||||
5.2 Configuring for MSI support
|
|
||||||
|
|
||||||
Due to the non-contiguous fashion in vector assignment of the
|
|
||||||
existing Linux kernel, this version does not support multiple
|
|
||||||
messages regardless of a device function is capable of supporting
|
|
||||||
more than one vector. To enable MSI on a device function's MSI
|
|
||||||
capability structure requires a device driver to call the function
|
|
||||||
pci_enable_msi() explicitly.
|
|
||||||
|
|
||||||
5.2.1 API pci_enable_msi
|
|
||||||
|
|
||||||
int pci_enable_msi(struct pci_dev *dev)
|
int pci_enable_msi(struct pci_dev *dev)
|
||||||
|
|
||||||
With this new API, a device driver that wants to have MSI
|
A successful call will allocate ONE interrupt to the device, regardless
|
||||||
enabled on its device function must call this API to enable MSI.
|
of how many MSIs the device supports. The device will be switched from
|
||||||
A successful call will initialize the MSI capability structure
|
pin-based interrupt mode to MSI mode. The dev->irq number is changed
|
||||||
with ONE vector, regardless of whether a device function is
|
to a new number which represents the message signaled interrupt.
|
||||||
capable of supporting multiple messages. This vector replaces the
|
This function should be called before the driver calls request_irq()
|
||||||
pre-assigned dev->irq with a new MSI vector. To avoid a conflict
|
since enabling MSIs disables the pin-based IRQ and the driver will not
|
||||||
of the new assigned vector with existing pre-assigned vector requires
|
receive interrupts on the old interrupt.
|
||||||
a device driver to call this API before calling request_irq().
|
|
||||||
|
|
||||||
5.2.2 API pci_disable_msi
|
4.2.2 pci_enable_msi_block
|
||||||
|
|
||||||
|
int pci_enable_msi_block(struct pci_dev *dev, int count)
|
||||||
|
|
||||||
|
This variation on the above call allows a device driver to request multiple
|
||||||
|
MSIs. The MSI specification only allows interrupts to be allocated in
|
||||||
|
powers of two, up to a maximum of 2^5 (32).
|
||||||
|
|
||||||
|
If this function returns 0, it has succeeded in allocating at least as many
|
||||||
|
interrupts as the driver requested (it may have allocated more in order
|
||||||
|
to satisfy the power-of-two requirement). In this case, the function
|
||||||
|
enables MSI on this device and updates dev->irq to be the lowest of
|
||||||
|
the new interrupts assigned to it. The other interrupts assigned to
|
||||||
|
the device are in the range dev->irq to dev->irq + count - 1.
|
||||||
|
|
||||||
|
If this function returns a negative number, it indicates an error and
|
||||||
|
the driver should not attempt to request any more MSI interrupts for
|
||||||
|
this device. If this function returns a positive number, it will be
|
||||||
|
less than 'count' and indicate the number of interrupts that could have
|
||||||
|
been allocated. In neither case will the irq value have been
|
||||||
|
updated, nor will the device have been switched into MSI mode.
|
||||||
|
|
||||||
|
The device driver must decide what action to take if
|
||||||
|
pci_enable_msi_block() returns a value less than the number asked for.
|
||||||
|
Some devices can make use of fewer interrupts than the maximum they
|
||||||
|
request; in this case the driver should call pci_enable_msi_block()
|
||||||
|
again. Note that it is not guaranteed to succeed, even when the
|
||||||
|
'count' has been reduced to the value returned from a previous call to
|
||||||
|
pci_enable_msi_block(). This is because there are multiple constraints
|
||||||
|
on the number of vectors that can be allocated; pci_enable_msi_block()
|
||||||
|
will return as soon as it finds any constraint that doesn't allow the
|
||||||
|
call to succeed.
|
||||||
|
|
||||||
|
4.2.3 pci_disable_msi
|
||||||
|
|
||||||
void pci_disable_msi(struct pci_dev *dev)
|
void pci_disable_msi(struct pci_dev *dev)
|
||||||
|
|
||||||
This API should always be used to undo the effect of pci_enable_msi()
|
This function should be used to undo the effect of pci_enable_msi() or
|
||||||
when a device driver is unloading. This API restores dev->irq with
|
pci_enable_msi_block(). Calling it restores dev->irq to the pin-based
|
||||||
the pre-assigned IOAPIC vector and switches a device's interrupt
|
interrupt number and frees the previously allocated message signaled
|
||||||
mode to PCI pin-irq assertion/INTx emulation mode.
|
interrupt(s). The interrupt may subsequently be assigned to another
|
||||||
|
device, so drivers should not cache the value of dev->irq.
|
||||||
|
|
||||||
Note that a device driver should always call free_irq() on the MSI vector
|
A device driver must always call free_irq() on the interrupt(s)
|
||||||
that it has done request_irq() on before calling this API. Failure to do
|
for which it has called request_irq() before calling this function.
|
||||||
so results in a BUG_ON() and a device will be left with MSI enabled and
|
Failure to do so will result in a BUG_ON(), the device will be left with
|
||||||
leaks its vector.
|
MSI enabled and will leak its vector.
|
||||||
|
|
||||||
5.2.3 MSI mode vs. legacy mode diagram
|
4.3 Using MSI-X
|
||||||
|
|
||||||
The below diagram shows the events which switch the interrupt
|
The MSI-X capability is much more flexible than the MSI capability.
|
||||||
mode on the MSI-capable device function between MSI mode and
|
It supports up to 2048 interrupts, each of which can be controlled
|
||||||
PIN-IRQ assertion mode.
|
independently. To support this flexibility, drivers must use an array of
|
||||||
|
`struct msix_entry':
|
||||||
------------ pci_enable_msi ------------------------
|
|
||||||
| | <=============== | |
|
|
||||||
| MSI MODE | | PIN-IRQ ASSERTION MODE |
|
|
||||||
| | ===============> | |
|
|
||||||
------------ pci_disable_msi ------------------------
|
|
||||||
|
|
||||||
|
|
||||||
Figure 1. MSI Mode vs. Legacy Mode
|
|
||||||
|
|
||||||
In Figure 1, a device operates by default in legacy mode. Legacy
|
|
||||||
in this context means PCI pin-irq assertion or PCI-Express INTx
|
|
||||||
emulation. A successful MSI request (using pci_enable_msi()) switches
|
|
||||||
a device's interrupt mode to MSI mode. A pre-assigned IOAPIC vector
|
|
||||||
stored in dev->irq will be saved by the PCI subsystem and a new
|
|
||||||
assigned MSI vector will replace dev->irq.
|
|
||||||
|
|
||||||
To return back to its default mode, a device driver should always call
|
|
||||||
pci_disable_msi() to undo the effect of pci_enable_msi(). Note that a
|
|
||||||
device driver should always call free_irq() on the MSI vector it has
|
|
||||||
done request_irq() on before calling pci_disable_msi(). Failure to do
|
|
||||||
so results in a BUG_ON() and a device will be left with MSI enabled and
|
|
||||||
leaks its vector. Otherwise, the PCI subsystem restores a device's
|
|
||||||
dev->irq with a pre-assigned IOAPIC vector and marks the released
|
|
||||||
MSI vector as unused.
|
|
||||||
|
|
||||||
Once being marked as unused, there is no guarantee that the PCI
|
|
||||||
subsystem will reserve this MSI vector for a device. Depending on
|
|
||||||
the availability of current PCI vector resources and the number of
|
|
||||||
MSI/MSI-X requests from other drivers, this MSI may be re-assigned.
|
|
||||||
|
|
||||||
For the case where the PCI subsystem re-assigns this MSI vector to
|
|
||||||
another driver, a request to switch back to MSI mode may result
|
|
||||||
in being assigned a different MSI vector or a failure if no more
|
|
||||||
vectors are available.
|
|
||||||
|
|
||||||
5.3 Configuring for MSI-X support
|
|
||||||
|
|
||||||
Due to the ability of the system software to configure each vector of
|
|
||||||
the MSI-X capability structure with an independent message address
|
|
||||||
and message data, the non-contiguous fashion in vector assignment of
|
|
||||||
the existing Linux kernel has no impact on supporting multiple
|
|
||||||
messages on an MSI-X capable device functions. To enable MSI-X on
|
|
||||||
a device function's MSI-X capability structure requires its device
|
|
||||||
driver to call the function pci_enable_msix() explicitly.
|
|
||||||
|
|
||||||
The function pci_enable_msix(), once invoked, enables either
|
|
||||||
all or nothing, depending on the current availability of PCI vector
|
|
||||||
resources. If the PCI vector resources are available for the number
|
|
||||||
of vectors requested by a device driver, this function will configure
|
|
||||||
the MSI-X table of the MSI-X capability structure of a device with
|
|
||||||
requested messages. To emphasize this reason, for example, a device
|
|
||||||
may be capable for supporting the maximum of 32 vectors while its
|
|
||||||
software driver usually may request 4 vectors. It is recommended
|
|
||||||
that the device driver should call this function once during the
|
|
||||||
initialization phase of the device driver.
|
|
||||||
|
|
||||||
Unlike the function pci_enable_msi(), the function pci_enable_msix()
|
|
||||||
does not replace the pre-assigned IOAPIC dev->irq with a new MSI
|
|
||||||
vector because the PCI subsystem writes the 1:1 vector-to-entry mapping
|
|
||||||
into the field vector of each element contained in a second argument.
|
|
||||||
Note that the pre-assigned IOAPIC dev->irq is valid only if the device
|
|
||||||
operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at
|
|
||||||
using dev->irq by the device driver to request for interrupt service
|
|
||||||
may result in unpredictable behavior.
|
|
||||||
|
|
||||||
For each MSI-X vector granted, a device driver is responsible for calling
|
|
||||||
other functions like request_irq(), enable_irq(), etc. to enable
|
|
||||||
this vector with its corresponding interrupt service handler. It is
|
|
||||||
a device driver's choice to assign all vectors with the same
|
|
||||||
interrupt service handler or each vector with a unique interrupt
|
|
||||||
service handler.
|
|
||||||
|
|
||||||
5.3.1 Handling MMIO address space of MSI-X Table
|
|
||||||
|
|
||||||
The PCI 3.0 specification has implementation notes that MMIO address
|
|
||||||
space for a device's MSI-X structure should be isolated so that the
|
|
||||||
software system can set different pages for controlling accesses to the
|
|
||||||
MSI-X structure. The implementation of MSI support requires the PCI
|
|
||||||
subsystem, not a device driver, to maintain full control of the MSI-X
|
|
||||||
table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
|
|
||||||
table/MSI-X PBA. A device driver should not access the MMIO address
|
|
||||||
space of the MSI-X table/MSI-X PBA.
|
|
||||||
|
|
||||||
5.3.2 API pci_enable_msix
|
|
||||||
|
|
||||||
int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
|
|
||||||
|
|
||||||
This API enables a device driver to request the PCI subsystem
|
|
||||||
to enable MSI-X messages on its hardware device. Depending on
|
|
||||||
the availability of PCI vectors resources, the PCI subsystem enables
|
|
||||||
either all or none of the requested vectors.
|
|
||||||
|
|
||||||
Argument 'dev' points to the device (pci_dev) structure.
|
|
||||||
|
|
||||||
Argument 'entries' is a pointer to an array of msix_entry structs.
|
|
||||||
The number of entries is indicated in argument 'nvec'.
|
|
||||||
struct msix_entry is defined in /driver/pci/msi.h:
|
|
||||||
|
|
||||||
struct msix_entry {
|
struct msix_entry {
|
||||||
u16 vector; /* kernel uses to write alloc vector */
|
u16 vector; /* kernel uses to write alloc vector */
|
||||||
u16 entry; /* driver uses to specify entry */
|
u16 entry; /* driver uses to specify entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
A device driver is responsible for initializing the field 'entry' of
|
This allows for the device to use these interrupts in a sparse fashion;
|
||||||
each element with a unique entry supported by MSI-X table. Otherwise,
|
for example it could use interrupts 3 and 1027 and allocate only a
|
||||||
-EINVAL will be returned as a result. A successful return of zero
|
two-element array. The driver is expected to fill in the 'entry' value
|
||||||
indicates the PCI subsystem completed initializing each of the requested
|
in each element of the array to indicate which entries it wants the kernel
|
||||||
entries of the MSI-X table with message address and message data.
|
to assign interrupts for. It is invalid to fill in two entries with the
|
||||||
Last but not least, the PCI subsystem will write the 1:1
|
same number.
|
||||||
vector-to-entry mapping into the field 'vector' of each element. A
|
|
||||||
device driver is responsible for keeping track of allocated MSI-X
|
|
||||||
vectors in its internal data structure.
|
|
||||||
|
|
||||||
A return of zero indicates that the number of MSI-X vectors was
|
4.3.1 pci_enable_msix
|
||||||
successfully allocated. A return of greater than zero indicates
|
|
||||||
MSI-X vector shortage. Or a return of less than zero indicates
|
|
||||||
a failure. This failure may be a result of duplicate entries
|
|
||||||
specified in second argument, or a result of no available vector,
|
|
||||||
or a result of failing to initialize MSI-X table entries.
|
|
||||||
|
|
||||||
5.3.3 API pci_disable_msix
|
int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
|
||||||
|
|
||||||
|
Calling this function asks the PCI subsystem to allocate 'nvec' MSIs.
|
||||||
|
The 'entries' argument is a pointer to an array of msix_entry structs
|
||||||
|
which should be at least 'nvec' entries in size. On success, the
|
||||||
|
function will return 0 and the device will have been switched into
|
||||||
|
MSI-X interrupt mode. The 'vector' elements in each entry will have
|
||||||
|
been filled in with the interrupt number. The driver should then call
|
||||||
|
request_irq() for each 'vector' that it decides to use.
|
||||||
|
|
||||||
|
If this function returns a negative number, it indicates an error and
|
||||||
|
the driver should not attempt to allocate any more MSI-X interrupts for
|
||||||
|
this device. If it returns a positive number, it indicates the maximum
|
||||||
|
number of interrupt vectors that could have been allocated. See example
|
||||||
|
below.
|
||||||
|
|
||||||
|
This function, in contrast with pci_enable_msi(), does not adjust
|
||||||
|
dev->irq. The device will not generate interrupts for this interrupt
|
||||||
|
number once MSI-X is enabled. The device driver is responsible for
|
||||||
|
keeping track of the interrupts assigned to the MSI-X vectors so it can
|
||||||
|
free them again later.
|
||||||
|
|
||||||
|
Device drivers should normally call this function once per device
|
||||||
|
during the initialization phase.
|
||||||
|
|
||||||
|
It is ideal if drivers can cope with a variable number of MSI-X interrupts,
|
||||||
|
there are many reasons why the platform may not be able to provide the
|
||||||
|
exact number a driver asks for.
|
||||||
|
|
||||||
|
A request loop to achieve that might look like:
|
||||||
|
|
||||||
|
static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
|
||||||
|
{
|
||||||
|
while (nvec >= FOO_DRIVER_MINIMUM_NVEC) {
|
||||||
|
rc = pci_enable_msix(adapter->pdev,
|
||||||
|
adapter->msix_entries, nvec);
|
||||||
|
if (rc > 0)
|
||||||
|
nvec = rc;
|
||||||
|
else
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
4.3.2 pci_disable_msix
|
||||||
|
|
||||||
void pci_disable_msix(struct pci_dev *dev)
|
void pci_disable_msix(struct pci_dev *dev)
|
||||||
|
|
||||||
This API should always be used to undo the effect of pci_enable_msix()
|
This API should be used to undo the effect of pci_enable_msix(). It frees
|
||||||
when a device driver is unloading. Note that a device driver should
|
the previously allocated message signaled interrupts. The interrupts may
|
||||||
always call free_irq() on all MSI-X vectors it has done request_irq()
|
subsequently be assigned to another device, so drivers should not cache
|
||||||
on before calling this API. Failure to do so results in a BUG_ON() and
|
the value of the 'vector' elements over a call to pci_disable_msix().
|
||||||
a device will be left with MSI-X enabled and leaks its vectors.
|
|
||||||
|
|
||||||
5.3.4 MSI-X mode vs. legacy mode diagram
|
A device driver must always call free_irq() on the interrupt(s)
|
||||||
|
for which it has called request_irq() before calling this function.
|
||||||
|
Failure to do so will result in a BUG_ON(), the device will be left with
|
||||||
|
MSI enabled and will leak its vector.
|
||||||
|
|
||||||
The below diagram shows the events which switch the interrupt
|
4.3.3 The MSI-X Table
|
||||||
mode on the MSI-X capable device function between MSI-X mode and
|
|
||||||
PIN-IRQ assertion mode (legacy).
|
|
||||||
|
|
||||||
------------ pci_enable_msix(,,n) ------------------------
|
The MSI-X capability specifies a BAR and offset within that BAR for the
|
||||||
| | <=============== | |
|
MSI-X Table. This address is mapped by the PCI subsystem, and should not
|
||||||
| MSI-X MODE | | PIN-IRQ ASSERTION MODE |
|
be accessed directly by the device driver. If the driver wishes to
|
||||||
| | ===============> | |
|
mask or unmask an interrupt, it should call disable_irq() / enable_irq().
|
||||||
------------ pci_disable_msix ------------------------
|
|
||||||
|
|
||||||
Figure 2. MSI-X Mode vs. Legacy Mode
|
4.4 Handling devices implementing both MSI and MSI-X capabilities
|
||||||
|
|
||||||
In Figure 2, a device operates by default in legacy mode. A
|
If a device implements both MSI and MSI-X capabilities, it can
|
||||||
successful MSI-X request (using pci_enable_msix()) switches a
|
run in either MSI mode or MSI-X mode but not both simultaneously.
|
||||||
device's interrupt mode to MSI-X mode. A pre-assigned IOAPIC vector
|
This is a requirement of the PCI spec, and it is enforced by the
|
||||||
stored in dev->irq will be saved by the PCI subsystem; however,
|
PCI layer. Calling pci_enable_msi() when MSI-X is already enabled or
|
||||||
unlike MSI mode, the PCI subsystem will not replace dev->irq with
|
pci_enable_msix() when MSI is already enabled will result in an error.
|
||||||
assigned MSI-X vector because the PCI subsystem already writes the 1:1
|
If a device driver wishes to switch between MSI and MSI-X at runtime,
|
||||||
vector-to-entry mapping into the field 'vector' of each element
|
it must first quiesce the device, then switch it back to pin-interrupt
|
||||||
specified in second argument.
|
mode, before calling pci_enable_msi() or pci_enable_msix() and resuming
|
||||||
|
operation. This is not expected to be a common operation but may be
|
||||||
|
useful for debugging or testing during development.
|
||||||
|
|
||||||
To return back to its default mode, a device driver should always call
|
4.5 Considerations when using MSIs
|
||||||
pci_disable_msix() to undo the effect of pci_enable_msix(). Note that
|
|
||||||
a device driver should always call free_irq() on all MSI-X vectors it
|
|
||||||
has done request_irq() on before calling pci_disable_msix(). Failure
|
|
||||||
to do so results in a BUG_ON() and a device will be left with MSI-X
|
|
||||||
enabled and leaks its vectors. Otherwise, the PCI subsystem switches a
|
|
||||||
device function's interrupt mode from MSI-X mode to legacy mode and
|
|
||||||
marks all allocated MSI-X vectors as unused.
|
|
||||||
|
|
||||||
Once being marked as unused, there is no guarantee that the PCI
|
4.5.1 Choosing between MSI-X and MSI
|
||||||
subsystem will reserve these MSI-X vectors for a device. Depending on
|
|
||||||
the availability of current PCI vector resources and the number of
|
|
||||||
MSI/MSI-X requests from other drivers, these MSI-X vectors may be
|
|
||||||
re-assigned.
|
|
||||||
|
|
||||||
For the case where the PCI subsystem re-assigned these MSI-X vectors
|
If your device supports both MSI-X and MSI capabilities, you should use
|
||||||
to other drivers, a request to switch back to MSI-X mode may result
|
the MSI-X facilities in preference to the MSI facilities. As mentioned
|
||||||
being assigned with another set of MSI-X vectors or a failure if no
|
above, MSI-X supports any number of interrupts between 1 and 2048.
|
||||||
more vectors are available.
|
In constrast, MSI is restricted to a maximum of 32 interrupts (and
|
||||||
|
must be a power of two). In addition, the MSI interrupt vectors must
|
||||||
|
be allocated consecutively, so the system may not be able to allocate
|
||||||
|
as many vectors for MSI as it could for MSI-X. On some platforms, MSI
|
||||||
|
interrupts must all be targetted at the same set of CPUs whereas MSI-X
|
||||||
|
interrupts can all be targetted at different CPUs.
|
||||||
|
|
||||||
5.4 Handling function implementing both MSI and MSI-X capabilities
|
4.5.2 Spinlocks
|
||||||
|
|
||||||
For the case where a function implements both MSI and MSI-X
|
Most device drivers have a per-device spinlock which is taken in the
|
||||||
capabilities, the PCI subsystem enables a device to run either in MSI
|
interrupt handler. With pin-based interrupts or a single MSI, it is not
|
||||||
mode or MSI-X mode but not both. A device driver determines whether it
|
necessary to disable interrupts (Linux guarantees the same interrupt will
|
||||||
wants MSI or MSI-X enabled on its hardware device. Once a device
|
not be re-entered). If a device uses multiple interrupts, the driver
|
||||||
driver requests for MSI, for example, it is prohibited from requesting
|
must disable interrupts while the lock is held. If the device sends
|
||||||
MSI-X; in other words, a device driver is not permitted to ping-pong
|
a different interrupt, the driver will deadlock trying to recursively
|
||||||
between MSI mod MSI-X mode during a run-time.
|
acquire the spinlock.
|
||||||
|
|
||||||
5.5 Hardware requirements for MSI/MSI-X support
|
There are two solutions. The first is to take the lock with
|
||||||
|
spin_lock_irqsave() or spin_lock_irq() (see
|
||||||
|
Documentation/DocBook/kernel-locking). The second is to specify
|
||||||
|
IRQF_DISABLED to request_irq() so that the kernel runs the entire
|
||||||
|
interrupt routine with interrupts disabled.
|
||||||
|
|
||||||
MSI/MSI-X support requires support from both system hardware and
|
If your MSI interrupt routine does not hold the lock for the whole time
|
||||||
individual hardware device functions.
|
it is running, the first solution may be best. The second solution is
|
||||||
|
normally preferred as it avoids making two transitions from interrupt
|
||||||
|
disabled to enabled and back again.
|
||||||
|
|
||||||
5.5.1 Required x86 hardware support
|
4.6 How to tell whether MSI/MSI-X is enabled on a device
|
||||||
|
|
||||||
Since the target of MSI address is the local APIC CPU, enabling
|
Using 'lspci -v' (as root) may show some devices with "MSI", "Message
|
||||||
MSI/MSI-X support in the Linux kernel is dependent on whether existing
|
Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities
|
||||||
system hardware supports local APIC. Users should verify that their
|
has an 'Enable' flag which will be followed with either "+" (enabled)
|
||||||
system supports local APIC operation by testing that it runs when
|
or "-" (disabled).
|
||||||
CONFIG_X86_LOCAL_APIC=y.
|
|
||||||
|
|
||||||
In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
|
|
||||||
however, in UP environment, users must manually set
|
|
||||||
CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
|
|
||||||
CONFIG_PCI_MSI enables the VECTOR based scheme and the option for
|
|
||||||
MSI-capable device drivers to selectively enable MSI/MSI-X.
|
|
||||||
|
|
||||||
Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI/MSI-X
|
5. MSI quirks
|
||||||
vector is allocated new during runtime and MSI/MSI-X support does not
|
|
||||||
depend on BIOS support. This key independency enables MSI/MSI-X
|
|
||||||
support on future IOxAPIC free platforms.
|
|
||||||
|
|
||||||
5.5.2 Device hardware support
|
Several PCI chipsets or devices are known not to support MSIs.
|
||||||
|
The PCI stack provides three ways to disable MSIs:
|
||||||
|
|
||||||
The hardware device function supports MSI by indicating the
|
1. globally
|
||||||
MSI/MSI-X capability structure on its PCI capability list. By
|
2. on all devices behind a specific bridge
|
||||||
default, this capability structure will not be initialized by
|
3. on a single device
|
||||||
the kernel to enable MSI during the system boot. In other words,
|
|
||||||
the device function is running on its default pin assertion mode.
|
|
||||||
Note that in many cases the hardware supporting MSI have bugs,
|
|
||||||
which may result in system hangs. The software driver of specific
|
|
||||||
MSI-capable hardware is responsible for deciding whether to call
|
|
||||||
pci_enable_msi or not. A return of zero indicates the kernel
|
|
||||||
successfully initialized the MSI/MSI-X capability structure of the
|
|
||||||
device function. The device function is now running on MSI/MSI-X mode.
|
|
||||||
|
|
||||||
5.6 How to tell whether MSI/MSI-X is enabled on device function
|
5.1. Disabling MSIs globally
|
||||||
|
|
||||||
At the driver level, a return of zero from the function call of
|
Some host chipsets simply don't support MSIs properly. If we're
|
||||||
pci_enable_msi()/pci_enable_msix() indicates to a device driver that
|
lucky, the manufacturer knows this and has indicated it in the ACPI
|
||||||
its device function is initialized successfully and ready to run in
|
FADT table. In this case, Linux will automatically disable MSIs.
|
||||||
MSI/MSI-X mode.
|
Some boards don't include this information in the table and so we have
|
||||||
|
to detect them ourselves. The complete list of these is found near the
|
||||||
|
quirk_disable_all_msi() function in drivers/pci/quirks.c.
|
||||||
|
|
||||||
At the user level, users can use the command 'cat /proc/interrupts'
|
If you have a board which has problems with MSIs, you can pass pci=nomsi
|
||||||
to display the vectors allocated for devices and their interrupt
|
on the kernel command line to disable MSIs on all devices. It would be
|
||||||
MSI/MSI-X modes ("PCI-MSI"/"PCI-MSI-X"). Below shows MSI mode is
|
in your best interests to report the problem to linux-pci@vger.kernel.org
|
||||||
enabled on a SCSI Adaptec 39320D Ultra320 controller.
|
including a full 'lspci -v' so we can add the quirks to the kernel.
|
||||||
|
|
||||||
CPU0 CPU1
|
5.2. Disabling MSIs below a bridge
|
||||||
0: 324639 0 IO-APIC-edge timer
|
|
||||||
1: 1186 0 IO-APIC-edge i8042
|
|
||||||
2: 0 0 XT-PIC cascade
|
|
||||||
12: 2797 0 IO-APIC-edge i8042
|
|
||||||
14: 6543 0 IO-APIC-edge ide0
|
|
||||||
15: 1 0 IO-APIC-edge ide1
|
|
||||||
169: 0 0 IO-APIC-level uhci-hcd
|
|
||||||
185: 0 0 IO-APIC-level uhci-hcd
|
|
||||||
193: 138 10 PCI-MSI aic79xx
|
|
||||||
201: 30 0 PCI-MSI aic79xx
|
|
||||||
225: 30 0 IO-APIC-level aic7xxx
|
|
||||||
233: 30 0 IO-APIC-level aic7xxx
|
|
||||||
NMI: 0 0
|
|
||||||
LOC: 324553 325068
|
|
||||||
ERR: 0
|
|
||||||
MIS: 0
|
|
||||||
|
|
||||||
6. MSI quirks
|
Some PCI bridges are not able to route MSIs between busses properly.
|
||||||
|
In this case, MSIs must be disabled on all devices behind the bridge.
|
||||||
|
|
||||||
Several PCI chipsets or devices are known to not support MSI.
|
Some bridges allow you to enable MSIs by changing some bits in their
|
||||||
The PCI stack provides 3 possible levels of MSI disabling:
|
PCI configuration space (especially the Hypertransport chipsets such
|
||||||
* on a single device
|
as the nVidia nForce and Serverworks HT2000). As with host chipsets,
|
||||||
* on all devices behind a specific bridge
|
Linux mostly knows about them and automatically enables MSIs if it can.
|
||||||
* globally
|
If you have a bridge which Linux doesn't yet know about, you can enable
|
||||||
|
MSIs in configuration space using whatever method you know works, then
|
||||||
|
enable MSIs on that bridge by doing:
|
||||||
|
|
||||||
6.1. Disabling MSI on a single device
|
echo 1 > /sys/bus/pci/devices/$bridge/msi_bus
|
||||||
|
|
||||||
Under some circumstances it might be required to disable MSI on a
|
where $bridge is the PCI address of the bridge you've enabled (eg
|
||||||
single device. This may be achieved by either not calling pci_enable_msi()
|
0000:00:0e.0).
|
||||||
or all, or setting the pci_dev->no_msi flag before (most of the time
|
|
||||||
in a quirk).
|
|
||||||
|
|
||||||
6.2. Disabling MSI below a bridge
|
To disable MSIs, echo 0 instead of 1. Changing this value should be
|
||||||
|
done with caution as it can break interrupt handling for all devices
|
||||||
|
below this bridge.
|
||||||
|
|
||||||
The vast majority of MSI quirks are required by PCI bridges not
|
Again, please notify linux-pci@vger.kernel.org of any bridges that need
|
||||||
being able to route MSI between busses. In this case, MSI have to be
|
special handling.
|
||||||
disabled on all devices behind this bridge. It is achieves by setting
|
|
||||||
the PCI_BUS_FLAGS_NO_MSI flag in the pci_bus->bus_flags of the bridge
|
|
||||||
subordinate bus. There is no need to set the same flag on bridges that
|
|
||||||
are below the broken bridge. When pci_enable_msi() is called to enable
|
|
||||||
MSI on a device, pci_msi_supported() takes care of checking the NO_MSI
|
|
||||||
flag in all parent busses of the device.
|
|
||||||
|
|
||||||
Some bridges actually support dynamic MSI support enabling/disabling
|
5.3. Disabling MSIs on a single device
|
||||||
by changing some bits in their PCI configuration space (especially
|
|
||||||
the Hypertransport chipsets such as the nVidia nForce and Serverworks
|
|
||||||
HT2000). It may then be required to update the NO_MSI flag on the
|
|
||||||
corresponding devices in the sysfs hierarchy. To enable MSI support
|
|
||||||
on device "0000:00:0e", do:
|
|
||||||
|
|
||||||
echo 1 > /sys/bus/pci/devices/0000:00:0e/msi_bus
|
Some devices are known to have faulty MSI implementations. Usually this
|
||||||
|
is handled in the individual device driver but occasionally it's necessary
|
||||||
|
to handle this with a quirk. Some drivers have an option to disable use
|
||||||
|
of MSI. While this is a convenient workaround for the driver author,
|
||||||
|
it is not good practise, and should not be emulated.
|
||||||
|
|
||||||
To disable MSI support, echo 0 instead of 1. Note that it should be
|
5.4. Finding why MSIs are disabled on a device
|
||||||
used with caution since changing this value might break interrupts.
|
|
||||||
|
|
||||||
6.3. Disabling MSI globally
|
From the above three sections, you can see that there are many reasons
|
||||||
|
why MSIs may not be enabled for a given device. Your first step should
|
||||||
|
be to examine your dmesg carefully to determine whether MSIs are enabled
|
||||||
|
for your machine. You should also check your .config to be sure you
|
||||||
|
have enabled CONFIG_PCI_MSI.
|
||||||
|
|
||||||
Some extreme cases may require to disable MSI globally on the system.
|
Then, 'lspci -t' gives the list of bridges above a device. Reading
|
||||||
For now, the only known case is a Serverworks PCI-X chipsets (MSI are
|
/sys/bus/pci/devices/*/msi_bus will tell you whether MSI are enabled (1)
|
||||||
not supported on several busses that are not all connected to the
|
or disabled (0). If 0 is found in any of the msi_bus files belonging
|
||||||
chipset in the Linux PCI hierarchy). In the vast majority of other
|
to bridges between the PCI root and the device, MSIs are disabled.
|
||||||
cases, disabling only behind a specific bridge is enough.
|
|
||||||
|
|
||||||
For debugging purpose, the user may also pass pci=nomsi on the kernel
|
It is also worth checking the device driver to see whether it supports MSIs.
|
||||||
command-line to explicitly disable MSI globally. But, once the appro-
|
For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or
|
||||||
priate quirks are added to the kernel, this option should not be
|
pci_enable_msi_block().
|
||||||
required anymore.
|
|
||||||
|
|
||||||
6.4. Finding why MSI cannot be enabled on a device
|
|
||||||
|
|
||||||
Assuming that MSI are not enabled on a device, you should look at
|
|
||||||
dmesg to find messages that quirks may output when disabling MSI
|
|
||||||
on some devices, some bridges or even globally.
|
|
||||||
Then, lspci -t gives the list of bridges above a device. Reading
|
|
||||||
/sys/bus/pci/devices/0000:00:0e/msi_bus will tell you whether MSI
|
|
||||||
are enabled (1) or disabled (0). In 0 is found in a single bridge
|
|
||||||
msi_bus file above the device, MSI cannot be enabled.
|
|
||||||
|
|
||||||
7. FAQ
|
|
||||||
|
|
||||||
Q1. Are there any limitations on using the MSI?
|
|
||||||
|
|
||||||
A1. If the PCI device supports MSI and conforms to the
|
|
||||||
specification and the platform supports the APIC local bus,
|
|
||||||
then using MSI should work.
|
|
||||||
|
|
||||||
Q2. Will it work on all the Pentium processors (P3, P4, Xeon,
|
|
||||||
AMD processors)? In P3 IPI's are transmitted on the APIC local
|
|
||||||
bus and in P4 and Xeon they are transmitted on the system
|
|
||||||
bus. Are there any implications with this?
|
|
||||||
|
|
||||||
A2. MSI support enables a PCI device sending an inbound
|
|
||||||
memory write (0xfeexxxxx as target address) on its PCI bus
|
|
||||||
directly to the FSB. Since the message address has a
|
|
||||||
redirection hint bit cleared, it should work.
|
|
||||||
|
|
||||||
Q3. The target address 0xfeexxxxx will be translated by the
|
|
||||||
Host Bridge into an interrupt message. Are there any
|
|
||||||
limitations on the chipsets such as Intel 8xx, Intel e7xxx,
|
|
||||||
or VIA?
|
|
||||||
|
|
||||||
A3. If these chipsets support an inbound memory write with
|
|
||||||
target address set as 0xfeexxxxx, as conformed to PCI
|
|
||||||
specification 2.3 or latest, then it should work.
|
|
||||||
|
|
||||||
Q4. From the driver point of view, if the MSI is lost because
|
|
||||||
of errors occurring during inbound memory write, then it may
|
|
||||||
wait forever. Is there a mechanism for it to recover?
|
|
||||||
|
|
||||||
A4. Since the target of the transaction is an inbound memory
|
|
||||||
write, all transaction termination conditions (Retry,
|
|
||||||
Master-Abort, Target-Abort, or normal completion) are
|
|
||||||
supported. A device sending an MSI must abide by all the PCI
|
|
||||||
rules and conditions regarding that inbound memory write. So,
|
|
||||||
if a retry is signaled it must retry, etc... We believe that
|
|
||||||
the recommendation for Abort is also a retry (refer to PCI
|
|
||||||
specification 2.3 or latest).
|
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
PCI Express I/O Virtualization Howto
|
||||||
|
Copyright (C) 2009 Intel Corporation
|
||||||
|
Yu Zhao <yu.zhao@intel.com>
|
||||||
|
|
||||||
|
|
||||||
|
1. Overview
|
||||||
|
|
||||||
|
1.1 What is SR-IOV
|
||||||
|
|
||||||
|
Single Root I/O Virtualization (SR-IOV) is a PCI Express Extended
|
||||||
|
capability which makes one physical device appear as multiple virtual
|
||||||
|
devices. The physical device is referred to as Physical Function (PF)
|
||||||
|
while the virtual devices are referred to as Virtual Functions (VF).
|
||||||
|
Allocation of the VF can be dynamically controlled by the PF via
|
||||||
|
registers encapsulated in the capability. By default, this feature is
|
||||||
|
not enabled and the PF behaves as traditional PCIe device. Once it's
|
||||||
|
turned on, each VF's PCI configuration space can be accessed by its own
|
||||||
|
Bus, Device and Function Number (Routing ID). And each VF also has PCI
|
||||||
|
Memory Space, which is used to map its register set. VF device driver
|
||||||
|
operates on the register set so it can be functional and appear as a
|
||||||
|
real existing PCI device.
|
||||||
|
|
||||||
|
2. User Guide
|
||||||
|
|
||||||
|
2.1 How can I enable SR-IOV capability
|
||||||
|
|
||||||
|
The device driver (PF driver) will control the enabling and disabling
|
||||||
|
of the capability via API provided by SR-IOV core. If the hardware
|
||||||
|
has SR-IOV capability, loading its PF driver would enable it and all
|
||||||
|
VFs associated with the PF.
|
||||||
|
|
||||||
|
2.2 How can I use the Virtual Functions
|
||||||
|
|
||||||
|
The VF is treated as hot-plugged PCI devices in the kernel, so they
|
||||||
|
should be able to work in the same way as real PCI devices. The VF
|
||||||
|
requires device driver that is same as a normal PCI device's.
|
||||||
|
|
||||||
|
3. Developer Guide
|
||||||
|
|
||||||
|
3.1 SR-IOV API
|
||||||
|
|
||||||
|
To enable SR-IOV capability:
|
||||||
|
int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
|
||||||
|
'nr_virtfn' is number of VFs to be enabled.
|
||||||
|
|
||||||
|
To disable SR-IOV capability:
|
||||||
|
void pci_disable_sriov(struct pci_dev *dev);
|
||||||
|
|
||||||
|
To notify SR-IOV core of Virtual Function Migration:
|
||||||
|
irqreturn_t pci_sriov_migration(struct pci_dev *dev);
|
||||||
|
|
||||||
|
3.2 Usage example
|
||||||
|
|
||||||
|
Following piece of code illustrates the usage of the SR-IOV API.
|
||||||
|
|
||||||
|
static int __devinit dev_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
|
{
|
||||||
|
pci_enable_sriov(dev, NR_VIRTFN);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __devexit dev_remove(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
pci_disable_sriov(dev);
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dev_suspend(struct pci_dev *dev, pm_message_t state)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dev_resume(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dev_shutdown(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pci_driver dev_driver = {
|
||||||
|
.name = "SR-IOV Physical Function driver",
|
||||||
|
.id_table = dev_id_table,
|
||||||
|
.probe = dev_probe,
|
||||||
|
.remove = __devexit_p(dev_remove),
|
||||||
|
.suspend = dev_suspend,
|
||||||
|
.resume = dev_resume,
|
||||||
|
.shutdown = dev_shutdown,
|
||||||
|
};
|
|
@ -184,14 +184,16 @@ length. Single character labels using special characters, that being anything
|
||||||
other than a letter or digit, are reserved for use by the Smack development
|
other than a letter or digit, are reserved for use by the Smack development
|
||||||
team. Smack labels are unstructured, case sensitive, and the only operation
|
team. Smack labels are unstructured, case sensitive, and the only operation
|
||||||
ever performed on them is comparison for equality. Smack labels cannot
|
ever performed on them is comparison for equality. Smack labels cannot
|
||||||
contain unprintable characters or the "/" (slash) character.
|
contain unprintable characters or the "/" (slash) character. Smack labels
|
||||||
|
cannot begin with a '-', which is reserved for special options.
|
||||||
|
|
||||||
There are some predefined labels:
|
There are some predefined labels:
|
||||||
|
|
||||||
_ Pronounced "floor", a single underscore character.
|
_ Pronounced "floor", a single underscore character.
|
||||||
^ Pronounced "hat", a single circumflex character.
|
^ Pronounced "hat", a single circumflex character.
|
||||||
* Pronounced "star", a single asterisk character.
|
* Pronounced "star", a single asterisk character.
|
||||||
? Pronounced "huh", a single question mark character.
|
? Pronounced "huh", a single question mark character.
|
||||||
|
@ Pronounced "Internet", a single at sign character.
|
||||||
|
|
||||||
Every task on a Smack system is assigned a label. System tasks, such as
|
Every task on a Smack system is assigned a label. System tasks, such as
|
||||||
init(8) and systems daemons, are run with the floor ("_") label. User tasks
|
init(8) and systems daemons, are run with the floor ("_") label. User tasks
|
||||||
|
@ -412,6 +414,36 @@ sockets.
|
||||||
A privileged program may set this to match the label of another
|
A privileged program may set this to match the label of another
|
||||||
task with which it hopes to communicate.
|
task with which it hopes to communicate.
|
||||||
|
|
||||||
|
Smack Netlabel Exceptions
|
||||||
|
|
||||||
|
You will often find that your labeled application has to talk to the outside,
|
||||||
|
unlabeled world. To do this there's a special file /smack/netlabel where you can
|
||||||
|
add some exceptions in the form of :
|
||||||
|
@IP1 LABEL1 or
|
||||||
|
@IP2/MASK LABEL2
|
||||||
|
|
||||||
|
It means that your application will have unlabeled access to @IP1 if it has
|
||||||
|
write access on LABEL1, and access to the subnet @IP2/MASK if it has write
|
||||||
|
access on LABEL2.
|
||||||
|
|
||||||
|
Entries in the /smack/netlabel file are matched by longest mask first, like in
|
||||||
|
classless IPv4 routing.
|
||||||
|
|
||||||
|
A special label '@' and an option '-CIPSO' can be used there :
|
||||||
|
@ means Internet, any application with any label has access to it
|
||||||
|
-CIPSO means standard CIPSO networking
|
||||||
|
|
||||||
|
If you don't know what CIPSO is and don't plan to use it, you can just do :
|
||||||
|
echo 127.0.0.1 -CIPSO > /smack/netlabel
|
||||||
|
echo 0.0.0.0/0 @ > /smack/netlabel
|
||||||
|
|
||||||
|
If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
|
||||||
|
Internet access, you can have :
|
||||||
|
echo 127.0.0.1 -CIPSO > /smack/netlabel
|
||||||
|
echo 192.168.0.0/16 -CIPSO > /smack/netlabel
|
||||||
|
echo 0.0.0.0/0 @ > /smack/netlabel
|
||||||
|
|
||||||
|
|
||||||
Writing Applications for Smack
|
Writing Applications for Smack
|
||||||
|
|
||||||
There are three sorts of applications that will run on a Smack system. How an
|
There are three sorts of applications that will run on a Smack system. How an
|
||||||
|
|
|
@ -40,13 +40,13 @@ Resuming
|
||||||
Machine Support
|
Machine Support
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The machine specific functions must call the s3c2410_pm_init() function
|
The machine specific functions must call the s3c_pm_init() function
|
||||||
to say that its bootloader is capable of resuming. This can be as
|
to say that its bootloader is capable of resuming. This can be as
|
||||||
simple as adding the following to the machine's definition:
|
simple as adding the following to the machine's definition:
|
||||||
|
|
||||||
INITMACHINE(s3c2410_pm_init)
|
INITMACHINE(s3c_pm_init)
|
||||||
|
|
||||||
A board can do its own setup before calling s3c2410_pm_init, if it
|
A board can do its own setup before calling s3c_pm_init, if it
|
||||||
needs to setup anything else for power management support.
|
needs to setup anything else for power management support.
|
||||||
|
|
||||||
There is currently no support for over-riding the default method of
|
There is currently no support for over-riding the default method of
|
||||||
|
@ -74,7 +74,7 @@ statuc void __init machine_init(void)
|
||||||
|
|
||||||
enable_irq_wake(IRQ_EINT0);
|
enable_irq_wake(IRQ_EINT0);
|
||||||
|
|
||||||
s3c2410_pm_init();
|
s3c_pm_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,14 @@ ffff0000 ffff0fff CPU vector page.
|
||||||
CPU supports vector relocation (control
|
CPU supports vector relocation (control
|
||||||
register V bit.)
|
register V bit.)
|
||||||
|
|
||||||
ffc00000 fffeffff DMA memory mapping region. Memory returned
|
fffe0000 fffeffff XScale cache flush area. This is used
|
||||||
|
in proc-xscale.S to flush the whole data
|
||||||
|
cache. Free for other usage on non-XScale.
|
||||||
|
|
||||||
|
fff00000 fffdffff Fixmap mapping region. Addresses provided
|
||||||
|
by fix_to_virt() will be located here.
|
||||||
|
|
||||||
|
ffc00000 ffefffff DMA memory mapping region. Memory returned
|
||||||
by the dma_alloc_xxx functions will be
|
by the dma_alloc_xxx functions will be
|
||||||
dynamically mapped here.
|
dynamically mapped here.
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,3 @@ noop anticipatory deadline [cfq]
|
||||||
# echo anticipatory > /sys/block/hda/queue/scheduler
|
# echo anticipatory > /sys/block/hda/queue/scheduler
|
||||||
# cat /sys/block/hda/queue/scheduler
|
# cat /sys/block/hda/queue/scheduler
|
||||||
noop [anticipatory] deadline cfq
|
noop [anticipatory] deadline cfq
|
||||||
|
|
||||||
Each io queue has a set of io scheduler tunables associated with it. These
|
|
||||||
tunables control how the io scheduler works. You can find these entries
|
|
||||||
in:
|
|
||||||
|
|
||||||
/sys/block/<device>/queue/iosched
|
|
||||||
|
|
|
@ -117,10 +117,28 @@ accessible parameters:
|
||||||
sampling_rate: measured in uS (10^-6 seconds), this is how often you
|
sampling_rate: measured in uS (10^-6 seconds), this is how often you
|
||||||
want the kernel to look at the CPU usage and to make decisions on
|
want the kernel to look at the CPU usage and to make decisions on
|
||||||
what to do about the frequency. Typically this is set to values of
|
what to do about the frequency. Typically this is set to values of
|
||||||
around '10000' or more.
|
around '10000' or more. It's default value is (cmp. with users-guide.txt):
|
||||||
|
transition_latency * 1000
|
||||||
|
The lowest value you can set is:
|
||||||
|
transition_latency * 100 or it may get restricted to a value where it
|
||||||
|
makes not sense for the kernel anymore to poll that often which depends
|
||||||
|
on your HZ config variable (HZ=1000: max=20000us, HZ=250: max=5000).
|
||||||
|
Be aware that transition latency is in ns and sampling_rate is in us, so you
|
||||||
|
get the same sysfs value by default.
|
||||||
|
Sampling rate should always get adjusted considering the transition latency
|
||||||
|
To set the sampling rate 750 times as high as the transition latency
|
||||||
|
in the bash (as said, 1000 is default), do:
|
||||||
|
echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) \
|
||||||
|
>ondemand/sampling_rate
|
||||||
|
|
||||||
show_sampling_rate_(min|max): the minimum and maximum sampling rates
|
show_sampling_rate_(min|max): THIS INTERFACE IS DEPRECATED, DON'T USE IT.
|
||||||
available that you may set 'sampling_rate' to.
|
You can use wider ranges now and the general
|
||||||
|
cpuinfo_transition_latency variable (cmp. with user-guide.txt) can be
|
||||||
|
used to obtain exactly the same info:
|
||||||
|
show_sampling_rate_min = transtition_latency * 500 / 1000
|
||||||
|
show_sampling_rate_max = transtition_latency * 500000 / 1000
|
||||||
|
(divided by 1000 is to illustrate that sampling rate is in us and
|
||||||
|
transition latency is exported ns).
|
||||||
|
|
||||||
up_threshold: defines what the average CPU usage between the samplings
|
up_threshold: defines what the average CPU usage between the samplings
|
||||||
of 'sampling_rate' needs to be for the kernel to make a decision on
|
of 'sampling_rate' needs to be for the kernel to make a decision on
|
||||||
|
|
|
@ -152,6 +152,18 @@ cpuinfo_min_freq : this file shows the minimum operating
|
||||||
frequency the processor can run at(in kHz)
|
frequency the processor can run at(in kHz)
|
||||||
cpuinfo_max_freq : this file shows the maximum operating
|
cpuinfo_max_freq : this file shows the maximum operating
|
||||||
frequency the processor can run at(in kHz)
|
frequency the processor can run at(in kHz)
|
||||||
|
cpuinfo_transition_latency The time it takes on this CPU to
|
||||||
|
switch between two frequencies in nano
|
||||||
|
seconds. If unknown or known to be
|
||||||
|
that high that the driver does not
|
||||||
|
work with the ondemand governor, -1
|
||||||
|
(CPUFREQ_ETERNAL) will be returned.
|
||||||
|
Using this information can be useful
|
||||||
|
to choose an appropriate polling
|
||||||
|
frequency for a kernel governor or
|
||||||
|
userspace daemon. Make sure to not
|
||||||
|
switch the frequency too often
|
||||||
|
resulting in performance loss.
|
||||||
scaling_driver : this file shows what cpufreq driver is
|
scaling_driver : this file shows what cpufreq driver is
|
||||||
used to set the frequency on this CPU
|
used to set the frequency on this CPU
|
||||||
|
|
||||||
|
|
|
@ -3145,6 +3145,12 @@ Your cooperation is appreciated.
|
||||||
1 = /dev/blockrom1 Second ROM card's translation layer interface
|
1 = /dev/blockrom1 Second ROM card's translation layer interface
|
||||||
...
|
...
|
||||||
|
|
||||||
|
260 char OSD (Object-based-device) SCSI Device
|
||||||
|
0 = /dev/osd0 First OSD Device
|
||||||
|
1 = /dev/osd1 Second OSD Device
|
||||||
|
...
|
||||||
|
255 = /dev/osd255 256th OSD Device
|
||||||
|
|
||||||
**** ADDITIONAL /dev DIRECTORY ENTRIES
|
**** ADDITIONAL /dev DIRECTORY ENTRIES
|
||||||
|
|
||||||
This section details additional entries that should or may exist in
|
This section details additional entries that should or may exist in
|
||||||
|
|
|
@ -62,7 +62,6 @@ aic7*reg_print.c*
|
||||||
aic7*seq.h*
|
aic7*seq.h*
|
||||||
aicasm
|
aicasm
|
||||||
aicdb.h*
|
aicdb.h*
|
||||||
asm
|
|
||||||
asm-offsets.h
|
asm-offsets.h
|
||||||
asm_offsets.h
|
asm_offsets.h
|
||||||
autoconf.h*
|
autoconf.h*
|
||||||
|
|
|
@ -25,7 +25,7 @@ use IO::Handle;
|
||||||
"tda10046lifeview", "av7110", "dec2000t", "dec2540t",
|
"tda10046lifeview", "av7110", "dec2000t", "dec2540t",
|
||||||
"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
|
"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
|
||||||
"or51211", "or51132_qam", "or51132_vsb", "bluebird",
|
"or51211", "or51132_qam", "or51132_vsb", "bluebird",
|
||||||
"opera1");
|
"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2" );
|
||||||
|
|
||||||
# Check args
|
# Check args
|
||||||
syntax() if (scalar(@ARGV) != 1);
|
syntax() if (scalar(@ARGV) != 1);
|
||||||
|
@ -37,8 +37,8 @@ for ($i=0; $i < scalar(@components); $i++) {
|
||||||
$outfile = eval($cid);
|
$outfile = eval($cid);
|
||||||
die $@ if $@;
|
die $@ if $@;
|
||||||
print STDERR <<EOF;
|
print STDERR <<EOF;
|
||||||
Firmware $outfile extracted successfully.
|
Firmware(s) $outfile extracted successfully.
|
||||||
Now copy it to either /usr/lib/hotplug/firmware or /lib/firmware
|
Now copy it(they) to either /usr/lib/hotplug/firmware or /lib/firmware
|
||||||
(depending on configuration of firmware hotplug).
|
(depending on configuration of firmware hotplug).
|
||||||
EOF
|
EOF
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -345,6 +345,85 @@ sub or51211 {
|
||||||
$fwfile;
|
$fwfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub cx231xx {
|
||||||
|
my $fwfile = "v4l-cx231xx-avcore-01.fw";
|
||||||
|
my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
|
||||||
|
my $hash = "7d3bb956dc9df0eafded2b56ba57cc42";
|
||||||
|
|
||||||
|
checkstandard();
|
||||||
|
|
||||||
|
wgetfile($fwfile, $url);
|
||||||
|
verify($fwfile, $hash);
|
||||||
|
|
||||||
|
$fwfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cx18 {
|
||||||
|
my $url = "http://linuxtv.org/downloads/firmware/";
|
||||||
|
|
||||||
|
my %files = (
|
||||||
|
'v4l-cx23418-apu.fw' => '588f081b562f5c653a3db1ad8f65939a',
|
||||||
|
'v4l-cx23418-cpu.fw' => 'b6c7ed64bc44b1a6e0840adaeac39d79',
|
||||||
|
'v4l-cx23418-dig.fw' => '95bc688d3e7599fd5800161e9971cc55',
|
||||||
|
);
|
||||||
|
|
||||||
|
checkstandard();
|
||||||
|
|
||||||
|
my $allfiles;
|
||||||
|
foreach my $fwfile (keys %files) {
|
||||||
|
wgetfile($fwfile, "$url/$fwfile");
|
||||||
|
verify($fwfile, $files{$fwfile});
|
||||||
|
$allfiles .= " $fwfile";
|
||||||
|
}
|
||||||
|
|
||||||
|
$allfiles =~ s/^\s//;
|
||||||
|
|
||||||
|
$allfiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cx23885 {
|
||||||
|
my $url = "http://linuxtv.org/downloads/firmware/";
|
||||||
|
|
||||||
|
my %files = (
|
||||||
|
'v4l-cx23885-avcore-01.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb',
|
||||||
|
'v4l-cx23885-enc.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb',
|
||||||
|
);
|
||||||
|
|
||||||
|
checkstandard();
|
||||||
|
|
||||||
|
my $allfiles;
|
||||||
|
foreach my $fwfile (keys %files) {
|
||||||
|
wgetfile($fwfile, "$url/$fwfile");
|
||||||
|
verify($fwfile, $files{$fwfile});
|
||||||
|
$allfiles .= " $fwfile";
|
||||||
|
}
|
||||||
|
|
||||||
|
$allfiles =~ s/^\s//;
|
||||||
|
|
||||||
|
$allfiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub pvrusb2 {
|
||||||
|
my $url = "http://linuxtv.org/downloads/firmware/";
|
||||||
|
|
||||||
|
my %files = (
|
||||||
|
'v4l-cx25840.fw' => 'dadb79e9904fc8af96e8111d9cb59320',
|
||||||
|
);
|
||||||
|
|
||||||
|
checkstandard();
|
||||||
|
|
||||||
|
my $allfiles;
|
||||||
|
foreach my $fwfile (keys %files) {
|
||||||
|
wgetfile($fwfile, "$url/$fwfile");
|
||||||
|
verify($fwfile, $files{$fwfile});
|
||||||
|
$allfiles .= " $fwfile";
|
||||||
|
}
|
||||||
|
|
||||||
|
$allfiles =~ s/^\s//;
|
||||||
|
|
||||||
|
$allfiles;
|
||||||
|
}
|
||||||
|
|
||||||
sub or51132_qam {
|
sub or51132_qam {
|
||||||
my $fwfile = "dvb-fe-or51132-qam.fw";
|
my $fwfile = "dvb-fe-or51132-qam.fw";
|
||||||
my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
|
my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
|
||||||
|
|
|
@ -0,0 +1,240 @@
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
This document describes how to use the dynamic debug (ddebug) feature.
|
||||||
|
|
||||||
|
Dynamic debug is designed to allow you to dynamically enable/disable kernel
|
||||||
|
code to obtain additional kernel information. Currently, if
|
||||||
|
CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_debug() calls can be
|
||||||
|
dynamically enabled per-callsite.
|
||||||
|
|
||||||
|
Dynamic debug has even more useful features:
|
||||||
|
|
||||||
|
* Simple query language allows turning on and off debugging statements by
|
||||||
|
matching any combination of:
|
||||||
|
|
||||||
|
- source filename
|
||||||
|
- function name
|
||||||
|
- line number (including ranges of line numbers)
|
||||||
|
- module name
|
||||||
|
- format string
|
||||||
|
|
||||||
|
* Provides a debugfs control file: <debugfs>/dynamic_debug/control which can be
|
||||||
|
read to display the complete list of known debug statements, to help guide you
|
||||||
|
|
||||||
|
Controlling dynamic debug Behaviour
|
||||||
|
===============================
|
||||||
|
|
||||||
|
The behaviour of pr_debug()/dev_debug()s are controlled via writing to a
|
||||||
|
control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs
|
||||||
|
filesystem, in order to make use of this feature. Subsequently, we refer to the
|
||||||
|
control file as: <debugfs>/dynamic_debug/control. For example, if you want to
|
||||||
|
enable printing from source file 'svcsock.c', line 1603 you simply do:
|
||||||
|
|
||||||
|
nullarbor:~ # echo 'file svcsock.c line 1603 +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
|
||||||
|
If you make a mistake with the syntax, the write will fail thus:
|
||||||
|
|
||||||
|
nullarbor:~ # echo 'file svcsock.c wtf 1 +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
-bash: echo: write error: Invalid argument
|
||||||
|
|
||||||
|
Viewing Dynamic Debug Behaviour
|
||||||
|
===========================
|
||||||
|
|
||||||
|
You can view the currently configured behaviour of all the debug statements
|
||||||
|
via:
|
||||||
|
|
||||||
|
nullarbor:~ # cat <debugfs>/dynamic_debug/control
|
||||||
|
# filename:lineno [module]function flags format
|
||||||
|
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup - "SVCRDMA Module Removed, deregister RPC RDMA transport\012"
|
||||||
|
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init - "\011max_inline : %d\012"
|
||||||
|
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init - "\011sq_depth : %d\012"
|
||||||
|
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init - "\011max_requests : %d\012"
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
You can also apply standard Unix text manipulation filters to this
|
||||||
|
data, e.g.
|
||||||
|
|
||||||
|
nullarbor:~ # grep -i rdma <debugfs>/dynamic_debug/control | wc -l
|
||||||
|
62
|
||||||
|
|
||||||
|
nullarbor:~ # grep -i tcp <debugfs>/dynamic_debug/control | wc -l
|
||||||
|
42
|
||||||
|
|
||||||
|
Note in particular that the third column shows the enabled behaviour
|
||||||
|
flags for each debug statement callsite (see below for definitions of the
|
||||||
|
flags). The default value, no extra behaviour enabled, is "-". So
|
||||||
|
you can view all the debug statement callsites with any non-default flags:
|
||||||
|
|
||||||
|
nullarbor:~ # awk '$3 != "-"' <debugfs>/dynamic_debug/control
|
||||||
|
# filename:lineno [module]function flags format
|
||||||
|
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process: st_sendto returned %d\012"
|
||||||
|
|
||||||
|
|
||||||
|
Command Language Reference
|
||||||
|
==========================
|
||||||
|
|
||||||
|
At the lexical level, a command comprises a sequence of words separated
|
||||||
|
by whitespace characters. Note that newlines are treated as word
|
||||||
|
separators and do *not* end a command or allow multiple commands to
|
||||||
|
be done together. So these are all equivalent:
|
||||||
|
|
||||||
|
nullarbor:~ # echo -c 'file svcsock.c line 1603 +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
nullarbor:~ # echo -c ' file svcsock.c line 1603 +p ' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
|
||||||
|
Commands are bounded by a write() system call. If you want to do
|
||||||
|
multiple commands you need to do a separate "echo" for each, like:
|
||||||
|
|
||||||
|
nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
|
||||||
|
> echo 'file svcsock.c line 1563 +p' > /proc/dprintk
|
||||||
|
|
||||||
|
or even like:
|
||||||
|
|
||||||
|
nullarbor:~ # (
|
||||||
|
> echo 'file svcsock.c line 1603 +p' ;\
|
||||||
|
> echo 'file svcsock.c line 1563 +p' ;\
|
||||||
|
> ) > /proc/dprintk
|
||||||
|
|
||||||
|
At the syntactical level, a command comprises a sequence of match
|
||||||
|
specifications, followed by a flags change specification.
|
||||||
|
|
||||||
|
command ::= match-spec* flags-spec
|
||||||
|
|
||||||
|
The match-spec's are used to choose a subset of the known dprintk()
|
||||||
|
callsites to which to apply the flags-spec. Think of them as a query
|
||||||
|
with implicit ANDs between each pair. Note that an empty list of
|
||||||
|
match-specs is possible, but is not very useful because it will not
|
||||||
|
match any debug statement callsites.
|
||||||
|
|
||||||
|
A match specification comprises a keyword, which controls the attribute
|
||||||
|
of the callsite to be compared, and a value to compare against. Possible
|
||||||
|
keywords are:
|
||||||
|
|
||||||
|
match-spec ::= 'func' string |
|
||||||
|
'file' string |
|
||||||
|
'module' string |
|
||||||
|
'format' string |
|
||||||
|
'line' line-range
|
||||||
|
|
||||||
|
line-range ::= lineno |
|
||||||
|
'-'lineno |
|
||||||
|
lineno'-' |
|
||||||
|
lineno'-'lineno
|
||||||
|
// Note: line-range cannot contain space, e.g.
|
||||||
|
// "1-30" is valid range but "1 - 30" is not.
|
||||||
|
|
||||||
|
lineno ::= unsigned-int
|
||||||
|
|
||||||
|
The meanings of each keyword are:
|
||||||
|
|
||||||
|
func
|
||||||
|
The given string is compared against the function name
|
||||||
|
of each callsite. Example:
|
||||||
|
|
||||||
|
func svc_tcp_accept
|
||||||
|
|
||||||
|
file
|
||||||
|
The given string is compared against either the full
|
||||||
|
pathname or the basename of the source file of each
|
||||||
|
callsite. Examples:
|
||||||
|
|
||||||
|
file svcsock.c
|
||||||
|
file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c
|
||||||
|
|
||||||
|
module
|
||||||
|
The given string is compared against the module name
|
||||||
|
of each callsite. The module name is the string as
|
||||||
|
seen in "lsmod", i.e. without the directory or the .ko
|
||||||
|
suffix and with '-' changed to '_'. Examples:
|
||||||
|
|
||||||
|
module sunrpc
|
||||||
|
module nfsd
|
||||||
|
|
||||||
|
format
|
||||||
|
The given string is searched for in the dynamic debug format
|
||||||
|
string. Note that the string does not need to match the
|
||||||
|
entire format, only some part. Whitespace and other
|
||||||
|
special characters can be escaped using C octal character
|
||||||
|
escape \ooo notation, e.g. the space character is \040.
|
||||||
|
Alternatively, the string can be enclosed in double quote
|
||||||
|
characters (") or single quote characters (').
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
format svcrdma: // many of the NFS/RDMA server dprintks
|
||||||
|
format readahead // some dprintks in the readahead cache
|
||||||
|
format nfsd:\040SETATTR // one way to match a format with whitespace
|
||||||
|
format "nfsd: SETATTR" // a neater way to match a format with whitespace
|
||||||
|
format 'nfsd: SETATTR' // yet another way to match a format with whitespace
|
||||||
|
|
||||||
|
line
|
||||||
|
The given line number or range of line numbers is compared
|
||||||
|
against the line number of each dprintk() callsite. A single
|
||||||
|
line number matches the callsite line number exactly. A
|
||||||
|
range of line numbers matches any callsite between the first
|
||||||
|
and last line number inclusive. An empty first number means
|
||||||
|
the first line in the file, an empty line number means the
|
||||||
|
last number in the file. Examples:
|
||||||
|
|
||||||
|
line 1603 // exactly line 1603
|
||||||
|
line 1600-1605 // the six lines from line 1600 to line 1605
|
||||||
|
line -1605 // the 1605 lines from line 1 to line 1605
|
||||||
|
line 1600- // all lines from line 1600 to the end of the file
|
||||||
|
|
||||||
|
The flags specification comprises a change operation followed
|
||||||
|
by one or more flag characters. The change operation is one
|
||||||
|
of the characters:
|
||||||
|
|
||||||
|
-
|
||||||
|
remove the given flags
|
||||||
|
|
||||||
|
+
|
||||||
|
add the given flags
|
||||||
|
|
||||||
|
=
|
||||||
|
set the flags to the given flags
|
||||||
|
|
||||||
|
The flags are:
|
||||||
|
|
||||||
|
p
|
||||||
|
Causes a printk() message to be emitted to dmesg
|
||||||
|
|
||||||
|
Note the regexp ^[-+=][scp]+$ matches a flags specification.
|
||||||
|
Note also that there is no convenient syntax to remove all
|
||||||
|
the flags at once, you need to use "-psc".
|
||||||
|
|
||||||
|
Examples
|
||||||
|
========
|
||||||
|
|
||||||
|
// enable the message at line 1603 of file svcsock.c
|
||||||
|
nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
|
||||||
|
// enable all the messages in file svcsock.c
|
||||||
|
nullarbor:~ # echo -n 'file svcsock.c +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
|
||||||
|
// enable all the messages in the NFS server module
|
||||||
|
nullarbor:~ # echo -n 'module nfsd +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
|
||||||
|
// enable all 12 messages in the function svc_process()
|
||||||
|
nullarbor:~ # echo -n 'func svc_process +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
|
||||||
|
// disable all 12 messages in the function svc_process()
|
||||||
|
nullarbor:~ # echo -n 'func svc_process -p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
||||||
|
|
||||||
|
// enable messages for NFS calls READ, READLINK, READDIR and READDIR+.
|
||||||
|
nullarbor:~ # echo -n 'format "nfsd: READ" +p' >
|
||||||
|
<debugfs>/dynamic_debug/control
|
|
@ -11,8 +11,6 @@ aty128fb.txt
|
||||||
- info on the ATI Rage128 frame buffer driver.
|
- info on the ATI Rage128 frame buffer driver.
|
||||||
cirrusfb.txt
|
cirrusfb.txt
|
||||||
- info on the driver for Cirrus Logic chipsets.
|
- info on the driver for Cirrus Logic chipsets.
|
||||||
cyblafb/
|
|
||||||
- directory with documentation files related to the cyblafb driver.
|
|
||||||
deferred_io.txt
|
deferred_io.txt
|
||||||
- an introduction to deferred IO.
|
- an introduction to deferred IO.
|
||||||
fbcon.txt
|
fbcon.txt
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
Bugs
|
|
||||||
====
|
|
||||||
|
|
||||||
I currently don't know of any bug. Please do send reports to:
|
|
||||||
- linux-fbdev-devel@lists.sourceforge.net
|
|
||||||
- Knut_Petersen@t-online.de.
|
|
||||||
|
|
||||||
|
|
||||||
Untested features
|
|
||||||
=================
|
|
||||||
|
|
||||||
All LCD stuff is untested. If it worked in tridentfb, it should work in
|
|
||||||
cyblafb. Please test and report the results to Knut_Petersen@t-online.de.
|
|
|
@ -1,7 +0,0 @@
|
||||||
Thanks to
|
|
||||||
=========
|
|
||||||
* Alan Hourihane, for writing the X trident driver
|
|
||||||
* Jani Monoses, for writing the tridentfb driver
|
|
||||||
* Antonino A. Daplas, for review of the first published
|
|
||||||
version of cyblafb and some code
|
|
||||||
* Jochen Hein, for testing and a helpfull bug report
|
|
|
@ -1,17 +0,0 @@
|
||||||
Available Documentation
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22,
|
|
||||||
2001, available from VIA:
|
|
||||||
|
|
||||||
http://www.viavpsd.com/product/6/15/DS8601A182.pdf
|
|
||||||
|
|
||||||
The datasheet is incomplete, some registers that need to be programmed are not
|
|
||||||
explained at all and important bits are listed as "reserved". But you really
|
|
||||||
need the datasheet to understand the code. "p. xxx" comments refer to page
|
|
||||||
numbers of this document.
|
|
||||||
|
|
||||||
XFree/XOrg drivers are available and of good quality, looking at the code
|
|
||||||
there is a good idea if the datasheet does not provide enough information
|
|
||||||
or if the datasheet seems to be wrong.
|
|
||||||
|
|
|
@ -1,154 +0,0 @@
|
||||||
#
|
|
||||||
# Sample fb.modes file
|
|
||||||
#
|
|
||||||
# Provides an incomplete list of working modes for
|
|
||||||
# the cyberblade/i1 graphics core.
|
|
||||||
#
|
|
||||||
# The value 4294967256 is used instead of -40. Of course, -40 is not
|
|
||||||
# a really reasonable value, but chip design does not always follow
|
|
||||||
# logic. Believe me, it's ok, and it's the way the BIOS does it.
|
|
||||||
#
|
|
||||||
# fbset requires 4294967256 in fb.modes and -40 as an argument to
|
|
||||||
# the -t parameter. That's also not too reasonable, and it might change
|
|
||||||
# in the future or might even be differt for your current version.
|
|
||||||
#
|
|
||||||
|
|
||||||
mode "640x480-50"
|
|
||||||
geometry 640 480 2048 4096 8
|
|
||||||
timings 47619 4294967256 24 17 0 216 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "640x480-60"
|
|
||||||
geometry 640 480 2048 4096 8
|
|
||||||
timings 39682 4294967256 24 17 0 216 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "640x480-70"
|
|
||||||
geometry 640 480 2048 4096 8
|
|
||||||
timings 34013 4294967256 24 17 0 216 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "640x480-72"
|
|
||||||
geometry 640 480 2048 4096 8
|
|
||||||
timings 33068 4294967256 24 17 0 216 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "640x480-75"
|
|
||||||
geometry 640 480 2048 4096 8
|
|
||||||
timings 31746 4294967256 24 17 0 216 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "640x480-80"
|
|
||||||
geometry 640 480 2048 4096 8
|
|
||||||
timings 29761 4294967256 24 17 0 216 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "640x480-85"
|
|
||||||
geometry 640 480 2048 4096 8
|
|
||||||
timings 28011 4294967256 24 17 0 216 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "800x600-50"
|
|
||||||
geometry 800 600 2048 4096 8
|
|
||||||
timings 30303 96 24 14 0 136 11
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "800x600-60"
|
|
||||||
geometry 800 600 2048 4096 8
|
|
||||||
timings 25252 96 24 14 0 136 11
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "800x600-70"
|
|
||||||
geometry 800 600 2048 4096 8
|
|
||||||
timings 21645 96 24 14 0 136 11
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "800x600-72"
|
|
||||||
geometry 800 600 2048 4096 8
|
|
||||||
timings 21043 96 24 14 0 136 11
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "800x600-75"
|
|
||||||
geometry 800 600 2048 4096 8
|
|
||||||
timings 20202 96 24 14 0 136 11
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "800x600-80"
|
|
||||||
geometry 800 600 2048 4096 8
|
|
||||||
timings 18939 96 24 14 0 136 11
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "800x600-85"
|
|
||||||
geometry 800 600 2048 4096 8
|
|
||||||
timings 17825 96 24 14 0 136 11
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1024x768-50"
|
|
||||||
geometry 1024 768 2048 4096 8
|
|
||||||
timings 19054 144 24 29 0 120 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1024x768-60"
|
|
||||||
geometry 1024 768 2048 4096 8
|
|
||||||
timings 15880 144 24 29 0 120 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1024x768-70"
|
|
||||||
geometry 1024 768 2048 4096 8
|
|
||||||
timings 13610 144 24 29 0 120 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1024x768-72"
|
|
||||||
geometry 1024 768 2048 4096 8
|
|
||||||
timings 13232 144 24 29 0 120 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1024x768-75"
|
|
||||||
geometry 1024 768 2048 4096 8
|
|
||||||
timings 12703 144 24 29 0 120 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1024x768-80"
|
|
||||||
geometry 1024 768 2048 4096 8
|
|
||||||
timings 11910 144 24 29 0 120 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1024x768-85"
|
|
||||||
geometry 1024 768 2048 4096 8
|
|
||||||
timings 11209 144 24 29 0 120 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1280x1024-50"
|
|
||||||
geometry 1280 1024 2048 4096 8
|
|
||||||
timings 11114 232 16 39 0 160 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1280x1024-60"
|
|
||||||
geometry 1280 1024 2048 4096 8
|
|
||||||
timings 9262 232 16 39 0 160 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1280x1024-70"
|
|
||||||
geometry 1280 1024 2048 4096 8
|
|
||||||
timings 7939 232 16 39 0 160 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1280x1024-72"
|
|
||||||
geometry 1280 1024 2048 4096 8
|
|
||||||
timings 7719 232 16 39 0 160 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1280x1024-75"
|
|
||||||
geometry 1280 1024 2048 4096 8
|
|
||||||
timings 7410 232 16 39 0 160 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1280x1024-80"
|
|
||||||
geometry 1280 1024 2048 4096 8
|
|
||||||
timings 6946 232 16 39 0 160 3
|
|
||||||
endmode
|
|
||||||
|
|
||||||
mode "1280x1024-85"
|
|
||||||
geometry 1280 1024 2048 4096 8
|
|
||||||
timings 6538 232 16 39 0 160 3
|
|
||||||
endmode
|
|
|
@ -1,79 +0,0 @@
|
||||||
Speed
|
|
||||||
=====
|
|
||||||
|
|
||||||
CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data
|
|
||||||
for mode 1280x1024-[8,16,32]@61 Hz.
|
|
||||||
|
|
||||||
Test 1: Cat a file with 2000 lines of 0 characters.
|
|
||||||
Test 2: Cat a file with 2000 lines of 80 characters.
|
|
||||||
Test 3: Cat a file with 2000 lines of 160 characters.
|
|
||||||
|
|
||||||
All values show system time use in seconds, kernel 2.6.12 was used for
|
|
||||||
the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a
|
|
||||||
patch that speeds up kernel bitblitting a lot ( > 20%).
|
|
||||||
|
|
||||||
+-----------+-----------------------------------------------------+
|
|
||||||
| | not accelerated |
|
|
||||||
| TRIDENTFB +-----------------+-----------------+-----------------+
|
|
||||||
| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
|
|
||||||
| | noypan | ypan | noypan | ypan | noypan | ypan |
|
|
||||||
+-----------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Test 1 | 4.31 | 4.33 | 6.05 | 12.81 | ---- | ---- |
|
|
||||||
| Test 2 | 67.94 | 5.44 | 123.16 | 14.79 | ---- | ---- |
|
|
||||||
| Test 3 | 131.36 | 6.55 | 240.12 | 16.76 | ---- | ---- |
|
|
||||||
+-----------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Comments | | | completely bro- |
|
|
||||||
| | | | ken, monitor |
|
|
||||||
| | | | switches off |
|
|
||||||
+-----------+-----------------+-----------------+-----------------+
|
|
||||||
|
|
||||||
|
|
||||||
+-----------+-----------------------------------------------------+
|
|
||||||
| | accelerated |
|
|
||||||
| TRIDENTFB +-----------------+-----------------+-----------------+
|
|
||||||
| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
|
|
||||||
| | noypan | ypan | noypan | ypan | noypan | ypan |
|
|
||||||
+-----------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Test 1 | ---- | ---- | 20.62 | 1.22 | ---- | ---- |
|
|
||||||
| Test 2 | ---- | ---- | 22.61 | 3.19 | ---- | ---- |
|
|
||||||
| Test 3 | ---- | ---- | 24.59 | 5.16 | ---- | ---- |
|
|
||||||
+-----------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Comments | broken, writing | broken, ok only | completely bro- |
|
|
||||||
| | to wrong places | if bgcolor is | ken, monitor |
|
|
||||||
| | on screen + bug | black, bug in | switches off |
|
|
||||||
| | in fillrect() | fillrect() | |
|
|
||||||
+-----------+-----------------+-----------------+-----------------+
|
|
||||||
|
|
||||||
|
|
||||||
+-----------+-----------------------------------------------------+
|
|
||||||
| | not accelerated |
|
|
||||||
| VESAFB +-----------------+-----------------+-----------------+
|
|
||||||
| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
|
|
||||||
| | noypan | ypan | noypan | ypan | noypan | ypan |
|
|
||||||
+-----------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Test 1 | 4.26 | 3.76 | 5.99 | 7.23 | ---- | ---- |
|
|
||||||
| Test 2 | 65.65 | 4.89 | 120.88 | 9.08 | ---- | ---- |
|
|
||||||
| Test 3 | 126.91 | 5.94 | 235.77 | 11.03 | ---- | ---- |
|
|
||||||
+-----------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Comments | vga=0x307 | vga=0x31a | vga=0x31b not |
|
|
||||||
| | fh=80kHz | fh=80kHz | supported by |
|
|
||||||
| | fv=75kHz | fv=75kHz | video BIOS and |
|
|
||||||
| | | | hardware |
|
|
||||||
+-----------+-----------------+-----------------+-----------------+
|
|
||||||
|
|
||||||
|
|
||||||
+-----------+-----------------------------------------------------+
|
|
||||||
| | accelerated |
|
|
||||||
| CYBLAFB +-----------------+-----------------+-----------------+
|
|
||||||
| | 8 bpp | 16 bpp | 32 bpp |
|
|
||||||
| | noypan | ypan | noypan | ypan | noypan | ypan |
|
|
||||||
+-----------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Test 1 | 8.02 | 0.23 | 19.04 | 0.61 | 57.12 | 2.74 |
|
|
||||||
| Test 2 | 8.38 | 0.55 | 19.39 | 0.92 | 57.54 | 3.13 |
|
|
||||||
| Test 3 | 8.73 | 0.86 | 19.74 | 1.24 | 57.95 | 3.51 |
|
|
||||||
+-----------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Comments | | | |
|
|
||||||
| | | | |
|
|
||||||
| | | | |
|
|
||||||
| | | | |
|
|
||||||
+-----------+-----------------+-----------------+-----------------+
|
|
|
@ -1,31 +0,0 @@
|
||||||
TODO / Missing features
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Verify LCD stuff "stretch" and "center" options are
|
|
||||||
completely untested ... this code needs to be
|
|
||||||
verified. As I don't have access to such
|
|
||||||
hardware, please contact me if you are
|
|
||||||
willing run some tests.
|
|
||||||
|
|
||||||
Interlaced video modes The reason that interleaved
|
|
||||||
modes are disabled is that I do not know
|
|
||||||
the meaning of the vertical interlace
|
|
||||||
parameter. Also the datasheet mentions a
|
|
||||||
bit d8 of a horizontal interlace parameter,
|
|
||||||
but nowhere the lower 8 bits. Please help
|
|
||||||
if you can.
|
|
||||||
|
|
||||||
low-res double scan modes Who needs it?
|
|
||||||
|
|
||||||
accelerated color blitting Who needs it? The console driver does use color
|
|
||||||
blitting for nothing but drawing the penguine,
|
|
||||||
everything else is done using color expanding
|
|
||||||
blitting of 1bpp character bitmaps.
|
|
||||||
|
|
||||||
ioctls Who needs it?
|
|
||||||
|
|
||||||
TV-out Will be done later. Use "vga= " at boot time
|
|
||||||
to set a suitable video mode.
|
|
||||||
|
|
||||||
??? Feel free to contact me if you have any
|
|
||||||
feature requests
|
|
|
@ -1,217 +0,0 @@
|
||||||
CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated
|
|
||||||
into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and
|
|
||||||
tested using a VIA EPIA 5000 board.
|
|
||||||
|
|
||||||
Cyblafb - compiled into the kernel or as a module?
|
|
||||||
==================================================
|
|
||||||
|
|
||||||
You might compile cyblafb either as a module or compile it permanently into the
|
|
||||||
kernel.
|
|
||||||
|
|
||||||
Unless you have a real reason to do so you should not compile both vesafb and
|
|
||||||
cyblafb permanently into the kernel. It's possible and it helps during the
|
|
||||||
developement cycle, but it's useless and will at least block some otherwise
|
|
||||||
usefull memory for ordinary users.
|
|
||||||
|
|
||||||
Selecting Modes
|
|
||||||
===============
|
|
||||||
|
|
||||||
Startup Mode
|
|
||||||
============
|
|
||||||
|
|
||||||
First of all, you might use the "vga=???" boot parameter as it is
|
|
||||||
documented in vesafb.txt and svga.txt. Cyblafb will detect the video
|
|
||||||
mode selected and will use the geometry and timings found by
|
|
||||||
inspecting the hardware registers.
|
|
||||||
|
|
||||||
video=cyblafb vga=0x317
|
|
||||||
|
|
||||||
Alternatively you might use a combination of the mode, ref and bpp
|
|
||||||
parameters. If you compiled the driver into the kernel, add something
|
|
||||||
like this to the kernel command line:
|
|
||||||
|
|
||||||
video=cyblafb:1280x1024,bpp=16,ref=50 ...
|
|
||||||
|
|
||||||
If you compiled the driver as a module, the same mode would be
|
|
||||||
selected by the following command:
|
|
||||||
|
|
||||||
modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
|
|
||||||
|
|
||||||
None of the modes possible to select as startup modes are affected by
|
|
||||||
the problems described at the end of the next subsection.
|
|
||||||
|
|
||||||
For all startup modes cyblafb chooses a virtual x resolution of 2048,
|
|
||||||
the only exception is mode 1280x1024 in combination with 32 bpp. This
|
|
||||||
allows ywrap scrolling for all those modes if rotation is 0 or 2, and
|
|
||||||
also fast scrolling if rotation is 1 or 3. The default virtual y reso-
|
|
||||||
lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32,
|
|
||||||
again with the only exception of 1280x1024 at 32 bpp.
|
|
||||||
|
|
||||||
Please do set your video memory size to 8 Mb in the Bios setup. Other
|
|
||||||
values will work, but performace is decreased for a lot of modes.
|
|
||||||
|
|
||||||
Mode changes using fbset
|
|
||||||
========================
|
|
||||||
|
|
||||||
You might use fbset to change the video mode, see "man fbset". Cyblafb
|
|
||||||
generally does assume that you know what you are doing. But it does
|
|
||||||
some checks, especially those that are needed to prevent you from
|
|
||||||
damaging your hardware.
|
|
||||||
|
|
||||||
- only 8, 16, 24 and 32 bpp video modes are accepted
|
|
||||||
- interlaced video modes are not accepted
|
|
||||||
- double scan video modes are not accepted
|
|
||||||
- if a flat panel is found, cyblafb does not allow you
|
|
||||||
to program a resolution higher than the physical
|
|
||||||
resolution of the flat panel monitor
|
|
||||||
- cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp
|
|
||||||
and (currently) 24 bit modes use a doubled vclk internally,
|
|
||||||
the dotclock limit as seen by fbset is 115 MHz for those
|
|
||||||
modes and 230 MHz for 8 and 16 bpp modes.
|
|
||||||
- cyblafb will allow you to select very high resolutions as
|
|
||||||
long as the hardware can be programmed to these modes. The
|
|
||||||
documented limit 1600x1200 is not enforced, but don't expect
|
|
||||||
perfect signal quality.
|
|
||||||
|
|
||||||
Any request that violates the rules given above will be either changed
|
|
||||||
to something the hardware supports or an error value will be returned.
|
|
||||||
|
|
||||||
If you program a virtual y resolution higher than the hardware limit,
|
|
||||||
cyblafb will silently decrease that value to the highest possible
|
|
||||||
value. The same is true for a virtual x resolution that is not
|
|
||||||
supported by the hardware. Cyblafb tries to adapt vyres first because
|
|
||||||
vxres decides if ywrap scrolling is possible or not.
|
|
||||||
|
|
||||||
Attempts to disable acceleration are ignored, I believe that this is
|
|
||||||
safe.
|
|
||||||
|
|
||||||
Some video modes that should work do not work as expected. If you use
|
|
||||||
the standard fb.modes, fbset 640x480-60 will program that mode, but
|
|
||||||
you will see a vertical area, about two characters wide, with only
|
|
||||||
much darker characters than the other characters on the screen.
|
|
||||||
Cyblafb does allow that mode to be set, as it does not violate the
|
|
||||||
official specifications. It would need a lot of code to reliably sort
|
|
||||||
out all invalid modes, playing around with the margin values will
|
|
||||||
give a valid mode quickly. And if cyblafb would detect such an invalid
|
|
||||||
mode, should it silently alter the requested values or should it
|
|
||||||
report an error? Both options have some pros and cons. As stated
|
|
||||||
above, none of the startup modes are affected, and if you set
|
|
||||||
verbosity to 1 or higher, cyblafb will print the fbset command that
|
|
||||||
would be needed to program that mode using fbset.
|
|
||||||
|
|
||||||
|
|
||||||
Other Parameters
|
|
||||||
================
|
|
||||||
|
|
||||||
|
|
||||||
crt don't autodetect, assume monitor connected to
|
|
||||||
standard VGA connector
|
|
||||||
|
|
||||||
fp don't autodetect, assume flat panel display
|
|
||||||
connected to flat panel monitor interface
|
|
||||||
|
|
||||||
nativex inform driver about native x resolution of
|
|
||||||
flat panel monitor connected to special
|
|
||||||
interface (should be autodetected)
|
|
||||||
|
|
||||||
stretch stretch image to adapt low resolution modes to
|
|
||||||
higer resolutions of flat panel monitors
|
|
||||||
connected to special interface
|
|
||||||
|
|
||||||
center center image to adapt low resolution modes to
|
|
||||||
higer resolutions of flat panel monitors
|
|
||||||
connected to special interface
|
|
||||||
|
|
||||||
memsize use if autodetected memsize is wrong ...
|
|
||||||
should never be necessary
|
|
||||||
|
|
||||||
nopcirr disable PCI read retry
|
|
||||||
nopciwr disable PCI write retry
|
|
||||||
nopcirb disable PCI read bursts
|
|
||||||
nopciwb disable PCI write bursts
|
|
||||||
|
|
||||||
bpp bpp for specified modes
|
|
||||||
valid values: 8 || 16 || 24 || 32
|
|
||||||
|
|
||||||
ref refresh rate for specified mode
|
|
||||||
valid values: 50 <= ref <= 85
|
|
||||||
|
|
||||||
mode 640x480 or 800x600 or 1024x768 or 1280x1024
|
|
||||||
if not specified, the startup mode will be detected
|
|
||||||
and used, so you might also use the vga=??? parameter
|
|
||||||
described in vesafb.txt. If you do not specify a mode,
|
|
||||||
bpp and ref parameters are ignored.
|
|
||||||
|
|
||||||
verbosity 0 is the default, increase to at least 2 for every
|
|
||||||
bug report!
|
|
||||||
|
|
||||||
Development hints
|
|
||||||
=================
|
|
||||||
|
|
||||||
It's much faster do compile a module and to load the new version after
|
|
||||||
unloading the old module than to compile a new kernel and to reboot. So if you
|
|
||||||
try to work on cyblafb, it might be a good idea to use cyblafb as a module.
|
|
||||||
In real life, fast often means dangerous, and that's also the case here. If
|
|
||||||
you introduce a serious bug when cyblafb is compiled into the kernel, the
|
|
||||||
kernel will lock or oops with a high probability before the file system is
|
|
||||||
mounted, and the danger for your data is low. If you load a broken own version
|
|
||||||
of cyblafb on a running system, the danger for the integrity of the file
|
|
||||||
system is much higher as you might need a hard reset afterwards. Decide
|
|
||||||
yourself.
|
|
||||||
|
|
||||||
Module unloading, the vfb method
|
|
||||||
================================
|
|
||||||
|
|
||||||
If you want to unload/reload cyblafb using the virtual framebuffer, you need
|
|
||||||
to enable vfb support in the kernel first. After that, load the modules as
|
|
||||||
shown below:
|
|
||||||
|
|
||||||
modprobe vfb vfb_enable=1
|
|
||||||
modprobe fbcon
|
|
||||||
modprobe cyblafb
|
|
||||||
fbset -fb /dev/fb1 1280x1024-60 -vyres 2662
|
|
||||||
con2fb /dev/fb1 /dev/tty1
|
|
||||||
...
|
|
||||||
|
|
||||||
If you now made some changes to cyblafb and want to reload it, you might do it
|
|
||||||
as show below:
|
|
||||||
|
|
||||||
con2fb /dev/fb0 /dev/tty1
|
|
||||||
...
|
|
||||||
rmmod cyblafb
|
|
||||||
modprobe cyblafb
|
|
||||||
con2fb /dev/fb1 /dev/tty1
|
|
||||||
...
|
|
||||||
|
|
||||||
Of course, you might choose another mode, and most certainly you also want to
|
|
||||||
map some other /dev/tty* to the real framebuffer device. You might also choose
|
|
||||||
to compile fbcon as a kernel module or place it permanently in the kernel.
|
|
||||||
|
|
||||||
I do not know of any way to unload fbcon, and fbcon will prevent the
|
|
||||||
framebuffer device loaded first from unloading. [If there is a way, then
|
|
||||||
please add a description here!]
|
|
||||||
|
|
||||||
Module unloading, the vesafb method
|
|
||||||
===================================
|
|
||||||
|
|
||||||
Configure the kernel:
|
|
||||||
|
|
||||||
<*> Support for frame buffer devices
|
|
||||||
[*] VESA VGA graphics support
|
|
||||||
<M> Cyberblade/i1 support
|
|
||||||
|
|
||||||
Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan
|
|
||||||
parameter is important, choose any vga parameter you like as long as it is
|
|
||||||
a graphics mode.
|
|
||||||
|
|
||||||
After booting, load cyblafb without any mode and bpp parameter and assign
|
|
||||||
cyblafb to individual ttys using con2fb, e.g.:
|
|
||||||
|
|
||||||
modprobe cyblafb
|
|
||||||
con2fb /dev/fb1 /dev/tty1
|
|
||||||
|
|
||||||
Unloading cyblafb works without problems after you assign vesafb to all
|
|
||||||
ttys again, e.g.:
|
|
||||||
|
|
||||||
con2fb /dev/fb0 /dev/tty1
|
|
||||||
rmmod cyblafb
|
|
|
@ -1,29 +0,0 @@
|
||||||
0.62
|
|
||||||
====
|
|
||||||
|
|
||||||
- the vesafb parameter has been removed as I decided to allow the
|
|
||||||
feature without any special parameter.
|
|
||||||
|
|
||||||
- Cyblafb does not use the vga style of panning any longer, now the
|
|
||||||
"right view" register in the graphics engine IO space is used. Without
|
|
||||||
that change it was impossible to use all available memory, and without
|
|
||||||
access to all available memory it is impossible to ywrap.
|
|
||||||
|
|
||||||
- The imageblit function now uses hardware acceleration for all font
|
|
||||||
widths. Hardware blitting across pixel column 2048 is broken in the
|
|
||||||
cyberblade/i1 graphics core, but we work around that hardware bug.
|
|
||||||
|
|
||||||
- modes with vxres != xres are supported now.
|
|
||||||
|
|
||||||
- ywrap scrolling is supported now and the default. This is a big
|
|
||||||
performance gain.
|
|
||||||
|
|
||||||
- default video modes use vyres > yres and vxres > xres to allow
|
|
||||||
almost optimal scrolling speed for normal and rotated screens
|
|
||||||
|
|
||||||
- some features mainly usefull for debugging the upper layers of the
|
|
||||||
framebuffer system have been added, have a look at the code
|
|
||||||
|
|
||||||
- fixed: Oops after unloading cyblafb when reading /proc/io*
|
|
||||||
|
|
||||||
- we work around some bugs of the higher framebuffer layers.
|
|
|
@ -1,85 +0,0 @@
|
||||||
I tried the following framebuffer drivers:
|
|
||||||
|
|
||||||
- TRIDENTFB is full of bugs. Acceleration is broken for Blade3D
|
|
||||||
graphics cores like the cyberblade/i1. It claims to support a great
|
|
||||||
number of devices, but documentation for most of these devices is
|
|
||||||
unfortunately not available. There is _no_ reason to use tridentfb
|
|
||||||
for cyberblade/i1 + CRT users. VESAFB is faster, and the one
|
|
||||||
advantage, mode switching, is broken in tridentfb.
|
|
||||||
|
|
||||||
- VESAFB is used by many distributions as a standard. Vesafb does
|
|
||||||
not support mode switching. VESAFB is a bit faster than the working
|
|
||||||
configurations of TRIDENTFB, but it is still too slow, even if you
|
|
||||||
use ypan.
|
|
||||||
|
|
||||||
- EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1
|
|
||||||
graphics core, but it still has serious bugs and developement seems
|
|
||||||
to have stopped. This is the one driver with TV-out support. If you
|
|
||||||
do need this feature, try epiafb.
|
|
||||||
|
|
||||||
None of these drivers was a real option for me.
|
|
||||||
|
|
||||||
I believe that is unreasonable to change code that announces to support 20
|
|
||||||
devices if I only have more or less sufficient documentation for exactly one
|
|
||||||
of these. The risk of breaking device foo while fixing device bar is too high.
|
|
||||||
|
|
||||||
So I decided to start CyBlaFB as a stripped down tridentfb.
|
|
||||||
|
|
||||||
All code specific to other Trident chips has been removed. After that there
|
|
||||||
were a lot of cosmetic changes to increase the readability of the code. All
|
|
||||||
register names were changed to those mnemonics used in the datasheet. Function
|
|
||||||
and macro names were changed if they hindered easy understanding of the code.
|
|
||||||
|
|
||||||
After that I debugged the code and implemented some new features. I'll try to
|
|
||||||
give a little summary of the main changes:
|
|
||||||
|
|
||||||
- calculation of vertical and horizontal timings was fixed
|
|
||||||
|
|
||||||
- video signal quality has been improved dramatically
|
|
||||||
|
|
||||||
- acceleration:
|
|
||||||
|
|
||||||
- fillrect and copyarea were fixed and reenabled
|
|
||||||
|
|
||||||
- color expanding imageblit was newly implemented, color
|
|
||||||
imageblit (only used to draw the penguine) still uses the
|
|
||||||
generic code.
|
|
||||||
|
|
||||||
- init of the acceleration engine was improved and moved to a
|
|
||||||
place where it really works ...
|
|
||||||
|
|
||||||
- sync function has a timeout now and tries to reset and
|
|
||||||
reinit the accel engine if necessary
|
|
||||||
|
|
||||||
- fewer slow copyarea calls when doing ypan scrolling by using
|
|
||||||
undocumented bit d21 of screen start address stored in
|
|
||||||
CR2B[5]. BIOS does use it also, so this should be safe.
|
|
||||||
|
|
||||||
- cyblafb rejects any attempt to set modes that would cause vclk
|
|
||||||
values above reasonable 230 MHz. 32bit modes use a clock
|
|
||||||
multiplicator of 2, so fbset does show the correct values for
|
|
||||||
pixclock but not for vclk in this case. The fbset limit is 115 MHz
|
|
||||||
for 32 bpp modes.
|
|
||||||
|
|
||||||
- cyblafb rejects modes known to be broken or unimplemented (all
|
|
||||||
interlaced modes, all doublescan modes for now)
|
|
||||||
|
|
||||||
- cyblafb now works independant of the video mode in effect at startup
|
|
||||||
time (tridentfb does not init all needed registers to reasonable
|
|
||||||
values)
|
|
||||||
|
|
||||||
- switching between video modes does work reliably now
|
|
||||||
|
|
||||||
- the first video mode now is the one selected on startup using the
|
|
||||||
vga=???? mechanism or any of
|
|
||||||
- 640x480, 800x600, 1024x768, 1280x1024
|
|
||||||
- 8, 16, 24 or 32 bpp
|
|
||||||
- refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32
|
|
||||||
is limited to 63Hz)
|
|
||||||
|
|
||||||
- pci retry and pci burst mode are settable (try to disable if you
|
|
||||||
experience latency problems)
|
|
||||||
|
|
||||||
- built as a module cyblafb might be unloaded and reloaded using
|
|
||||||
the vfb module and con2vt or might be used together with vesafb
|
|
||||||
|
|
|
@ -6,20 +6,47 @@ be removed from this file.
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What: old static regulatory information and ieee80211_regdom module parameter
|
What: The ieee80211_regdom module parameter
|
||||||
When: 2.6.29
|
When: March 2010 / desktop catchup
|
||||||
|
|
||||||
|
Why: This was inherited by the CONFIG_WIRELESS_OLD_REGULATORY code,
|
||||||
|
and currently serves as an option for users to define an
|
||||||
|
ISO / IEC 3166 alpha2 code for the country they are currently
|
||||||
|
present in. Although there are userspace API replacements for this
|
||||||
|
through nl80211 distributions haven't yet caught up with implementing
|
||||||
|
decent alternatives through standard GUIs. Although available as an
|
||||||
|
option through iw or wpa_supplicant its just a matter of time before
|
||||||
|
distributions pick up good GUI options for this. The ideal solution
|
||||||
|
would actually consist of intelligent designs which would do this for
|
||||||
|
the user automatically even when travelling through different countries.
|
||||||
|
Until then we leave this module parameter as a compromise.
|
||||||
|
|
||||||
|
When userspace improves with reasonable widely-available alternatives for
|
||||||
|
this we will no longer need this module parameter. This entry hopes that
|
||||||
|
by the super-futuristically looking date of "March 2010" we will have
|
||||||
|
such replacements widely available.
|
||||||
|
|
||||||
|
Who: Luis R. Rodriguez <lrodriguez@atheros.com>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: CONFIG_WIRELESS_OLD_REGULATORY - old static regulatory information
|
||||||
|
When: March 2010 / desktop catchup
|
||||||
|
|
||||||
Why: The old regulatory infrastructure has been replaced with a new one
|
Why: The old regulatory infrastructure has been replaced with a new one
|
||||||
which does not require statically defined regulatory domains. We do
|
which does not require statically defined regulatory domains. We do
|
||||||
not want to keep static regulatory domains in the kernel due to the
|
not want to keep static regulatory domains in the kernel due to the
|
||||||
the dynamic nature of regulatory law and localization. We kept around
|
the dynamic nature of regulatory law and localization. We kept around
|
||||||
the old static definitions for the regulatory domains of:
|
the old static definitions for the regulatory domains of:
|
||||||
|
|
||||||
* US
|
* US
|
||||||
* JP
|
* JP
|
||||||
* EU
|
* EU
|
||||||
|
|
||||||
and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was
|
and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was
|
||||||
set. We also kept around the ieee80211_regdom module parameter in case
|
set. We will remove this option once the standard Linux desktop catches
|
||||||
some applications were relying on it. Changing regulatory domains
|
up with the new userspace APIs we have implemented.
|
||||||
can now be done instead by using nl80211, as is done with iw.
|
|
||||||
Who: Luis R. Rodriguez <lrodriguez@atheros.com>
|
Who: Luis R. Rodriguez <lrodriguez@atheros.com>
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
@ -37,10 +64,10 @@ Who: Pavel Machek <pavel@suse.cz>
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
|
What: Video4Linux API 1 ioctls and from Video devices.
|
||||||
When: December 2008
|
When: July 2009
|
||||||
Files: include/linux/video_decoder.h include/linux/videodev.h
|
Files: include/linux/videodev.h
|
||||||
Check: include/linux/video_decoder.h include/linux/videodev.h
|
Check: include/linux/videodev.h
|
||||||
Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
|
Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
|
||||||
series. The old API have lots of drawbacks and don't provide enough
|
series. The old API have lots of drawbacks and don't provide enough
|
||||||
means to work with all video and audio standards. The newer API is
|
means to work with all video and audio standards. The newer API is
|
||||||
|
@ -229,7 +256,9 @@ Who: Jan Engelhardt <jengelh@computergmbh.de>
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What: b43 support for firmware revision < 410
|
What: b43 support for firmware revision < 410
|
||||||
When: July 2008
|
When: The schedule was July 2008, but it was decided that we are going to keep the
|
||||||
|
code as long as there are no major maintanance headaches.
|
||||||
|
So it _could_ be removed _any_ time now, if it conflicts with something new.
|
||||||
Why: The support code for the old firmware hurts code readability/maintainability
|
Why: The support code for the old firmware hurts code readability/maintainability
|
||||||
and slightly hurts runtime performance. Bugfixes for the old firmware
|
and slightly hurts runtime performance. Bugfixes for the old firmware
|
||||||
are not provided by Broadcom anymore.
|
are not provided by Broadcom anymore.
|
||||||
|
@ -282,6 +311,18 @@ Who: Vlad Yasevich <vladislav.yasevich@hp.com>
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
What: Ability for non root users to shm_get hugetlb pages based on mlock
|
||||||
|
resource limits
|
||||||
|
When: 2.6.31
|
||||||
|
Why: Non root users need to be part of /proc/sys/vm/hugetlb_shm_group or
|
||||||
|
have CAP_IPC_LOCK to be able to allocate shm segments backed by
|
||||||
|
huge pages. The mlock based rlimit check to allow shm hugetlb is
|
||||||
|
inconsistent with mmap based allocations. Hence it is being
|
||||||
|
deprecated.
|
||||||
|
Who: Ravikiran Thirumalai <kiran@scalex86.org>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
What: CONFIG_THERMAL_HWMON
|
What: CONFIG_THERMAL_HWMON
|
||||||
When: January 2009
|
When: January 2009
|
||||||
Why: This option was introduced just to allow older lm-sensors userspace
|
Why: This option was introduced just to allow older lm-sensors userspace
|
||||||
|
@ -311,7 +352,8 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
|
What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
|
||||||
When: 2.6.29 (ideally) or 2.6.30 (more likely)
|
When: 2.6.30
|
||||||
|
Check: i2c_attach_client i2c_detach_client
|
||||||
Why: Deprecated by the new (standard) device driver binding model. Use
|
Why: Deprecated by the new (standard) device driver binding model. Use
|
||||||
i2c_driver->probe() and ->remove() instead.
|
i2c_driver->probe() and ->remove() instead.
|
||||||
Who: Jean Delvare <khali@linux-fr.org>
|
Who: Jean Delvare <khali@linux-fr.org>
|
||||||
|
@ -326,17 +368,6 @@ Who: Hans de Goede <hdegoede@redhat.com>
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What: SELinux "compat_net" functionality
|
|
||||||
When: 2.6.30 at the earliest
|
|
||||||
Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
|
|
||||||
network access control functionality of SELinux. Secmark offers both
|
|
||||||
better performance and greater flexibility than the "compat_net"
|
|
||||||
mechanism. Now that the major Linux distributions have moved to
|
|
||||||
Secmark, it is time to deprecate the older mechanism and start the
|
|
||||||
process of removing the old code.
|
|
||||||
Who: Paul Moore <paul.moore@hp.com>
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
What: sysfs ui for changing p4-clockmod parameters
|
What: sysfs ui for changing p4-clockmod parameters
|
||||||
When: September 2009
|
When: September 2009
|
||||||
Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
|
Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
|
||||||
|
@ -344,3 +375,52 @@ Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
|
||||||
Removal is subject to fixing any remaining bugs in ACPI which may
|
Removal is subject to fixing any remaining bugs in ACPI which may
|
||||||
cause the thermal throttling not to happen at the right time.
|
cause the thermal throttling not to happen at the right time.
|
||||||
Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
|
Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
What: __do_IRQ all in one fits nothing interrupt handler
|
||||||
|
When: 2.6.32
|
||||||
|
Why: __do_IRQ was kept for easy migration to the type flow handlers.
|
||||||
|
More than two years of migration time is enough.
|
||||||
|
Who: Thomas Gleixner <tglx@linutronix.de>
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
What: obsolete generic irq defines and typedefs
|
||||||
|
When: 2.6.30
|
||||||
|
Why: The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t)
|
||||||
|
have been kept around for migration reasons. After more than two years
|
||||||
|
it's time to remove them finally
|
||||||
|
Who: Thomas Gleixner <tglx@linutronix.de>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: fakephp and associated sysfs files in /sys/bus/pci/slots/
|
||||||
|
When: 2011
|
||||||
|
Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
|
||||||
|
represent a machine's physical PCI slots. The change in semantics
|
||||||
|
had userspace implications, as the hotplug core no longer allowed
|
||||||
|
drivers to create multiple sysfs files per physical slot (required
|
||||||
|
for multi-function devices, e.g.). fakephp was seen as a developer's
|
||||||
|
tool only, and its interface changed. Too late, we learned that
|
||||||
|
there were some users of the fakephp interface.
|
||||||
|
|
||||||
|
In 2.6.30, the original fakephp interface was restored. At the same
|
||||||
|
time, the PCI core gained the ability that fakephp provided, namely
|
||||||
|
function-level hot-remove and hot-add.
|
||||||
|
|
||||||
|
Since the PCI core now provides the same functionality, exposed in:
|
||||||
|
|
||||||
|
/sys/bus/pci/rescan
|
||||||
|
/sys/bus/pci/devices/.../remove
|
||||||
|
/sys/bus/pci/devices/.../rescan
|
||||||
|
|
||||||
|
there is no functional reason to maintain fakephp as well.
|
||||||
|
|
||||||
|
We will keep the existing module so that 'modprobe fakephp' will
|
||||||
|
present the old /sys/bus/pci/slots/... interface for compatibility,
|
||||||
|
but users are urged to migrate their applications to the API above.
|
||||||
|
|
||||||
|
After a reasonable transition period, we will remove the legacy
|
||||||
|
fakephp interface.
|
||||||
|
Who: Alex Chiang <achiang@hp.com>
|
||||||
|
|
|
@ -437,8 +437,11 @@ grab BKL for cases when we close a file that had been opened r/w, but that
|
||||||
can and should be done using the internal locking with smaller critical areas).
|
can and should be done using the internal locking with smaller critical areas).
|
||||||
Current worst offender is ext2_get_block()...
|
Current worst offender is ext2_get_block()...
|
||||||
|
|
||||||
->fasync() is a mess. This area needs a big cleanup and that will probably
|
->fasync() is called without BKL protection, and is responsible for
|
||||||
affect locking.
|
maintaining the FASYNC bit in filp->f_flags. Most instances call
|
||||||
|
fasync_helper(), which does that maintenance, so it's not normally
|
||||||
|
something one needs to worry about. Return values > 0 will be mapped to
|
||||||
|
zero in the VFS layer.
|
||||||
|
|
||||||
->readdir() and ->ioctl() on directories must be changed. Ideally we would
|
->readdir() and ->ioctl() on directories must be changed. Ideally we would
|
||||||
move ->readdir() to inode_operations and use a separate method for directory
|
move ->readdir() to inode_operations and use a separate method for directory
|
||||||
|
@ -502,7 +505,7 @@ prototypes:
|
||||||
void (*open)(struct vm_area_struct*);
|
void (*open)(struct vm_area_struct*);
|
||||||
void (*close)(struct vm_area_struct*);
|
void (*close)(struct vm_area_struct*);
|
||||||
int (*fault)(struct vm_area_struct*, struct vm_fault *);
|
int (*fault)(struct vm_area_struct*, struct vm_fault *);
|
||||||
int (*page_mkwrite)(struct vm_area_struct *, struct page *);
|
int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *);
|
||||||
int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
|
int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
|
||||||
|
|
||||||
locking rules:
|
locking rules:
|
||||||
|
|
|
@ -85,7 +85,7 @@ Note: More extensive information for getting started with ext4 can be
|
||||||
* extent format more robust in face of on-disk corruption due to magics,
|
* extent format more robust in face of on-disk corruption due to magics,
|
||||||
* internal redundancy in tree
|
* internal redundancy in tree
|
||||||
* improved file allocation (multi-block alloc)
|
* improved file allocation (multi-block alloc)
|
||||||
* fix 32000 subdirectory limit
|
* lift 32000 subdirectory limit imposed by i_links_count[1]
|
||||||
* nsec timestamps for mtime, atime, ctime, create time
|
* nsec timestamps for mtime, atime, ctime, create time
|
||||||
* inode version field on disk (NFSv4, Lustre)
|
* inode version field on disk (NFSv4, Lustre)
|
||||||
* reduced e2fsck time via uninit_bg feature
|
* reduced e2fsck time via uninit_bg feature
|
||||||
|
@ -100,6 +100,9 @@ Note: More extensive information for getting started with ext4 can be
|
||||||
* efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force
|
* efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force
|
||||||
the ordering)
|
the ordering)
|
||||||
|
|
||||||
|
[1] Filesystems with a block size of 1k may see a limit imposed by the
|
||||||
|
directory hash tree having a maximum depth of two.
|
||||||
|
|
||||||
2.2 Candidate features for future inclusion
|
2.2 Candidate features for future inclusion
|
||||||
|
|
||||||
* Online defrag (patches available but not well tested)
|
* Online defrag (patches available but not well tested)
|
||||||
|
@ -180,8 +183,8 @@ commit=nrsec (*) Ext4 can be told to sync all its data and metadata
|
||||||
performance.
|
performance.
|
||||||
|
|
||||||
barrier=<0|1(*)> This enables/disables the use of write barriers in
|
barrier=<0|1(*)> This enables/disables the use of write barriers in
|
||||||
the jbd code. barrier=0 disables, barrier=1 enables.
|
barrier(*) the jbd code. barrier=0 disables, barrier=1 enables.
|
||||||
This also requires an IO stack which can support
|
nobarrier This also requires an IO stack which can support
|
||||||
barriers, and if jbd gets an error on a barrier
|
barriers, and if jbd gets an error on a barrier
|
||||||
write, it will disable again with a warning.
|
write, it will disable again with a warning.
|
||||||
Write barriers enforce proper on-disk ordering
|
Write barriers enforce proper on-disk ordering
|
||||||
|
@ -189,6 +192,9 @@ barrier=<0|1(*)> This enables/disables the use of write barriers in
|
||||||
safe to use, at some performance penalty. If
|
safe to use, at some performance penalty. If
|
||||||
your disks are battery-backed in one way or another,
|
your disks are battery-backed in one way or another,
|
||||||
disabling barriers may safely improve performance.
|
disabling barriers may safely improve performance.
|
||||||
|
The mount options "barrier" and "nobarrier" can
|
||||||
|
also be used to enable or disable barriers, for
|
||||||
|
consistency with other ext4 mount options.
|
||||||
|
|
||||||
inode_readahead=n This tuning parameter controls the maximum
|
inode_readahead=n This tuning parameter controls the maximum
|
||||||
number of inode table blocks that ext4's inode
|
number of inode table blocks that ext4's inode
|
||||||
|
@ -310,6 +316,24 @@ journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the
|
||||||
a slightly higher priority than the default I/O
|
a slightly higher priority than the default I/O
|
||||||
priority.
|
priority.
|
||||||
|
|
||||||
|
auto_da_alloc(*) Many broken applications don't use fsync() when
|
||||||
|
noauto_da_alloc replacing existing files via patterns such as
|
||||||
|
fd = open("foo.new")/write(fd,..)/close(fd)/
|
||||||
|
rename("foo.new", "foo"), or worse yet,
|
||||||
|
fd = open("foo", O_TRUNC)/write(fd,..)/close(fd).
|
||||||
|
If auto_da_alloc is enabled, ext4 will detect
|
||||||
|
the replace-via-rename and replace-via-truncate
|
||||||
|
patterns and force that any delayed allocation
|
||||||
|
blocks are allocated such that at the next
|
||||||
|
journal commit, in the default data=ordered
|
||||||
|
mode, the data blocks of the new file are forced
|
||||||
|
to disk before the rename() operation is
|
||||||
|
commited. This provides roughly the same level
|
||||||
|
of guarantees as ext3, and avoids the
|
||||||
|
"zero-length" problem that can happen when a
|
||||||
|
system crashes before the delayed allocation
|
||||||
|
blocks are forced to disk.
|
||||||
|
|
||||||
Data Mode
|
Data Mode
|
||||||
=========
|
=========
|
||||||
There are 3 different data modes:
|
There are 3 different data modes:
|
||||||
|
|
|
@ -940,27 +940,6 @@ Table 1-10: Files in /proc/fs/ext4/<devname>
|
||||||
File Content
|
File Content
|
||||||
mb_groups details of multiblock allocator buddy cache of free blocks
|
mb_groups details of multiblock allocator buddy cache of free blocks
|
||||||
mb_history multiblock allocation history
|
mb_history multiblock allocation history
|
||||||
stats controls whether the multiblock allocator should start
|
|
||||||
collecting statistics, which are shown during the unmount
|
|
||||||
group_prealloc the multiblock allocator will round up allocation
|
|
||||||
requests to a multiple of this tuning parameter if the
|
|
||||||
stripe size is not set in the ext4 superblock
|
|
||||||
max_to_scan The maximum number of extents the multiblock allocator
|
|
||||||
will search to find the best extent
|
|
||||||
min_to_scan The minimum number of extents the multiblock allocator
|
|
||||||
will search to find the best extent
|
|
||||||
order2_req Tuning parameter which controls the minimum size for
|
|
||||||
requests (as a power of 2) where the buddy cache is
|
|
||||||
used
|
|
||||||
stream_req Files which have fewer blocks than this tunable
|
|
||||||
parameter will have their blocks allocated out of a
|
|
||||||
block group specific preallocation pool, so that small
|
|
||||||
files are packed closely together. Each large file
|
|
||||||
will have its blocks allocated out of its own unique
|
|
||||||
preallocation pool.
|
|
||||||
inode_readahead Tuning parameter which controls the maximum number of
|
|
||||||
inode table blocks that ext4's inode table readahead
|
|
||||||
algorithm will pre-read into the buffer cache
|
|
||||||
..............................................................................
|
..............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ that support it. For example, a given bus might look like this:
|
||||||
| |-- enable
|
| |-- enable
|
||||||
| |-- irq
|
| |-- irq
|
||||||
| |-- local_cpus
|
| |-- local_cpus
|
||||||
|
| |-- remove
|
||||||
| |-- resource
|
| |-- resource
|
||||||
| |-- resource0
|
| |-- resource0
|
||||||
| |-- resource1
|
| |-- resource1
|
||||||
|
@ -36,6 +37,7 @@ files, each with their own function.
|
||||||
enable Whether the device is enabled (ascii, rw)
|
enable Whether the device is enabled (ascii, rw)
|
||||||
irq IRQ number (ascii, ro)
|
irq IRQ number (ascii, ro)
|
||||||
local_cpus nearby CPU mask (cpumask, ro)
|
local_cpus nearby CPU mask (cpumask, ro)
|
||||||
|
remove remove device from kernel's list (ascii, wo)
|
||||||
resource PCI resource host addresses (ascii, ro)
|
resource PCI resource host addresses (ascii, ro)
|
||||||
resource0..N PCI resource N, if present (binary, mmap)
|
resource0..N PCI resource N, if present (binary, mmap)
|
||||||
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
|
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
|
||||||
|
@ -46,6 +48,7 @@ files, each with their own function.
|
||||||
|
|
||||||
ro - read only file
|
ro - read only file
|
||||||
rw - file is readable and writable
|
rw - file is readable and writable
|
||||||
|
wo - write only file
|
||||||
mmap - file is mmapable
|
mmap - file is mmapable
|
||||||
ascii - file contains ascii text
|
ascii - file contains ascii text
|
||||||
binary - file contains binary data
|
binary - file contains binary data
|
||||||
|
@ -73,6 +76,13 @@ that the device must be enabled for a rom read to return data succesfully.
|
||||||
In the event a driver is not bound to the device, it can be enabled using the
|
In the event a driver is not bound to the device, it can be enabled using the
|
||||||
'enable' file, documented above.
|
'enable' file, documented above.
|
||||||
|
|
||||||
|
The 'remove' file is used to remove the PCI device, by writing a non-zero
|
||||||
|
integer to the file. This does not involve any kind of hot-plug functionality,
|
||||||
|
e.g. powering off the device. The device is removed from the kernel's list of
|
||||||
|
PCI devices, the sysfs directory for it is removed, and the device will be
|
||||||
|
removed from any drivers attached to it. Removal of PCI root buses is
|
||||||
|
disallowed.
|
||||||
|
|
||||||
Accessing legacy resources through sysfs
|
Accessing legacy resources through sysfs
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,9 @@ of up to +/- 0.5 degrees even when compared against precise temperature
|
||||||
readings. Be sure to have a high vs. low temperature limit gap of al least
|
readings. Be sure to have a high vs. low temperature limit gap of al least
|
||||||
1.0 degree Celsius to avoid Tout "bouncing", though!
|
1.0 degree Celsius to avoid Tout "bouncing", though!
|
||||||
|
|
||||||
As for alarms, you can read the alarm status of the DS1621 via the 'alarms'
|
The alarm bits are set when the high or low limits are met or exceeded and
|
||||||
/sys file interface. The result consists mainly of bit 6 and 5 of the
|
are reset by the module as soon as the respective temperature ranges are
|
||||||
configuration register of the chip; bit 6 (0x40 or 64) is the high alarm
|
left.
|
||||||
bit and bit 5 (0x20 or 32) the low one. These bits are set when the high or
|
|
||||||
low limits are met or exceeded and are reset by the module as soon as the
|
|
||||||
respective temperature ranges are left.
|
|
||||||
|
|
||||||
The alarm registers are in no way suitable to find out about the actual
|
The alarm registers are in no way suitable to find out about the actual
|
||||||
status of Tout. They will only tell you about its history, whether or not
|
status of Tout. They will only tell you about its history, whether or not
|
||||||
|
@ -64,45 +61,3 @@ with neither of the alarms set.
|
||||||
|
|
||||||
Temperature conversion of the DS1621 takes up to 1000ms; internal access to
|
Temperature conversion of the DS1621 takes up to 1000ms; internal access to
|
||||||
non-volatile registers may last for 10ms or below.
|
non-volatile registers may last for 10ms or below.
|
||||||
|
|
||||||
High Accuracy Temperature Reading
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
As said before, the temperature issued via the 9-bit i2c-bus data is
|
|
||||||
somewhat arbitrary. Internally, the temperature conversion is of a
|
|
||||||
different kind that is explained (not so...) well in the DS1621 data sheet.
|
|
||||||
To cut the long story short: Inside the DS1621 there are two oscillators,
|
|
||||||
both of them biassed by a temperature coefficient.
|
|
||||||
|
|
||||||
Higher resolution of the temperature reading can be achieved using the
|
|
||||||
internal projection, which means taking account of REG_COUNT and REG_SLOPE
|
|
||||||
(the driver manages them):
|
|
||||||
|
|
||||||
Taken from Dallas Semiconductors App Note 068: 'Increasing Temperature
|
|
||||||
Resolution on the DS1620' and App Note 105: 'High Resolution Temperature
|
|
||||||
Measurement with Dallas Direct-to-Digital Temperature Sensors'
|
|
||||||
|
|
||||||
- Read the 9-bit temperature and strip the LSB (Truncate the .5 degs)
|
|
||||||
- The resulting value is TEMP_READ.
|
|
||||||
- Then, read REG_COUNT.
|
|
||||||
- And then, REG_SLOPE.
|
|
||||||
|
|
||||||
TEMP = TEMP_READ - 0.25 + ((REG_SLOPE - REG_COUNT) / REG_SLOPE)
|
|
||||||
|
|
||||||
Note that this is what the DONE bit in the DS1621 configuration register is
|
|
||||||
good for: Internally, one temperature conversion takes up to 1000ms. Before
|
|
||||||
that conversion is complete you will not be able to read valid things out
|
|
||||||
of REG_COUNT and REG_SLOPE. The DONE bit, as you may have guessed by now,
|
|
||||||
tells you whether the conversion is complete ("done", in plain English) and
|
|
||||||
thus, whether the values you read are good or not.
|
|
||||||
|
|
||||||
The DS1621 has two modes of operation: "Continuous" conversion, which can
|
|
||||||
be understood as the default stand-alone mode where the chip gets the
|
|
||||||
temperature and controls external devices via its Tout pin or tells other
|
|
||||||
i2c's about it if they care. The other mode is called "1SHOT", that means
|
|
||||||
that it only figures out about the temperature when it is explicitly told
|
|
||||||
to do so; this can be seen as power saving mode.
|
|
||||||
|
|
||||||
Now if you want to read REG_COUNT and REG_SLOPE, you have to either stop
|
|
||||||
the continuous conversions until the contents of these registers are valid,
|
|
||||||
or, in 1SHOT mode, you have to have one conversion made.
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
Kernel driver lis3lv02d
|
Kernel driver lis3lv02d
|
||||||
==================
|
=======================
|
||||||
|
|
||||||
Supported chips:
|
Supported chips:
|
||||||
|
|
||||||
* STMicroelectronics LIS3LV02DL and LIS3LV02DQ
|
* STMicroelectronics LIS3LV02DL and LIS3LV02DQ
|
||||||
|
|
||||||
Author:
|
Authors:
|
||||||
Yan Burman <burman.yan@gmail.com>
|
Yan Burman <burman.yan@gmail.com>
|
||||||
Eric Piel <eric.piel@tremplin-utc.net>
|
Eric Piel <eric.piel@tremplin-utc.net>
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ Description
|
||||||
|
|
||||||
This driver provides support for the accelerometer found in various HP
|
This driver provides support for the accelerometer found in various HP
|
||||||
laptops sporting the feature officially called "HP Mobile Data
|
laptops sporting the feature officially called "HP Mobile Data
|
||||||
Protection System 3D" or "HP 3D DriveGuard". It detect automatically
|
Protection System 3D" or "HP 3D DriveGuard". It detects automatically
|
||||||
laptops with this sensor. Known models (for now the HP 2133, nc6420,
|
laptops with this sensor. Known models (for now the HP 2133, nc6420,
|
||||||
nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis
|
nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis
|
||||||
automatically oriented on standard way (eg: you can directly play
|
automatically oriented on standard way (eg: you can directly play
|
||||||
|
@ -27,7 +27,7 @@ position - 3D position that the accelerometer reports. Format: "(x,y,z)"
|
||||||
calibrate - read: values (x, y, z) that are used as the base for input
|
calibrate - read: values (x, y, z) that are used as the base for input
|
||||||
class device operation.
|
class device operation.
|
||||||
write: forces the base to be recalibrated with the current
|
write: forces the base to be recalibrated with the current
|
||||||
position.
|
position.
|
||||||
rate - reports the sampling rate of the accelerometer device in HZ
|
rate - reports the sampling rate of the accelerometer device in HZ
|
||||||
|
|
||||||
This driver also provides an absolute input class device, allowing
|
This driver also provides an absolute input class device, allowing
|
||||||
|
@ -48,7 +48,7 @@ For better compatibility between the various laptops. The values reported by
|
||||||
the accelerometer are converted into a "standard" organisation of the axes
|
the accelerometer are converted into a "standard" organisation of the axes
|
||||||
(aka "can play neverball out of the box"):
|
(aka "can play neverball out of the box"):
|
||||||
* When the laptop is horizontal the position reported is about 0 for X and Y
|
* When the laptop is horizontal the position reported is about 0 for X and Y
|
||||||
and a positive value for Z
|
and a positive value for Z
|
||||||
* If the left side is elevated, X increases (becomes positive)
|
* If the left side is elevated, X increases (becomes positive)
|
||||||
* If the front side (where the touchpad is) is elevated, Y decreases
|
* If the front side (where the touchpad is) is elevated, Y decreases
|
||||||
(becomes negative)
|
(becomes negative)
|
||||||
|
@ -59,3 +59,13 @@ email to the authors to add it to the database. When reporting a new
|
||||||
laptop, please include the output of "dmidecode" plus the value of
|
laptop, please include the output of "dmidecode" plus the value of
|
||||||
/sys/devices/platform/lis3lv02d/position in these four cases.
|
/sys/devices/platform/lis3lv02d/position in these four cases.
|
||||||
|
|
||||||
|
Q&A
|
||||||
|
---
|
||||||
|
|
||||||
|
Q: How do I safely simulate freefall? I have an HP "portable
|
||||||
|
workstation" which has about 3.5kg and a plastic case, so letting it
|
||||||
|
fall to the ground is out of question...
|
||||||
|
|
||||||
|
A: The sensor is pretty sensitive, so your hands can do it. Lift it
|
||||||
|
into free space, follow the fall with your hands for like 10
|
||||||
|
centimeters. That should be enough to trigger the detection.
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
Kernel driver ltc4215
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Linear Technology LTC4215
|
||||||
|
Prefix: 'ltc4215'
|
||||||
|
Addresses scanned: 0x44
|
||||||
|
Datasheet:
|
||||||
|
http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
|
||||||
|
|
||||||
|
Author: Ira W. Snyder <iws@ovro.caltech.edu>
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The LTC4215 controller allows a board to be safely inserted and removed
|
||||||
|
from a live backplane.
|
||||||
|
|
||||||
|
|
||||||
|
Usage Notes
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver does not probe for LTC4215 devices, due to the fact that some
|
||||||
|
of the possible addresses are unfriendly to probing. You will need to use
|
||||||
|
the "force" parameter to tell the driver where to find the device.
|
||||||
|
|
||||||
|
Example: the following will load the driver for an LTC4215 at address 0x44
|
||||||
|
on I2C bus #0:
|
||||||
|
$ modprobe ltc4215 force=0,0x44
|
||||||
|
|
||||||
|
|
||||||
|
Sysfs entries
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The LTC4215 has built-in limits for overvoltage, undervoltage, and
|
||||||
|
undercurrent warnings. This makes it very likely that the reference
|
||||||
|
circuit will be used.
|
||||||
|
|
||||||
|
in1_input input voltage
|
||||||
|
in2_input output voltage
|
||||||
|
|
||||||
|
in1_min_alarm input undervoltage alarm
|
||||||
|
in1_max_alarm input overvoltage alarm
|
||||||
|
|
||||||
|
curr1_input current
|
||||||
|
curr1_max_alarm overcurrent alarm
|
||||||
|
|
||||||
|
power1_input power usage
|
||||||
|
power1_alarm power bad alarm
|
|
@ -365,6 +365,7 @@ energy[1-*]_input Cumulative energy use
|
||||||
Unit: microJoule
|
Unit: microJoule
|
||||||
RO
|
RO
|
||||||
|
|
||||||
|
|
||||||
**********
|
**********
|
||||||
* Alarms *
|
* Alarms *
|
||||||
**********
|
**********
|
||||||
|
@ -453,6 +454,27 @@ beep_mask Bitmask for beep.
|
||||||
RW
|
RW
|
||||||
|
|
||||||
|
|
||||||
|
***********************
|
||||||
|
* Intrusion detection *
|
||||||
|
***********************
|
||||||
|
|
||||||
|
intrusion[0-*]_alarm
|
||||||
|
Chassis intrusion detection
|
||||||
|
0: OK
|
||||||
|
1: intrusion detected
|
||||||
|
RW
|
||||||
|
Contrary to regular alarm flags which clear themselves
|
||||||
|
automatically when read, this one sticks until cleared by
|
||||||
|
the user. This is done by writing 0 to the file. Writing
|
||||||
|
other values is unsupported.
|
||||||
|
|
||||||
|
intrusion[0-*]_beep
|
||||||
|
Chassis intrusion beep
|
||||||
|
0: disable
|
||||||
|
1: enable
|
||||||
|
RW
|
||||||
|
|
||||||
|
|
||||||
sysfs attribute writes interpretation
|
sysfs attribute writes interpretation
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -2,30 +2,40 @@ Kernel driver w83627ehf
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
Supported chips:
|
Supported chips:
|
||||||
* Winbond W83627EHF/EHG/DHG (ISA access ONLY)
|
* Winbond W83627EHF/EHG (ISA access ONLY)
|
||||||
Prefix: 'w83627ehf'
|
Prefix: 'w83627ehf'
|
||||||
Addresses scanned: ISA address retrieved from Super I/O registers
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
Datasheet:
|
Datasheet:
|
||||||
http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf
|
http://www.nuvoton.com.tw/NR/rdonlyres/A6A258F0-F0C9-4F97-81C0-C4D29E7E943E/0/W83627EHF.pdf
|
||||||
DHG datasheet confidential.
|
* Winbond W83627DHG
|
||||||
|
Prefix: 'w83627dhg'
|
||||||
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
|
Datasheet:
|
||||||
|
http://www.nuvoton.com.tw/NR/rdonlyres/7885623D-A487-4CF9-A47F-30C5F73D6FE6/0/W83627DHG.pdf
|
||||||
|
* Winbond W83667HG
|
||||||
|
Prefix: 'w83667hg'
|
||||||
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
|
Datasheet: not available
|
||||||
|
|
||||||
Authors:
|
Authors:
|
||||||
Jean Delvare <khali@linux-fr.org>
|
Jean Delvare <khali@linux-fr.org>
|
||||||
Yuan Mu (Winbond)
|
Yuan Mu (Winbond)
|
||||||
Rudolf Marek <r.marek@assembler.cz>
|
Rudolf Marek <r.marek@assembler.cz>
|
||||||
David Hubbard <david.c.hubbard@gmail.com>
|
David Hubbard <david.c.hubbard@gmail.com>
|
||||||
|
Gong Jun <JGong@nuvoton.com>
|
||||||
|
|
||||||
Description
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
This driver implements support for the Winbond W83627EHF, W83627EHG, and
|
This driver implements support for the Winbond W83627EHF, W83627EHG,
|
||||||
W83627DHG super I/O chips. We will refer to them collectively as Winbond chips.
|
W83627DHG and W83667HG super I/O chips. We will refer to them collectively
|
||||||
|
as Winbond chips.
|
||||||
|
|
||||||
The chips implement three temperature sensors, five fan rotation
|
The chips implement three temperature sensors, five fan rotation
|
||||||
speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
|
speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
|
||||||
VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG), alarms with beep
|
VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG and 667HG), alarms
|
||||||
warnings (control unimplemented), and some automatic fan regulation
|
with beep warnings (control unimplemented), and some automatic fan
|
||||||
strategies (plus manual fan control mode).
|
regulation strategies (plus manual fan control mode).
|
||||||
|
|
||||||
Temperatures are measured in degrees Celsius and measurement resolution is 1
|
Temperatures are measured in degrees Celsius and measurement resolution is 1
|
||||||
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
|
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
|
||||||
|
@ -54,7 +64,8 @@ follows:
|
||||||
temp1 -> pwm1
|
temp1 -> pwm1
|
||||||
temp2 -> pwm2
|
temp2 -> pwm2
|
||||||
temp3 -> pwm3
|
temp3 -> pwm3
|
||||||
prog -> pwm4 (the programmable setting is not supported by the driver)
|
prog -> pwm4 (not on 667HG; the programmable setting is not supported by
|
||||||
|
the driver)
|
||||||
|
|
||||||
/sys files
|
/sys files
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -7,10 +7,14 @@ Supported adapters:
|
||||||
* nForce3 250Gb MCP 10de:00E4
|
* nForce3 250Gb MCP 10de:00E4
|
||||||
* nForce4 MCP 10de:0052
|
* nForce4 MCP 10de:0052
|
||||||
* nForce4 MCP-04 10de:0034
|
* nForce4 MCP-04 10de:0034
|
||||||
* nForce4 MCP51 10de:0264
|
* nForce MCP51 10de:0264
|
||||||
* nForce4 MCP55 10de:0368
|
* nForce MCP55 10de:0368
|
||||||
* nForce4 MCP61 10de:03EB
|
* nForce MCP61 10de:03EB
|
||||||
* nForce4 MCP65 10de:0446
|
* nForce MCP65 10de:0446
|
||||||
|
* nForce MCP67 10de:0542
|
||||||
|
* nForce MCP73 10de:07D8
|
||||||
|
* nForce MCP78S 10de:0752
|
||||||
|
* nForce MCP79 10de:0AA2
|
||||||
|
|
||||||
Datasheet: not publicly available, but seems to be similar to the
|
Datasheet: not publicly available, but seems to be similar to the
|
||||||
AMD-8111 SMBus 2.0 adapter.
|
AMD-8111 SMBus 2.0 adapter.
|
||||||
|
|
|
@ -4,7 +4,7 @@ Supported adapters:
|
||||||
* Intel 82371AB PIIX4 and PIIX4E
|
* Intel 82371AB PIIX4 and PIIX4E
|
||||||
* Intel 82443MX (440MX)
|
* Intel 82443MX (440MX)
|
||||||
Datasheet: Publicly available at the Intel website
|
Datasheet: Publicly available at the Intel website
|
||||||
* ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
|
* ServerWorks OSB4, CSB5, CSB6, HT-1000 and HT-1100 southbridges
|
||||||
Datasheet: Only available via NDA from ServerWorks
|
Datasheet: Only available via NDA from ServerWorks
|
||||||
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
|
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
|
||||||
Datasheet: Not publicly available
|
Datasheet: Not publicly available
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
How to instantiate I2C devices
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Unlike PCI or USB devices, I2C devices are not enumerated at the hardware
|
||||||
|
level. Instead, the software must know which devices are connected on each
|
||||||
|
I2C bus segment, and what address these devices are using. For this
|
||||||
|
reason, the kernel code must instantiate I2C devices explicitly. There are
|
||||||
|
several ways to achieve this, depending on the context and requirements.
|
||||||
|
|
||||||
|
|
||||||
|
Method 1: Declare the I2C devices by bus number
|
||||||
|
-----------------------------------------------
|
||||||
|
|
||||||
|
This method is appropriate when the I2C bus is a system bus as is the case
|
||||||
|
for many embedded systems. On such systems, each I2C bus has a number
|
||||||
|
which is known in advance. It is thus possible to pre-declare the I2C
|
||||||
|
devices which live on this bus. This is done with an array of struct
|
||||||
|
i2c_board_info which is registered by calling i2c_register_board_info().
|
||||||
|
|
||||||
|
Example (from omap2 h4):
|
||||||
|
|
||||||
|
static struct i2c_board_info __initdata h4_i2c_board_info[] = {
|
||||||
|
{
|
||||||
|
I2C_BOARD_INFO("isp1301_omap", 0x2d),
|
||||||
|
.irq = OMAP_GPIO_IRQ(125),
|
||||||
|
},
|
||||||
|
{ /* EEPROM on mainboard */
|
||||||
|
I2C_BOARD_INFO("24c01", 0x52),
|
||||||
|
.platform_data = &m24c01,
|
||||||
|
},
|
||||||
|
{ /* EEPROM on cpu card */
|
||||||
|
I2C_BOARD_INFO("24c01", 0x57),
|
||||||
|
.platform_data = &m24c01,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init omap_h4_init(void)
|
||||||
|
{
|
||||||
|
(...)
|
||||||
|
i2c_register_board_info(1, h4_i2c_board_info,
|
||||||
|
ARRAY_SIZE(h4_i2c_board_info));
|
||||||
|
(...)
|
||||||
|
}
|
||||||
|
|
||||||
|
The above code declares 3 devices on I2C bus 1, including their respective
|
||||||
|
addresses and custom data needed by their drivers. When the I2C bus in
|
||||||
|
question is registered, the I2C devices will be instantiated automatically
|
||||||
|
by i2c-core.
|
||||||
|
|
||||||
|
The devices will be automatically unbound and destroyed when the I2C bus
|
||||||
|
they sit on goes away (if ever.)
|
||||||
|
|
||||||
|
|
||||||
|
Method 2: Instantiate the devices explicitly
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
This method is appropriate when a larger device uses an I2C bus for
|
||||||
|
internal communication. A typical case is TV adapters. These can have a
|
||||||
|
tuner, a video decoder, an audio decoder, etc. usually connected to the
|
||||||
|
main chip by the means of an I2C bus. You won't know the number of the I2C
|
||||||
|
bus in advance, so the method 1 described above can't be used. Instead,
|
||||||
|
you can instantiate your I2C devices explicitly. This is done by filling
|
||||||
|
a struct i2c_board_info and calling i2c_new_device().
|
||||||
|
|
||||||
|
Example (from the sfe4001 network driver):
|
||||||
|
|
||||||
|
static struct i2c_board_info sfe4001_hwmon_info = {
|
||||||
|
I2C_BOARD_INFO("max6647", 0x4e),
|
||||||
|
};
|
||||||
|
|
||||||
|
int sfe4001_init(struct efx_nic *efx)
|
||||||
|
{
|
||||||
|
(...)
|
||||||
|
efx->board_info.hwmon_client =
|
||||||
|
i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
|
||||||
|
|
||||||
|
(...)
|
||||||
|
}
|
||||||
|
|
||||||
|
The above code instantiates 1 I2C device on the I2C bus which is on the
|
||||||
|
network adapter in question.
|
||||||
|
|
||||||
|
A variant of this is when you don't know for sure if an I2C device is
|
||||||
|
present or not (for example for an optional feature which is not present
|
||||||
|
on cheap variants of a board but you have no way to tell them apart), or
|
||||||
|
it may have different addresses from one board to the next (manufacturer
|
||||||
|
changing its design without notice). In this case, you can call
|
||||||
|
i2c_new_probed_device() instead of i2c_new_device().
|
||||||
|
|
||||||
|
Example (from the pnx4008 OHCI driver):
|
||||||
|
|
||||||
|
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
|
||||||
|
|
||||||
|
static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
(...)
|
||||||
|
struct i2c_adapter *i2c_adap;
|
||||||
|
struct i2c_board_info i2c_info;
|
||||||
|
|
||||||
|
(...)
|
||||||
|
i2c_adap = i2c_get_adapter(2);
|
||||||
|
memset(&i2c_info, 0, sizeof(struct i2c_board_info));
|
||||||
|
strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
|
||||||
|
isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
|
||||||
|
normal_i2c);
|
||||||
|
i2c_put_adapter(i2c_adap);
|
||||||
|
(...)
|
||||||
|
}
|
||||||
|
|
||||||
|
The above code instantiates up to 1 I2C device on the I2C bus which is on
|
||||||
|
the OHCI adapter in question. It first tries at address 0x2c, if nothing
|
||||||
|
is found there it tries address 0x2d, and if still nothing is found, it
|
||||||
|
simply gives up.
|
||||||
|
|
||||||
|
The driver which instantiated the I2C device is responsible for destroying
|
||||||
|
it on cleanup. This is done by calling i2c_unregister_device() on the
|
||||||
|
pointer that was earlier returned by i2c_new_device() or
|
||||||
|
i2c_new_probed_device().
|
||||||
|
|
||||||
|
|
||||||
|
Method 3: Probe an I2C bus for certain devices
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
Sometimes you do not have enough information about an I2C device, not even
|
||||||
|
to call i2c_new_probed_device(). The typical case is hardware monitoring
|
||||||
|
chips on PC mainboards. There are several dozen models, which can live
|
||||||
|
at 25 different addresses. Given the huge number of mainboards out there,
|
||||||
|
it is next to impossible to build an exhaustive list of the hardware
|
||||||
|
monitoring chips being used. Fortunately, most of these chips have
|
||||||
|
manufacturer and device ID registers, so they can be identified by
|
||||||
|
probing.
|
||||||
|
|
||||||
|
In that case, I2C devices are neither declared nor instantiated
|
||||||
|
explicitly. Instead, i2c-core will probe for such devices as soon as their
|
||||||
|
drivers are loaded, and if any is found, an I2C device will be
|
||||||
|
instantiated automatically. In order to prevent any misbehavior of this
|
||||||
|
mechanism, the following restrictions apply:
|
||||||
|
* The I2C device driver must implement the detect() method, which
|
||||||
|
identifies a supported device by reading from arbitrary registers.
|
||||||
|
* Only buses which are likely to have a supported device and agree to be
|
||||||
|
probed, will be probed. For example this avoids probing for hardware
|
||||||
|
monitoring chips on a TV adapter.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
See lm90_driver and lm90_detect() in drivers/hwmon/lm90.c
|
||||||
|
|
||||||
|
I2C devices instantiated as a result of such a successful probe will be
|
||||||
|
destroyed automatically when the driver which detected them is removed,
|
||||||
|
or when the underlying I2C bus is itself destroyed, whichever happens
|
||||||
|
first.
|
||||||
|
|
||||||
|
Those of you familiar with the i2c subsystem of 2.4 kernels and early 2.6
|
||||||
|
kernels will find out that this method 3 is essentially similar to what
|
||||||
|
was done there. Two significant differences are:
|
||||||
|
* Probing is only one way to instantiate I2C devices now, while it was the
|
||||||
|
only way back then. Where possible, methods 1 and 2 should be preferred.
|
||||||
|
Method 3 should only be used when there is no other way, as it can have
|
||||||
|
undesirable side effects.
|
||||||
|
* I2C buses must now explicitly say which I2C driver classes can probe
|
||||||
|
them (by the means of the class bitfield), while all I2C buses were
|
||||||
|
probed by default back then. The default is an empty class which means
|
||||||
|
that no probing happens. The purpose of the class bitfield is to limit
|
||||||
|
the aforementioned undesirable side effects.
|
||||||
|
|
||||||
|
Once again, method 3 should be avoided wherever possible. Explicit device
|
||||||
|
instantiation (methods 1 and 2) is much preferred for it is safer and
|
||||||
|
faster.
|
|
@ -207,15 +207,26 @@ You simply have to define a detect callback which will attempt to
|
||||||
identify supported devices (returning 0 for supported ones and -ENODEV
|
identify supported devices (returning 0 for supported ones and -ENODEV
|
||||||
for unsupported ones), a list of addresses to probe, and a device type
|
for unsupported ones), a list of addresses to probe, and a device type
|
||||||
(or class) so that only I2C buses which may have that type of device
|
(or class) so that only I2C buses which may have that type of device
|
||||||
connected (and not otherwise enumerated) will be probed. The i2c
|
connected (and not otherwise enumerated) will be probed. For example,
|
||||||
core will then call you back as needed and will instantiate a device
|
a driver for a hardware monitoring chip for which auto-detection is
|
||||||
for you for every successful detection.
|
needed would set its class to I2C_CLASS_HWMON, and only I2C adapters
|
||||||
|
with a class including I2C_CLASS_HWMON would be probed by this driver.
|
||||||
|
Note that the absence of matching classes does not prevent the use of
|
||||||
|
a device of that type on the given I2C adapter. All it prevents is
|
||||||
|
auto-detection; explicit instantiation of devices is still possible.
|
||||||
|
|
||||||
Note that this mechanism is purely optional and not suitable for all
|
Note that this mechanism is purely optional and not suitable for all
|
||||||
devices. You need some reliable way to identify the supported devices
|
devices. You need some reliable way to identify the supported devices
|
||||||
(typically using device-specific, dedicated identification registers),
|
(typically using device-specific, dedicated identification registers),
|
||||||
otherwise misdetections are likely to occur and things can get wrong
|
otherwise misdetections are likely to occur and things can get wrong
|
||||||
quickly.
|
quickly. Keep in mind that the I2C protocol doesn't include any
|
||||||
|
standard way to detect the presence of a chip at a given address, let
|
||||||
|
alone a standard way to identify devices. Even worse is the lack of
|
||||||
|
semantics associated to bus transfers, which means that the same
|
||||||
|
transfer can be seen as a read operation by a chip and as a write
|
||||||
|
operation by another chip. For these reasons, explicit device
|
||||||
|
instantiation should always be preferred to auto-detection where
|
||||||
|
possible.
|
||||||
|
|
||||||
|
|
||||||
Device Deletion
|
Device Deletion
|
||||||
|
|
|
@ -122,10 +122,8 @@ Code Seq# Include File Comments
|
||||||
'c' 00-7F linux/coda.h conflict!
|
'c' 00-7F linux/coda.h conflict!
|
||||||
'c' 80-9F arch/s390/include/asm/chsc.h
|
'c' 80-9F arch/s390/include/asm/chsc.h
|
||||||
'd' 00-FF linux/char/drm/drm/h conflict!
|
'd' 00-FF linux/char/drm/drm/h conflict!
|
||||||
'd' 00-DF linux/video_decoder.h conflict!
|
|
||||||
'd' F0-FF linux/digi1.h
|
'd' F0-FF linux/digi1.h
|
||||||
'e' all linux/digi1.h conflict!
|
'e' all linux/digi1.h conflict!
|
||||||
'e' 00-1F linux/video_encoder.h conflict!
|
|
||||||
'e' 00-1F net/irda/irtty.h conflict!
|
'e' 00-1F net/irda/irtty.h conflict!
|
||||||
'f' 00-1F linux/ext2_fs.h
|
'f' 00-1F linux/ext2_fs.h
|
||||||
'h' 00-7F Charon filesystem
|
'h' 00-7F Charon filesystem
|
||||||
|
|
|
@ -44,6 +44,7 @@ parameter is applicable:
|
||||||
FB The frame buffer device is enabled.
|
FB The frame buffer device is enabled.
|
||||||
HW Appropriate hardware is enabled.
|
HW Appropriate hardware is enabled.
|
||||||
IA-64 IA-64 architecture is enabled.
|
IA-64 IA-64 architecture is enabled.
|
||||||
|
IMA Integrity measurement architecture is enabled.
|
||||||
IOSCHED More than one I/O scheduler is enabled.
|
IOSCHED More than one I/O scheduler is enabled.
|
||||||
IP_PNP IP DHCP, BOOTP, or RARP is enabled.
|
IP_PNP IP DHCP, BOOTP, or RARP is enabled.
|
||||||
ISAPNP ISA PnP code is enabled.
|
ISAPNP ISA PnP code is enabled.
|
||||||
|
@ -491,11 +492,23 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
Range: 0 - 8192
|
Range: 0 - 8192
|
||||||
Default: 64
|
Default: 64
|
||||||
|
|
||||||
|
dma_debug=off If the kernel is compiled with DMA_API_DEBUG support
|
||||||
|
this option disables the debugging code at boot.
|
||||||
|
|
||||||
|
dma_debug_entries=<number>
|
||||||
|
This option allows to tune the number of preallocated
|
||||||
|
entries for DMA-API debugging code. One entry is
|
||||||
|
required per DMA-API allocation. Use this if the
|
||||||
|
DMA-API debugging code disables itself because the
|
||||||
|
architectural default is too low.
|
||||||
|
|
||||||
hpet= [X86-32,HPET] option to control HPET usage
|
hpet= [X86-32,HPET] option to control HPET usage
|
||||||
Format: { enable (default) | disable | force }
|
Format: { enable (default) | disable | force |
|
||||||
|
verbose }
|
||||||
disable: disable HPET and use PIT instead
|
disable: disable HPET and use PIT instead
|
||||||
force: allow force enabled of undocumented chips (ICH4,
|
force: allow force enabled of undocumented chips (ICH4,
|
||||||
VIA, nVidia)
|
VIA, nVidia)
|
||||||
|
verbose: show contents of HPET registers during setup
|
||||||
|
|
||||||
com20020= [HW,NET] ARCnet - COM20020 chipset
|
com20020= [HW,NET] ARCnet - COM20020 chipset
|
||||||
Format:
|
Format:
|
||||||
|
@ -829,6 +842,15 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
|
|
||||||
hvc_iucv= [S390] Number of z/VM IUCV hypervisor console (HVC)
|
hvc_iucv= [S390] Number of z/VM IUCV hypervisor console (HVC)
|
||||||
terminal devices. Valid values: 0..8
|
terminal devices. Valid values: 0..8
|
||||||
|
hvc_iucv_allow= [S390] Comma-separated list of z/VM user IDs.
|
||||||
|
If specified, z/VM IUCV HVC accepts connections
|
||||||
|
from listed z/VM user IDs only.
|
||||||
|
|
||||||
|
i2c_bus= [HW] Override the default board specific I2C bus speed
|
||||||
|
or register an additional I2C bus that is not
|
||||||
|
registered from board initialization code.
|
||||||
|
Format:
|
||||||
|
<bus_id>,<clkrate>
|
||||||
|
|
||||||
i8042.debug [HW] Toggle i8042 debug mode
|
i8042.debug [HW] Toggle i8042 debug mode
|
||||||
i8042.direct [HW] Put keyboard port into non-translated mode
|
i8042.direct [HW] Put keyboard port into non-translated mode
|
||||||
|
@ -902,6 +924,15 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
ihash_entries= [KNL]
|
ihash_entries= [KNL]
|
||||||
Set number of hash buckets for inode cache.
|
Set number of hash buckets for inode cache.
|
||||||
|
|
||||||
|
ima_audit= [IMA]
|
||||||
|
Format: { "0" | "1" }
|
||||||
|
0 -- integrity auditing messages. (Default)
|
||||||
|
1 -- enable informational integrity auditing messages.
|
||||||
|
|
||||||
|
ima_hash= [IMA]
|
||||||
|
Formt: { "sha1" | "md5" }
|
||||||
|
default: "sha1"
|
||||||
|
|
||||||
in2000= [HW,SCSI]
|
in2000= [HW,SCSI]
|
||||||
See header of drivers/scsi/in2000.c.
|
See header of drivers/scsi/in2000.c.
|
||||||
|
|
||||||
|
@ -1664,6 +1695,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
See also Documentation/blockdev/paride.txt.
|
See also Documentation/blockdev/paride.txt.
|
||||||
|
|
||||||
pci=option[,option...] [PCI] various PCI subsystem options:
|
pci=option[,option...] [PCI] various PCI subsystem options:
|
||||||
|
earlydump [X86] dump PCI config space before the kernel
|
||||||
|
changes anything
|
||||||
off [X86] don't probe for the PCI bus
|
off [X86] don't probe for the PCI bus
|
||||||
bios [X86-32] force use of PCI BIOS, don't access
|
bios [X86-32] force use of PCI BIOS, don't access
|
||||||
the hardware directly. Use this if your machine
|
the hardware directly. Use this if your machine
|
||||||
|
@ -1763,6 +1796,15 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
cbmemsize=nn[KMG] The fixed amount of bus space which is
|
cbmemsize=nn[KMG] The fixed amount of bus space which is
|
||||||
reserved for the CardBus bridge's memory
|
reserved for the CardBus bridge's memory
|
||||||
window. The default value is 64 megabytes.
|
window. The default value is 64 megabytes.
|
||||||
|
resource_alignment=
|
||||||
|
Format:
|
||||||
|
[<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...]
|
||||||
|
Specifies alignment and device to reassign
|
||||||
|
aligned memory resources.
|
||||||
|
If <order of align> is not specified,
|
||||||
|
PAGE_SIZE is used as alignment.
|
||||||
|
PCI-PCI bridge can be specified, if resource
|
||||||
|
windows need to be expanded.
|
||||||
|
|
||||||
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
|
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
|
||||||
Management.
|
Management.
|
||||||
|
@ -1821,11 +1863,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
autoconfiguration.
|
autoconfiguration.
|
||||||
Ranges are in pairs (memory base and size).
|
Ranges are in pairs (memory base and size).
|
||||||
|
|
||||||
dynamic_printk Enables pr_debug()/dev_dbg() calls if
|
|
||||||
CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
|
|
||||||
These can also be switched on/off via
|
|
||||||
<debugfs>/dynamic_printk/modules
|
|
||||||
|
|
||||||
print-fatal-signals=
|
print-fatal-signals=
|
||||||
[KNL] debug: print fatal signals
|
[KNL] debug: print fatal signals
|
||||||
print-fatal-signals=1: print segfault info to
|
print-fatal-signals=1: print segfault info to
|
||||||
|
@ -2014,15 +2051,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
If enabled at boot time, /selinux/disable can be used
|
If enabled at boot time, /selinux/disable can be used
|
||||||
later to disable prior to initial policy load.
|
later to disable prior to initial policy load.
|
||||||
|
|
||||||
selinux_compat_net =
|
|
||||||
[SELINUX] Set initial selinux_compat_net flag value.
|
|
||||||
Format: { "0" | "1" }
|
|
||||||
0 -- use new secmark-based packet controls
|
|
||||||
1 -- use legacy packet controls
|
|
||||||
Default value is 0 (preferred).
|
|
||||||
Value can be changed at runtime via
|
|
||||||
/selinux/compat_net.
|
|
||||||
|
|
||||||
serialnumber [BUGS=X86-32]
|
serialnumber [BUGS=X86-32]
|
||||||
|
|
||||||
shapers= [NET]
|
shapers= [NET]
|
||||||
|
|
|
@ -1630,6 +1630,13 @@ static bool service_io(struct device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* OK, so we noted that it was pretty poor to use an fdatasync as a
|
||||||
|
* barrier. But Christoph Hellwig points out that we need a sync
|
||||||
|
* *afterwards* as well: "Barriers specify no reordering to the front
|
||||||
|
* or the back." And Jens Axboe confirmed it, so here we are: */
|
||||||
|
if (out->type & VIRTIO_BLK_T_BARRIER)
|
||||||
|
fdatasync(vblk->fd);
|
||||||
|
|
||||||
/* We can't trigger an IRQ, because we're not the Launcher. It does
|
/* We can't trigger an IRQ, because we're not the Launcher. It does
|
||||||
* that when we tell it we're done. */
|
* that when we tell it we're done. */
|
||||||
add_used(dev->vq, head, wlen);
|
add_used(dev->vq, head, wlen);
|
||||||
|
|
|
@ -27,33 +27,37 @@ lock-class.
|
||||||
State
|
State
|
||||||
-----
|
-----
|
||||||
|
|
||||||
The validator tracks lock-class usage history into 5 separate state bits:
|
The validator tracks lock-class usage history into 4n + 1 separate state bits:
|
||||||
|
|
||||||
- 'ever held in hardirq context' [ == hardirq-safe ]
|
- 'ever held in STATE context'
|
||||||
- 'ever held in softirq context' [ == softirq-safe ]
|
- 'ever head as readlock in STATE context'
|
||||||
- 'ever held with hardirqs enabled' [ == hardirq-unsafe ]
|
- 'ever head with STATE enabled'
|
||||||
- 'ever held with softirqs and hardirqs enabled' [ == softirq-unsafe ]
|
- 'ever head as readlock with STATE enabled'
|
||||||
|
|
||||||
|
Where STATE can be either one of (kernel/lockdep_states.h)
|
||||||
|
- hardirq
|
||||||
|
- softirq
|
||||||
|
- reclaim_fs
|
||||||
|
|
||||||
- 'ever used' [ == !unused ]
|
- 'ever used' [ == !unused ]
|
||||||
|
|
||||||
When locking rules are violated, these 4 state bits are presented in the
|
When locking rules are violated, these state bits are presented in the
|
||||||
locking error messages, inside curlies. A contrived example:
|
locking error messages, inside curlies. A contrived example:
|
||||||
|
|
||||||
modprobe/2287 is trying to acquire lock:
|
modprobe/2287 is trying to acquire lock:
|
||||||
(&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
|
(&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
|
||||||
|
|
||||||
but task is already holding lock:
|
but task is already holding lock:
|
||||||
(&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
|
(&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
|
||||||
|
|
||||||
|
|
||||||
The bit position indicates hardirq, softirq, hardirq-read,
|
The bit position indicates STATE, STATE-read, for each of the states listed
|
||||||
softirq-read respectively, and the character displayed in each
|
above, and the character displayed in each indicates:
|
||||||
indicates:
|
|
||||||
|
|
||||||
'.' acquired while irqs disabled
|
'.' acquired while irqs disabled
|
||||||
'+' acquired in irq context
|
'+' acquired in irq context
|
||||||
'-' acquired with irqs enabled
|
'-' acquired with irqs enabled
|
||||||
'?' read acquired in irq context with irqs enabled.
|
'?' acquired in irq context with irqs enabled.
|
||||||
|
|
||||||
Unused mutexes cannot be part of the cause of an error.
|
Unused mutexes cannot be part of the cause of an error.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
Kernel driver isl29003
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Intersil ISL29003
|
||||||
|
Prefix: 'isl29003'
|
||||||
|
Addresses scanned: none
|
||||||
|
Datasheet:
|
||||||
|
http://www.intersil.com/data/fn/fn7464.pdf
|
||||||
|
|
||||||
|
Author: Daniel Mack <daniel@caiaq.de>
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
The ISL29003 is an integrated light sensor with a 16-bit integrating type
|
||||||
|
ADC, I2C user programmable lux range select for optimized counts/lux, and
|
||||||
|
I2C multi-function control and monitoring capabilities. The internal ADC
|
||||||
|
provides 16-bit resolution while rejecting 50Hz and 60Hz flicker caused by
|
||||||
|
artificial light sources.
|
||||||
|
|
||||||
|
The driver allows to set the lux range, the bit resolution, the operational
|
||||||
|
mode (see below) and the power state of device and can read the current lux
|
||||||
|
value, of course.
|
||||||
|
|
||||||
|
|
||||||
|
Detection
|
||||||
|
---------
|
||||||
|
|
||||||
|
The ISL29003 does not have an ID register which could be used to identify
|
||||||
|
it, so the detection routine will just try to read from the configured I2C
|
||||||
|
addess and consider the device to be present as soon as it ACKs the
|
||||||
|
transfer.
|
||||||
|
|
||||||
|
|
||||||
|
Sysfs entries
|
||||||
|
-------------
|
||||||
|
|
||||||
|
range:
|
||||||
|
0: 0 lux to 1000 lux (default)
|
||||||
|
1: 0 lux to 4000 lux
|
||||||
|
2: 0 lux to 16,000 lux
|
||||||
|
3: 0 lux to 64,000 lux
|
||||||
|
|
||||||
|
resolution:
|
||||||
|
0: 2^16 cycles (default)
|
||||||
|
1: 2^12 cycles
|
||||||
|
2: 2^8 cycles
|
||||||
|
3: 2^4 cycles
|
||||||
|
|
||||||
|
mode:
|
||||||
|
0: diode1's current (unsigned 16bit) (default)
|
||||||
|
1: diode1's current (unsigned 16bit)
|
||||||
|
2: difference between diodes (l1 - l2, signed 15bit)
|
||||||
|
|
||||||
|
power_state:
|
||||||
|
0: device is disabled (default)
|
||||||
|
1: device is enabled
|
||||||
|
|
||||||
|
lux (read only):
|
||||||
|
returns the value from the last sensor reading
|
||||||
|
|
|
@ -141,7 +141,8 @@ rx_ccid = 2
|
||||||
Default CCID for the receiver-sender half-connection; see tx_ccid.
|
Default CCID for the receiver-sender half-connection; see tx_ccid.
|
||||||
|
|
||||||
seq_window = 100
|
seq_window = 100
|
||||||
The initial sequence window (sec. 7.5.2).
|
The initial sequence window (sec. 7.5.2) of the sender. This influences
|
||||||
|
the local ackno validity and the remote seqno validity windows (7.5.1).
|
||||||
|
|
||||||
tx_qlen = 5
|
tx_qlen = 5
|
||||||
The size of the transmit buffer in packets. A value of 0 corresponds
|
The size of the transmit buffer in packets. A value of 0 corresponds
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
ip_forward - BOOLEAN
|
ip_forward - BOOLEAN
|
||||||
0 - disabled (default)
|
0 - disabled (default)
|
||||||
not 0 - enabled
|
not 0 - enabled
|
||||||
|
|
||||||
Forward Packets between interfaces.
|
Forward Packets between interfaces.
|
||||||
|
|
||||||
|
@ -36,49 +36,49 @@ rt_cache_rebuild_count - INTEGER
|
||||||
IP Fragmentation:
|
IP Fragmentation:
|
||||||
|
|
||||||
ipfrag_high_thresh - INTEGER
|
ipfrag_high_thresh - INTEGER
|
||||||
Maximum memory used to reassemble IP fragments. When
|
Maximum memory used to reassemble IP fragments. When
|
||||||
ipfrag_high_thresh bytes of memory is allocated for this purpose,
|
ipfrag_high_thresh bytes of memory is allocated for this purpose,
|
||||||
the fragment handler will toss packets until ipfrag_low_thresh
|
the fragment handler will toss packets until ipfrag_low_thresh
|
||||||
is reached.
|
is reached.
|
||||||
|
|
||||||
ipfrag_low_thresh - INTEGER
|
ipfrag_low_thresh - INTEGER
|
||||||
See ipfrag_high_thresh
|
See ipfrag_high_thresh
|
||||||
|
|
||||||
ipfrag_time - INTEGER
|
ipfrag_time - INTEGER
|
||||||
Time in seconds to keep an IP fragment in memory.
|
Time in seconds to keep an IP fragment in memory.
|
||||||
|
|
||||||
ipfrag_secret_interval - INTEGER
|
ipfrag_secret_interval - INTEGER
|
||||||
Regeneration interval (in seconds) of the hash secret (or lifetime
|
Regeneration interval (in seconds) of the hash secret (or lifetime
|
||||||
for the hash secret) for IP fragments.
|
for the hash secret) for IP fragments.
|
||||||
Default: 600
|
Default: 600
|
||||||
|
|
||||||
ipfrag_max_dist - INTEGER
|
ipfrag_max_dist - INTEGER
|
||||||
ipfrag_max_dist is a non-negative integer value which defines the
|
ipfrag_max_dist is a non-negative integer value which defines the
|
||||||
maximum "disorder" which is allowed among fragments which share a
|
maximum "disorder" which is allowed among fragments which share a
|
||||||
common IP source address. Note that reordering of packets is
|
common IP source address. Note that reordering of packets is
|
||||||
not unusual, but if a large number of fragments arrive from a source
|
not unusual, but if a large number of fragments arrive from a source
|
||||||
IP address while a particular fragment queue remains incomplete, it
|
IP address while a particular fragment queue remains incomplete, it
|
||||||
probably indicates that one or more fragments belonging to that queue
|
probably indicates that one or more fragments belonging to that queue
|
||||||
have been lost. When ipfrag_max_dist is positive, an additional check
|
have been lost. When ipfrag_max_dist is positive, an additional check
|
||||||
is done on fragments before they are added to a reassembly queue - if
|
is done on fragments before they are added to a reassembly queue - if
|
||||||
ipfrag_max_dist (or more) fragments have arrived from a particular IP
|
ipfrag_max_dist (or more) fragments have arrived from a particular IP
|
||||||
address between additions to any IP fragment queue using that source
|
address between additions to any IP fragment queue using that source
|
||||||
address, it's presumed that one or more fragments in the queue are
|
address, it's presumed that one or more fragments in the queue are
|
||||||
lost. The existing fragment queue will be dropped, and a new one
|
lost. The existing fragment queue will be dropped, and a new one
|
||||||
started. An ipfrag_max_dist value of zero disables this check.
|
started. An ipfrag_max_dist value of zero disables this check.
|
||||||
|
|
||||||
Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
|
Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
|
||||||
result in unnecessarily dropping fragment queues when normal
|
result in unnecessarily dropping fragment queues when normal
|
||||||
reordering of packets occurs, which could lead to poor application
|
reordering of packets occurs, which could lead to poor application
|
||||||
performance. Using a very large value, e.g. 50000, increases the
|
performance. Using a very large value, e.g. 50000, increases the
|
||||||
likelihood of incorrectly reassembling IP fragments that originate
|
likelihood of incorrectly reassembling IP fragments that originate
|
||||||
from different IP datagrams, which could result in data corruption.
|
from different IP datagrams, which could result in data corruption.
|
||||||
Default: 64
|
Default: 64
|
||||||
|
|
||||||
INET peer storage:
|
INET peer storage:
|
||||||
|
|
||||||
inet_peer_threshold - INTEGER
|
inet_peer_threshold - INTEGER
|
||||||
The approximate size of the storage. Starting from this threshold
|
The approximate size of the storage. Starting from this threshold
|
||||||
entries will be thrown aggressively. This threshold also determines
|
entries will be thrown aggressively. This threshold also determines
|
||||||
entries' time-to-live and time intervals between garbage collection
|
entries' time-to-live and time intervals between garbage collection
|
||||||
passes. More entries, less time-to-live, less GC interval.
|
passes. More entries, less time-to-live, less GC interval.
|
||||||
|
@ -105,7 +105,7 @@ inet_peer_gc_maxtime - INTEGER
|
||||||
in effect under low (or absent) memory pressure on the pool.
|
in effect under low (or absent) memory pressure on the pool.
|
||||||
Measured in seconds.
|
Measured in seconds.
|
||||||
|
|
||||||
TCP variables:
|
TCP variables:
|
||||||
|
|
||||||
somaxconn - INTEGER
|
somaxconn - INTEGER
|
||||||
Limit of socket listen() backlog, known in userspace as SOMAXCONN.
|
Limit of socket listen() backlog, known in userspace as SOMAXCONN.
|
||||||
|
@ -310,7 +310,7 @@ tcp_orphan_retries - INTEGER
|
||||||
|
|
||||||
tcp_reordering - INTEGER
|
tcp_reordering - INTEGER
|
||||||
Maximal reordering of packets in a TCP stream.
|
Maximal reordering of packets in a TCP stream.
|
||||||
Default: 3
|
Default: 3
|
||||||
|
|
||||||
tcp_retrans_collapse - BOOLEAN
|
tcp_retrans_collapse - BOOLEAN
|
||||||
Bug-to-bug compatibility with some broken printers.
|
Bug-to-bug compatibility with some broken printers.
|
||||||
|
@ -521,7 +521,7 @@ IP Variables:
|
||||||
|
|
||||||
ip_local_port_range - 2 INTEGERS
|
ip_local_port_range - 2 INTEGERS
|
||||||
Defines the local port range that is used by TCP and UDP to
|
Defines the local port range that is used by TCP and UDP to
|
||||||
choose the local port. The first number is the first, the
|
choose the local port. The first number is the first, the
|
||||||
second the last local port number. Default value depends on
|
second the last local port number. Default value depends on
|
||||||
amount of memory available on the system:
|
amount of memory available on the system:
|
||||||
> 128Mb 32768-61000
|
> 128Mb 32768-61000
|
||||||
|
@ -594,12 +594,12 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN
|
||||||
|
|
||||||
If zero, icmp error messages are sent with the primary address of
|
If zero, icmp error messages are sent with the primary address of
|
||||||
the exiting interface.
|
the exiting interface.
|
||||||
|
|
||||||
If non-zero, the message will be sent with the primary address of
|
If non-zero, the message will be sent with the primary address of
|
||||||
the interface that received the packet that caused the icmp error.
|
the interface that received the packet that caused the icmp error.
|
||||||
This is the behaviour network many administrators will expect from
|
This is the behaviour network many administrators will expect from
|
||||||
a router. And it can make debugging complicated network layouts
|
a router. And it can make debugging complicated network layouts
|
||||||
much easier.
|
much easier.
|
||||||
|
|
||||||
Note that if no primary address exists for the interface selected,
|
Note that if no primary address exists for the interface selected,
|
||||||
then the primary address of the first non-loopback interface that
|
then the primary address of the first non-loopback interface that
|
||||||
|
@ -611,7 +611,7 @@ igmp_max_memberships - INTEGER
|
||||||
Change the maximum number of multicast groups we can subscribe to.
|
Change the maximum number of multicast groups we can subscribe to.
|
||||||
Default: 20
|
Default: 20
|
||||||
|
|
||||||
conf/interface/* changes special settings per interface (where "interface" is
|
conf/interface/* changes special settings per interface (where "interface" is
|
||||||
the name of your network interface)
|
the name of your network interface)
|
||||||
conf/all/* is special, changes the settings for all interfaces
|
conf/all/* is special, changes the settings for all interfaces
|
||||||
|
|
||||||
|
@ -625,11 +625,11 @@ log_martians - BOOLEAN
|
||||||
accept_redirects - BOOLEAN
|
accept_redirects - BOOLEAN
|
||||||
Accept ICMP redirect messages.
|
Accept ICMP redirect messages.
|
||||||
accept_redirects for the interface will be enabled if:
|
accept_redirects for the interface will be enabled if:
|
||||||
- both conf/{all,interface}/accept_redirects are TRUE in the case forwarding
|
- both conf/{all,interface}/accept_redirects are TRUE in the case
|
||||||
for the interface is enabled
|
forwarding for the interface is enabled
|
||||||
or
|
or
|
||||||
- at least one of conf/{all,interface}/accept_redirects is TRUE in the case
|
- at least one of conf/{all,interface}/accept_redirects is TRUE in the
|
||||||
forwarding for the interface is disabled
|
case forwarding for the interface is disabled
|
||||||
accept_redirects for the interface will be disabled otherwise
|
accept_redirects for the interface will be disabled otherwise
|
||||||
default TRUE (host)
|
default TRUE (host)
|
||||||
FALSE (router)
|
FALSE (router)
|
||||||
|
@ -640,8 +640,8 @@ forwarding - BOOLEAN
|
||||||
mc_forwarding - BOOLEAN
|
mc_forwarding - BOOLEAN
|
||||||
Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
|
Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
|
||||||
and a multicast routing daemon is required.
|
and a multicast routing daemon is required.
|
||||||
conf/all/mc_forwarding must also be set to TRUE to enable multicast routing
|
conf/all/mc_forwarding must also be set to TRUE to enable multicast
|
||||||
for the interface
|
routing for the interface
|
||||||
|
|
||||||
medium_id - INTEGER
|
medium_id - INTEGER
|
||||||
Integer value used to differentiate the devices by the medium they
|
Integer value used to differentiate the devices by the medium they
|
||||||
|
@ -649,7 +649,7 @@ medium_id - INTEGER
|
||||||
the broadcast packets are received only on one of them.
|
the broadcast packets are received only on one of them.
|
||||||
The default value 0 means that the device is the only interface
|
The default value 0 means that the device is the only interface
|
||||||
to its medium, value of -1 means that medium is not known.
|
to its medium, value of -1 means that medium is not known.
|
||||||
|
|
||||||
Currently, it is used to change the proxy_arp behavior:
|
Currently, it is used to change the proxy_arp behavior:
|
||||||
the proxy_arp feature is enabled for packets forwarded between
|
the proxy_arp feature is enabled for packets forwarded between
|
||||||
two devices attached to different media.
|
two devices attached to different media.
|
||||||
|
@ -699,16 +699,22 @@ accept_source_route - BOOLEAN
|
||||||
default TRUE (router)
|
default TRUE (router)
|
||||||
FALSE (host)
|
FALSE (host)
|
||||||
|
|
||||||
rp_filter - BOOLEAN
|
rp_filter - INTEGER
|
||||||
1 - do source validation by reversed path, as specified in RFC1812
|
|
||||||
Recommended option for single homed hosts and stub network
|
|
||||||
routers. Could cause troubles for complicated (not loop free)
|
|
||||||
networks running a slow unreliable protocol (sort of RIP),
|
|
||||||
or using static routes.
|
|
||||||
|
|
||||||
0 - No source validation.
|
0 - No source validation.
|
||||||
|
1 - Strict mode as defined in RFC3704 Strict Reverse Path
|
||||||
|
Each incoming packet is tested against the FIB and if the interface
|
||||||
|
is not the best reverse path the packet check will fail.
|
||||||
|
By default failed packets are discarded.
|
||||||
|
2 - Loose mode as defined in RFC3704 Loose Reverse Path
|
||||||
|
Each incoming packet's source address is also tested against the FIB
|
||||||
|
and if the source address is not reachable via any interface
|
||||||
|
the packet check will fail.
|
||||||
|
|
||||||
conf/all/rp_filter must also be set to TRUE to do source validation
|
Current recommended practice in RFC3704 is to enable strict mode
|
||||||
|
to prevent IP spoofing from DDos attacks. If using asymmetric routing
|
||||||
|
or other complicated routing, then loose mode is recommended.
|
||||||
|
|
||||||
|
conf/all/rp_filter must also be set to non-zero to do source validation
|
||||||
on the interface
|
on the interface
|
||||||
|
|
||||||
Default value is 0. Note that some distributions enable it
|
Default value is 0. Note that some distributions enable it
|
||||||
|
@ -782,6 +788,12 @@ arp_ignore - INTEGER
|
||||||
The max value from conf/{all,interface}/arp_ignore is used
|
The max value from conf/{all,interface}/arp_ignore is used
|
||||||
when ARP request is received on the {interface}
|
when ARP request is received on the {interface}
|
||||||
|
|
||||||
|
arp_notify - BOOLEAN
|
||||||
|
Define mode for notification of address and device changes.
|
||||||
|
0 - (default): do nothing
|
||||||
|
1 - Generate gratuitous arp replies when device is brought up
|
||||||
|
or hardware address changes.
|
||||||
|
|
||||||
arp_accept - BOOLEAN
|
arp_accept - BOOLEAN
|
||||||
Define behavior when gratuitous arp replies are received:
|
Define behavior when gratuitous arp replies are received:
|
||||||
0 - drop gratuitous arp frames
|
0 - drop gratuitous arp frames
|
||||||
|
@ -823,7 +835,7 @@ apply to IPv6 [XXX?].
|
||||||
|
|
||||||
bindv6only - BOOLEAN
|
bindv6only - BOOLEAN
|
||||||
Default value for IPV6_V6ONLY socket option,
|
Default value for IPV6_V6ONLY socket option,
|
||||||
which restricts use of the IPv6 socket to IPv6 communication
|
which restricts use of the IPv6 socket to IPv6 communication
|
||||||
only.
|
only.
|
||||||
TRUE: disable IPv4-mapped address feature
|
TRUE: disable IPv4-mapped address feature
|
||||||
FALSE: enable IPv4-mapped address feature
|
FALSE: enable IPv4-mapped address feature
|
||||||
|
@ -833,19 +845,19 @@ bindv6only - BOOLEAN
|
||||||
IPv6 Fragmentation:
|
IPv6 Fragmentation:
|
||||||
|
|
||||||
ip6frag_high_thresh - INTEGER
|
ip6frag_high_thresh - INTEGER
|
||||||
Maximum memory used to reassemble IPv6 fragments. When
|
Maximum memory used to reassemble IPv6 fragments. When
|
||||||
ip6frag_high_thresh bytes of memory is allocated for this purpose,
|
ip6frag_high_thresh bytes of memory is allocated for this purpose,
|
||||||
the fragment handler will toss packets until ip6frag_low_thresh
|
the fragment handler will toss packets until ip6frag_low_thresh
|
||||||
is reached.
|
is reached.
|
||||||
|
|
||||||
ip6frag_low_thresh - INTEGER
|
ip6frag_low_thresh - INTEGER
|
||||||
See ip6frag_high_thresh
|
See ip6frag_high_thresh
|
||||||
|
|
||||||
ip6frag_time - INTEGER
|
ip6frag_time - INTEGER
|
||||||
Time in seconds to keep an IPv6 fragment in memory.
|
Time in seconds to keep an IPv6 fragment in memory.
|
||||||
|
|
||||||
ip6frag_secret_interval - INTEGER
|
ip6frag_secret_interval - INTEGER
|
||||||
Regeneration interval (in seconds) of the hash secret (or lifetime
|
Regeneration interval (in seconds) of the hash secret (or lifetime
|
||||||
for the hash secret) for IPv6 fragments.
|
for the hash secret) for IPv6 fragments.
|
||||||
Default: 600
|
Default: 600
|
||||||
|
|
||||||
|
@ -854,17 +866,17 @@ conf/default/*:
|
||||||
|
|
||||||
|
|
||||||
conf/all/*:
|
conf/all/*:
|
||||||
Change all the interface-specific settings.
|
Change all the interface-specific settings.
|
||||||
|
|
||||||
[XXX: Other special features than forwarding?]
|
[XXX: Other special features than forwarding?]
|
||||||
|
|
||||||
conf/all/forwarding - BOOLEAN
|
conf/all/forwarding - BOOLEAN
|
||||||
Enable global IPv6 forwarding between all interfaces.
|
Enable global IPv6 forwarding between all interfaces.
|
||||||
|
|
||||||
IPv4 and IPv6 work differently here; e.g. netfilter must be used
|
IPv4 and IPv6 work differently here; e.g. netfilter must be used
|
||||||
to control which interfaces may forward packets and which not.
|
to control which interfaces may forward packets and which not.
|
||||||
|
|
||||||
This also sets all interfaces' Host/Router setting
|
This also sets all interfaces' Host/Router setting
|
||||||
'forwarding' to the specified value. See below for details.
|
'forwarding' to the specified value. See below for details.
|
||||||
|
|
||||||
This referred to as global forwarding.
|
This referred to as global forwarding.
|
||||||
|
@ -875,12 +887,12 @@ proxy_ndp - BOOLEAN
|
||||||
conf/interface/*:
|
conf/interface/*:
|
||||||
Change special settings per interface.
|
Change special settings per interface.
|
||||||
|
|
||||||
The functional behaviour for certain settings is different
|
The functional behaviour for certain settings is different
|
||||||
depending on whether local forwarding is enabled or not.
|
depending on whether local forwarding is enabled or not.
|
||||||
|
|
||||||
accept_ra - BOOLEAN
|
accept_ra - BOOLEAN
|
||||||
Accept Router Advertisements; autoconfigure using them.
|
Accept Router Advertisements; autoconfigure using them.
|
||||||
|
|
||||||
Functional default: enabled if local forwarding is disabled.
|
Functional default: enabled if local forwarding is disabled.
|
||||||
disabled if local forwarding is enabled.
|
disabled if local forwarding is enabled.
|
||||||
|
|
||||||
|
@ -926,7 +938,7 @@ accept_source_route - INTEGER
|
||||||
Default: 0
|
Default: 0
|
||||||
|
|
||||||
autoconf - BOOLEAN
|
autoconf - BOOLEAN
|
||||||
Autoconfigure addresses using Prefix Information in Router
|
Autoconfigure addresses using Prefix Information in Router
|
||||||
Advertisements.
|
Advertisements.
|
||||||
|
|
||||||
Functional default: enabled if accept_ra_pinfo is enabled.
|
Functional default: enabled if accept_ra_pinfo is enabled.
|
||||||
|
@ -935,11 +947,11 @@ autoconf - BOOLEAN
|
||||||
dad_transmits - INTEGER
|
dad_transmits - INTEGER
|
||||||
The amount of Duplicate Address Detection probes to send.
|
The amount of Duplicate Address Detection probes to send.
|
||||||
Default: 1
|
Default: 1
|
||||||
|
|
||||||
forwarding - BOOLEAN
|
|
||||||
Configure interface-specific Host/Router behaviour.
|
|
||||||
|
|
||||||
Note: It is recommended to have the same setting on all
|
forwarding - BOOLEAN
|
||||||
|
Configure interface-specific Host/Router behaviour.
|
||||||
|
|
||||||
|
Note: It is recommended to have the same setting on all
|
||||||
interfaces; mixed router/host scenarios are rather uncommon.
|
interfaces; mixed router/host scenarios are rather uncommon.
|
||||||
|
|
||||||
FALSE:
|
FALSE:
|
||||||
|
@ -948,13 +960,13 @@ forwarding - BOOLEAN
|
||||||
|
|
||||||
1. IsRouter flag is not set in Neighbour Advertisements.
|
1. IsRouter flag is not set in Neighbour Advertisements.
|
||||||
2. Router Solicitations are being sent when necessary.
|
2. Router Solicitations are being sent when necessary.
|
||||||
3. If accept_ra is TRUE (default), accept Router
|
3. If accept_ra is TRUE (default), accept Router
|
||||||
Advertisements (and do autoconfiguration).
|
Advertisements (and do autoconfiguration).
|
||||||
4. If accept_redirects is TRUE (default), accept Redirects.
|
4. If accept_redirects is TRUE (default), accept Redirects.
|
||||||
|
|
||||||
TRUE:
|
TRUE:
|
||||||
|
|
||||||
If local forwarding is enabled, Router behaviour is assumed.
|
If local forwarding is enabled, Router behaviour is assumed.
|
||||||
This means exactly the reverse from the above:
|
This means exactly the reverse from the above:
|
||||||
|
|
||||||
1. IsRouter flag is set in Neighbour Advertisements.
|
1. IsRouter flag is set in Neighbour Advertisements.
|
||||||
|
@ -989,7 +1001,7 @@ router_solicitation_interval - INTEGER
|
||||||
Default: 4
|
Default: 4
|
||||||
|
|
||||||
router_solicitations - INTEGER
|
router_solicitations - INTEGER
|
||||||
Number of Router Solicitations to send until assuming no
|
Number of Router Solicitations to send until assuming no
|
||||||
routers are present.
|
routers are present.
|
||||||
Default: 3
|
Default: 3
|
||||||
|
|
||||||
|
@ -1013,11 +1025,11 @@ temp_prefered_lft - INTEGER
|
||||||
|
|
||||||
max_desync_factor - INTEGER
|
max_desync_factor - INTEGER
|
||||||
Maximum value for DESYNC_FACTOR, which is a random value
|
Maximum value for DESYNC_FACTOR, which is a random value
|
||||||
that ensures that clients don't synchronize with each
|
that ensures that clients don't synchronize with each
|
||||||
other and generate new addresses at exactly the same time.
|
other and generate new addresses at exactly the same time.
|
||||||
value is in seconds.
|
value is in seconds.
|
||||||
Default: 600
|
Default: 600
|
||||||
|
|
||||||
regen_max_retry - INTEGER
|
regen_max_retry - INTEGER
|
||||||
Number of attempts before give up attempting to generate
|
Number of attempts before give up attempting to generate
|
||||||
valid temporary addresses.
|
valid temporary addresses.
|
||||||
|
@ -1025,13 +1037,15 @@ regen_max_retry - INTEGER
|
||||||
|
|
||||||
max_addresses - INTEGER
|
max_addresses - INTEGER
|
||||||
Number of maximum addresses per interface. 0 disables limitation.
|
Number of maximum addresses per interface. 0 disables limitation.
|
||||||
It is recommended not set too large value (or 0) because it would
|
It is recommended not set too large value (or 0) because it would
|
||||||
be too easy way to crash kernel to allow to create too much of
|
be too easy way to crash kernel to allow to create too much of
|
||||||
autoconfigured addresses.
|
autoconfigured addresses.
|
||||||
Default: 16
|
Default: 16
|
||||||
|
|
||||||
disable_ipv6 - BOOLEAN
|
disable_ipv6 - BOOLEAN
|
||||||
Disable IPv6 operation.
|
Disable IPv6 operation. If accept_dad is set to 2, this value
|
||||||
|
will be dynamically set to TRUE if DAD fails for the link-local
|
||||||
|
address.
|
||||||
Default: FALSE (enable IPv6 operation)
|
Default: FALSE (enable IPv6 operation)
|
||||||
|
|
||||||
accept_dad - INTEGER
|
accept_dad - INTEGER
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
Linux Base Driver for 10 Gigabit PCI Express Intel(R) Network Connection
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
March 10, 2009
|
||||||
|
|
||||||
|
|
||||||
|
Contents
|
||||||
|
========
|
||||||
|
|
||||||
|
- In This Release
|
||||||
|
- Identifying Your Adapter
|
||||||
|
- Building and Installation
|
||||||
|
- Additional Configurations
|
||||||
|
- Support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
In This Release
|
||||||
|
===============
|
||||||
|
|
||||||
|
This file describes the ixgbe Linux Base Driver for the 10 Gigabit PCI
|
||||||
|
Express Intel(R) Network Connection. This driver includes support for
|
||||||
|
Itanium(R)2-based systems.
|
||||||
|
|
||||||
|
For questions related to hardware requirements, refer to the documentation
|
||||||
|
supplied with your 10 Gigabit adapter. All hardware requirements listed apply
|
||||||
|
to use with Linux.
|
||||||
|
|
||||||
|
The following features are available in this kernel:
|
||||||
|
- Native VLANs
|
||||||
|
- Channel Bonding (teaming)
|
||||||
|
- SNMP
|
||||||
|
- Generic Receive Offload
|
||||||
|
- Data Center Bridging
|
||||||
|
|
||||||
|
Channel Bonding documentation can be found in the Linux kernel source:
|
||||||
|
/Documentation/networking/bonding.txt
|
||||||
|
|
||||||
|
Ethtool, lspci, and ifconfig can be used to display device and driver
|
||||||
|
specific information.
|
||||||
|
|
||||||
|
|
||||||
|
Identifying Your Adapter
|
||||||
|
========================
|
||||||
|
|
||||||
|
This driver supports devices based on the 82598 controller and the 82599
|
||||||
|
controller.
|
||||||
|
|
||||||
|
For specific information on identifying which adapter you have, please visit:
|
||||||
|
|
||||||
|
http://support.intel.com/support/network/sb/CS-008441.htm
|
||||||
|
|
||||||
|
|
||||||
|
Building and Installation
|
||||||
|
=========================
|
||||||
|
|
||||||
|
select m for "Intel(R) 10GbE PCI Express adapters support" located at:
|
||||||
|
Location:
|
||||||
|
-> Device Drivers
|
||||||
|
-> Network device support (NETDEVICES [=y])
|
||||||
|
-> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
|
||||||
|
|
||||||
|
1. make modules & make modules_install
|
||||||
|
|
||||||
|
2. Load the module:
|
||||||
|
|
||||||
|
# modprobe ixgbe
|
||||||
|
|
||||||
|
The insmod command can be used if the full
|
||||||
|
path to the driver module is specified. For example:
|
||||||
|
|
||||||
|
insmod /lib/modules/<KERNEL VERSION>/kernel/drivers/net/ixgbe/ixgbe.ko
|
||||||
|
|
||||||
|
With 2.6 based kernels also make sure that older ixgbe drivers are
|
||||||
|
removed from the kernel, before loading the new module:
|
||||||
|
|
||||||
|
rmmod ixgbe; modprobe ixgbe
|
||||||
|
|
||||||
|
3. Assign an IP address to the interface by entering the following, where
|
||||||
|
x is the interface number:
|
||||||
|
|
||||||
|
ifconfig ethx <IP_address>
|
||||||
|
|
||||||
|
4. Verify that the interface works. Enter the following, where <IP_address>
|
||||||
|
is the IP address for another machine on the same subnet as the interface
|
||||||
|
that is being tested:
|
||||||
|
|
||||||
|
ping <IP_address>
|
||||||
|
|
||||||
|
|
||||||
|
Additional Configurations
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Viewing Link Messages
|
||||||
|
---------------------
|
||||||
|
Link messages will not be displayed to the console if the distribution is
|
||||||
|
restricting system messages. In order to see network driver link messages on
|
||||||
|
your console, set dmesg to eight by entering the following:
|
||||||
|
|
||||||
|
dmesg -n 8
|
||||||
|
|
||||||
|
NOTE: This setting is not saved across reboots.
|
||||||
|
|
||||||
|
|
||||||
|
Jumbo Frames
|
||||||
|
------------
|
||||||
|
The driver supports Jumbo Frames for all adapters. Jumbo Frames support is
|
||||||
|
enabled by changing the MTU to a value larger than the default of 1500.
|
||||||
|
The maximum value for the MTU is 16110. Use the ifconfig command to
|
||||||
|
increase the MTU size. For example:
|
||||||
|
|
||||||
|
ifconfig ethx mtu 9000 up
|
||||||
|
|
||||||
|
The maximum MTU setting for Jumbo Frames is 16110. This value coincides
|
||||||
|
with the maximum Jumbo Frames size of 16128.
|
||||||
|
|
||||||
|
Generic Receive Offload, aka GRO
|
||||||
|
--------------------------------
|
||||||
|
The driver supports the in-kernel software implementation of GRO. GRO has
|
||||||
|
shown that by coalescing Rx traffic into larger chunks of data, CPU
|
||||||
|
utilization can be significantly reduced when under large Rx load. GRO is an
|
||||||
|
evolution of the previously-used LRO interface. GRO is able to coalesce
|
||||||
|
other protocols besides TCP. It's also safe to use with configurations that
|
||||||
|
are problematic for LRO, namely bridging and iSCSI.
|
||||||
|
|
||||||
|
GRO is enabled by default in the driver. Future versions of ethtool will
|
||||||
|
support disabling and re-enabling GRO on the fly.
|
||||||
|
|
||||||
|
|
||||||
|
Data Center Bridging, aka DCB
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
DCB is a configuration Quality of Service implementation in hardware.
|
||||||
|
It uses the VLAN priority tag (802.1p) to filter traffic. That means
|
||||||
|
that there are 8 different priorities that traffic can be filtered into.
|
||||||
|
It also enables priority flow control which can limit or eliminate the
|
||||||
|
number of dropped packets during network stress. Bandwidth can be
|
||||||
|
allocated to each of these priorities, which is enforced at the hardware
|
||||||
|
level.
|
||||||
|
|
||||||
|
To enable DCB support in ixgbe, you must enable the DCB netlink layer to
|
||||||
|
allow the userspace tools (see below) to communicate with the driver.
|
||||||
|
This can be found in the kernel configuration here:
|
||||||
|
|
||||||
|
-> Networking support
|
||||||
|
-> Networking options
|
||||||
|
-> Data Center Bridging support
|
||||||
|
|
||||||
|
Once this is selected, DCB support must be selected for ixgbe. This can
|
||||||
|
be found here:
|
||||||
|
|
||||||
|
-> Device Drivers
|
||||||
|
-> Network device support (NETDEVICES [=y])
|
||||||
|
-> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
|
||||||
|
-> Intel(R) 10GbE PCI Express adapters support
|
||||||
|
-> Data Center Bridging (DCB) Support
|
||||||
|
|
||||||
|
After these options are selected, you must rebuild your kernel and your
|
||||||
|
modules.
|
||||||
|
|
||||||
|
In order to use DCB, userspace tools must be downloaded and installed.
|
||||||
|
The dcbd tools can be found at:
|
||||||
|
|
||||||
|
http://e1000.sf.net
|
||||||
|
|
||||||
|
|
||||||
|
Ethtool
|
||||||
|
-------
|
||||||
|
The driver utilizes the ethtool interface for driver configuration and
|
||||||
|
diagnostics, as well as displaying statistical information. Ethtool
|
||||||
|
version 3.0 or later is required for this functionality.
|
||||||
|
|
||||||
|
The latest release of ethtool can be found from
|
||||||
|
http://sourceforge.net/projects/gkernel.
|
||||||
|
|
||||||
|
|
||||||
|
NAPI
|
||||||
|
----
|
||||||
|
|
||||||
|
NAPI (Rx polling mode) is supported in the ixgbe driver. NAPI is enabled
|
||||||
|
by default in the driver.
|
||||||
|
|
||||||
|
See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
|
||||||
|
|
||||||
|
|
||||||
|
Support
|
||||||
|
=======
|
||||||
|
|
||||||
|
For general information, go to the Intel support website at:
|
||||||
|
|
||||||
|
http://support.intel.com
|
||||||
|
|
||||||
|
or the Intel Wired Networking project hosted by Sourceforge at:
|
||||||
|
|
||||||
|
http://e1000.sourceforge.net
|
||||||
|
|
||||||
|
If an issue is identified with the released source code on the supported
|
||||||
|
kernel with a supported adapter, email the specific information related
|
||||||
|
to the issue to e1000-devel@lists.sf.net
|
|
@ -0,0 +1,356 @@
|
||||||
|
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
This readme tries to provide some background on the hows and whys of RDS,
|
||||||
|
and will hopefully help you find your way around the code.
|
||||||
|
|
||||||
|
In addition, please see this email about RDS origins:
|
||||||
|
http://oss.oracle.com/pipermail/rds-devel/2007-November/000228.html
|
||||||
|
|
||||||
|
RDS Architecture
|
||||||
|
================
|
||||||
|
|
||||||
|
RDS provides reliable, ordered datagram delivery by using a single
|
||||||
|
reliable connection between any two nodes in the cluster. This allows
|
||||||
|
applications to use a single socket to talk to any other process in the
|
||||||
|
cluster - so in a cluster with N processes you need N sockets, in contrast
|
||||||
|
to N*N if you use a connection-oriented socket transport like TCP.
|
||||||
|
|
||||||
|
RDS is not Infiniband-specific; it was designed to support different
|
||||||
|
transports. The current implementation used to support RDS over TCP as well
|
||||||
|
as IB. Work is in progress to support RDS over iWARP, and using DCE to
|
||||||
|
guarantee no dropped packets on Ethernet, it may be possible to use RDS over
|
||||||
|
UDP in the future.
|
||||||
|
|
||||||
|
The high-level semantics of RDS from the application's point of view are
|
||||||
|
|
||||||
|
* Addressing
|
||||||
|
RDS uses IPv4 addresses and 16bit port numbers to identify
|
||||||
|
the end point of a connection. All socket operations that involve
|
||||||
|
passing addresses between kernel and user space generally
|
||||||
|
use a struct sockaddr_in.
|
||||||
|
|
||||||
|
The fact that IPv4 addresses are used does not mean the underlying
|
||||||
|
transport has to be IP-based. In fact, RDS over IB uses a
|
||||||
|
reliable IB connection; the IP address is used exclusively to
|
||||||
|
locate the remote node's GID (by ARPing for the given IP).
|
||||||
|
|
||||||
|
The port space is entirely independent of UDP, TCP or any other
|
||||||
|
protocol.
|
||||||
|
|
||||||
|
* Socket interface
|
||||||
|
RDS sockets work *mostly* as you would expect from a BSD
|
||||||
|
socket. The next section will cover the details. At any rate,
|
||||||
|
all I/O is performed through the standard BSD socket API.
|
||||||
|
Some additions like zerocopy support are implemented through
|
||||||
|
control messages, while other extensions use the getsockopt/
|
||||||
|
setsockopt calls.
|
||||||
|
|
||||||
|
Sockets must be bound before you can send or receive data.
|
||||||
|
This is needed because binding also selects a transport and
|
||||||
|
attaches it to the socket. Once bound, the transport assignment
|
||||||
|
does not change. RDS will tolerate IPs moving around (eg in
|
||||||
|
a active-active HA scenario), but only as long as the address
|
||||||
|
doesn't move to a different transport.
|
||||||
|
|
||||||
|
* sysctls
|
||||||
|
RDS supports a number of sysctls in /proc/sys/net/rds
|
||||||
|
|
||||||
|
|
||||||
|
Socket Interface
|
||||||
|
================
|
||||||
|
|
||||||
|
AF_RDS, PF_RDS, SOL_RDS
|
||||||
|
These constants haven't been assigned yet, because RDS isn't in
|
||||||
|
mainline yet. Currently, the kernel module assigns some constant
|
||||||
|
and publishes it to user space through two sysctl files
|
||||||
|
/proc/sys/net/rds/pf_rds
|
||||||
|
/proc/sys/net/rds/sol_rds
|
||||||
|
|
||||||
|
fd = socket(PF_RDS, SOCK_SEQPACKET, 0);
|
||||||
|
This creates a new, unbound RDS socket.
|
||||||
|
|
||||||
|
setsockopt(SOL_SOCKET): send and receive buffer size
|
||||||
|
RDS honors the send and receive buffer size socket options.
|
||||||
|
You are not allowed to queue more than SO_SNDSIZE bytes to
|
||||||
|
a socket. A message is queued when sendmsg is called, and
|
||||||
|
it leaves the queue when the remote system acknowledges
|
||||||
|
its arrival.
|
||||||
|
|
||||||
|
The SO_RCVSIZE option controls the maximum receive queue length.
|
||||||
|
This is a soft limit rather than a hard limit - RDS will
|
||||||
|
continue to accept and queue incoming messages, even if that
|
||||||
|
takes the queue length over the limit. However, it will also
|
||||||
|
mark the port as "congested" and send a congestion update to
|
||||||
|
the source node. The source node is supposed to throttle any
|
||||||
|
processes sending to this congested port.
|
||||||
|
|
||||||
|
bind(fd, &sockaddr_in, ...)
|
||||||
|
This binds the socket to a local IP address and port, and a
|
||||||
|
transport.
|
||||||
|
|
||||||
|
sendmsg(fd, ...)
|
||||||
|
Sends a message to the indicated recipient. The kernel will
|
||||||
|
transparently establish the underlying reliable connection
|
||||||
|
if it isn't up yet.
|
||||||
|
|
||||||
|
An attempt to send a message that exceeds SO_SNDSIZE will
|
||||||
|
return with -EMSGSIZE
|
||||||
|
|
||||||
|
An attempt to send a message that would take the total number
|
||||||
|
of queued bytes over the SO_SNDSIZE threshold will return
|
||||||
|
EAGAIN.
|
||||||
|
|
||||||
|
An attempt to send a message to a destination that is marked
|
||||||
|
as "congested" will return ENOBUFS.
|
||||||
|
|
||||||
|
recvmsg(fd, ...)
|
||||||
|
Receives a message that was queued to this socket. The sockets
|
||||||
|
recv queue accounting is adjusted, and if the queue length
|
||||||
|
drops below SO_SNDSIZE, the port is marked uncongested, and
|
||||||
|
a congestion update is sent to all peers.
|
||||||
|
|
||||||
|
Applications can ask the RDS kernel module to receive
|
||||||
|
notifications via control messages (for instance, there is a
|
||||||
|
notification when a congestion update arrived, or when a RDMA
|
||||||
|
operation completes). These notifications are received through
|
||||||
|
the msg.msg_control buffer of struct msghdr. The format of the
|
||||||
|
messages is described in manpages.
|
||||||
|
|
||||||
|
poll(fd)
|
||||||
|
RDS supports the poll interface to allow the application
|
||||||
|
to implement async I/O.
|
||||||
|
|
||||||
|
POLLIN handling is pretty straightforward. When there's an
|
||||||
|
incoming message queued to the socket, or a pending notification,
|
||||||
|
we signal POLLIN.
|
||||||
|
|
||||||
|
POLLOUT is a little harder. Since you can essentially send
|
||||||
|
to any destination, RDS will always signal POLLOUT as long as
|
||||||
|
there's room on the send queue (ie the number of bytes queued
|
||||||
|
is less than the sendbuf size).
|
||||||
|
|
||||||
|
However, the kernel will refuse to accept messages to
|
||||||
|
a destination marked congested - in this case you will loop
|
||||||
|
forever if you rely on poll to tell you what to do.
|
||||||
|
This isn't a trivial problem, but applications can deal with
|
||||||
|
this - by using congestion notifications, and by checking for
|
||||||
|
ENOBUFS errors returned by sendmsg.
|
||||||
|
|
||||||
|
setsockopt(SOL_RDS, RDS_CANCEL_SENT_TO, &sockaddr_in)
|
||||||
|
This allows the application to discard all messages queued to a
|
||||||
|
specific destination on this particular socket.
|
||||||
|
|
||||||
|
This allows the application to cancel outstanding messages if
|
||||||
|
it detects a timeout. For instance, if it tried to send a message,
|
||||||
|
and the remote host is unreachable, RDS will keep trying forever.
|
||||||
|
The application may decide it's not worth it, and cancel the
|
||||||
|
operation. In this case, it would use RDS_CANCEL_SENT_TO to
|
||||||
|
nuke any pending messages.
|
||||||
|
|
||||||
|
|
||||||
|
RDMA for RDS
|
||||||
|
============
|
||||||
|
|
||||||
|
see rds-rdma(7) manpage (available in rds-tools)
|
||||||
|
|
||||||
|
|
||||||
|
Congestion Notifications
|
||||||
|
========================
|
||||||
|
|
||||||
|
see rds(7) manpage
|
||||||
|
|
||||||
|
|
||||||
|
RDS Protocol
|
||||||
|
============
|
||||||
|
|
||||||
|
Message header
|
||||||
|
|
||||||
|
The message header is a 'struct rds_header' (see rds.h):
|
||||||
|
Fields:
|
||||||
|
h_sequence:
|
||||||
|
per-packet sequence number
|
||||||
|
h_ack:
|
||||||
|
piggybacked acknowledgment of last packet received
|
||||||
|
h_len:
|
||||||
|
length of data, not including header
|
||||||
|
h_sport:
|
||||||
|
source port
|
||||||
|
h_dport:
|
||||||
|
destination port
|
||||||
|
h_flags:
|
||||||
|
CONG_BITMAP - this is a congestion update bitmap
|
||||||
|
ACK_REQUIRED - receiver must ack this packet
|
||||||
|
RETRANSMITTED - packet has previously been sent
|
||||||
|
h_credit:
|
||||||
|
indicate to other end of connection that
|
||||||
|
it has more credits available (i.e. there is
|
||||||
|
more send room)
|
||||||
|
h_padding[4]:
|
||||||
|
unused, for future use
|
||||||
|
h_csum:
|
||||||
|
header checksum
|
||||||
|
h_exthdr:
|
||||||
|
optional data can be passed here. This is currently used for
|
||||||
|
passing RDMA-related information.
|
||||||
|
|
||||||
|
ACK and retransmit handling
|
||||||
|
|
||||||
|
One might think that with reliable IB connections you wouldn't need
|
||||||
|
to ack messages that have been received. The problem is that IB
|
||||||
|
hardware generates an ack message before it has DMAed the message
|
||||||
|
into memory. This creates a potential message loss if the HCA is
|
||||||
|
disabled for any reason between when it sends the ack and before
|
||||||
|
the message is DMAed and processed. This is only a potential issue
|
||||||
|
if another HCA is available for fail-over.
|
||||||
|
|
||||||
|
Sending an ack immediately would allow the sender to free the sent
|
||||||
|
message from their send queue quickly, but could cause excessive
|
||||||
|
traffic to be used for acks. RDS piggybacks acks on sent data
|
||||||
|
packets. Ack-only packets are reduced by only allowing one to be
|
||||||
|
in flight at a time, and by the sender only asking for acks when
|
||||||
|
its send buffers start to fill up. All retransmissions are also
|
||||||
|
acked.
|
||||||
|
|
||||||
|
Flow Control
|
||||||
|
|
||||||
|
RDS's IB transport uses a credit-based mechanism to verify that
|
||||||
|
there is space in the peer's receive buffers for more data. This
|
||||||
|
eliminates the need for hardware retries on the connection.
|
||||||
|
|
||||||
|
Congestion
|
||||||
|
|
||||||
|
Messages waiting in the receive queue on the receiving socket
|
||||||
|
are accounted against the sockets SO_RCVBUF option value. Only
|
||||||
|
the payload bytes in the message are accounted for. If the
|
||||||
|
number of bytes queued equals or exceeds rcvbuf then the socket
|
||||||
|
is congested. All sends attempted to this socket's address
|
||||||
|
should return block or return -EWOULDBLOCK.
|
||||||
|
|
||||||
|
Applications are expected to be reasonably tuned such that this
|
||||||
|
situation very rarely occurs. An application encountering this
|
||||||
|
"back-pressure" is considered a bug.
|
||||||
|
|
||||||
|
This is implemented by having each node maintain bitmaps which
|
||||||
|
indicate which ports on bound addresses are congested. As the
|
||||||
|
bitmap changes it is sent through all the connections which
|
||||||
|
terminate in the local address of the bitmap which changed.
|
||||||
|
|
||||||
|
The bitmaps are allocated as connections are brought up. This
|
||||||
|
avoids allocation in the interrupt handling path which queues
|
||||||
|
sages on sockets. The dense bitmaps let transports send the
|
||||||
|
entire bitmap on any bitmap change reasonably efficiently. This
|
||||||
|
is much easier to implement than some finer-grained
|
||||||
|
communication of per-port congestion. The sender does a very
|
||||||
|
inexpensive bit test to test if the port it's about to send to
|
||||||
|
is congested or not.
|
||||||
|
|
||||||
|
|
||||||
|
RDS Transport Layer
|
||||||
|
==================
|
||||||
|
|
||||||
|
As mentioned above, RDS is not IB-specific. Its code is divided
|
||||||
|
into a general RDS layer and a transport layer.
|
||||||
|
|
||||||
|
The general layer handles the socket API, congestion handling,
|
||||||
|
loopback, stats, usermem pinning, and the connection state machine.
|
||||||
|
|
||||||
|
The transport layer handles the details of the transport. The IB
|
||||||
|
transport, for example, handles all the queue pairs, work requests,
|
||||||
|
CM event handlers, and other Infiniband details.
|
||||||
|
|
||||||
|
|
||||||
|
RDS Kernel Structures
|
||||||
|
=====================
|
||||||
|
|
||||||
|
struct rds_message
|
||||||
|
aka possibly "rds_outgoing", the generic RDS layer copies data to
|
||||||
|
be sent and sets header fields as needed, based on the socket API.
|
||||||
|
This is then queued for the individual connection and sent by the
|
||||||
|
connection's transport.
|
||||||
|
struct rds_incoming
|
||||||
|
a generic struct referring to incoming data that can be handed from
|
||||||
|
the transport to the general code and queued by the general code
|
||||||
|
while the socket is awoken. It is then passed back to the transport
|
||||||
|
code to handle the actual copy-to-user.
|
||||||
|
struct rds_socket
|
||||||
|
per-socket information
|
||||||
|
struct rds_connection
|
||||||
|
per-connection information
|
||||||
|
struct rds_transport
|
||||||
|
pointers to transport-specific functions
|
||||||
|
struct rds_statistics
|
||||||
|
non-transport-specific statistics
|
||||||
|
struct rds_cong_map
|
||||||
|
wraps the raw congestion bitmap, contains rbnode, waitq, etc.
|
||||||
|
|
||||||
|
Connection management
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Connections may be in UP, DOWN, CONNECTING, DISCONNECTING, and
|
||||||
|
ERROR states.
|
||||||
|
|
||||||
|
The first time an attempt is made by an RDS socket to send data to
|
||||||
|
a node, a connection is allocated and connected. That connection is
|
||||||
|
then maintained forever -- if there are transport errors, the
|
||||||
|
connection will be dropped and re-established.
|
||||||
|
|
||||||
|
Dropping a connection while packets are queued will cause queued or
|
||||||
|
partially-sent datagrams to be retransmitted when the connection is
|
||||||
|
re-established.
|
||||||
|
|
||||||
|
|
||||||
|
The send path
|
||||||
|
=============
|
||||||
|
|
||||||
|
rds_sendmsg()
|
||||||
|
struct rds_message built from incoming data
|
||||||
|
CMSGs parsed (e.g. RDMA ops)
|
||||||
|
transport connection alloced and connected if not already
|
||||||
|
rds_message placed on send queue
|
||||||
|
send worker awoken
|
||||||
|
rds_send_worker()
|
||||||
|
calls rds_send_xmit() until queue is empty
|
||||||
|
rds_send_xmit()
|
||||||
|
transmits congestion map if one is pending
|
||||||
|
may set ACK_REQUIRED
|
||||||
|
calls transport to send either non-RDMA or RDMA message
|
||||||
|
(RDMA ops never retransmitted)
|
||||||
|
rds_ib_xmit()
|
||||||
|
allocs work requests from send ring
|
||||||
|
adds any new send credits available to peer (h_credits)
|
||||||
|
maps the rds_message's sg list
|
||||||
|
piggybacks ack
|
||||||
|
populates work requests
|
||||||
|
post send to connection's queue pair
|
||||||
|
|
||||||
|
The recv path
|
||||||
|
=============
|
||||||
|
|
||||||
|
rds_ib_recv_cq_comp_handler()
|
||||||
|
looks at write completions
|
||||||
|
unmaps recv buffer from device
|
||||||
|
no errors, call rds_ib_process_recv()
|
||||||
|
refill recv ring
|
||||||
|
rds_ib_process_recv()
|
||||||
|
validate header checksum
|
||||||
|
copy header to rds_ib_incoming struct if start of a new datagram
|
||||||
|
add to ibinc's fraglist
|
||||||
|
if competed datagram:
|
||||||
|
update cong map if datagram was cong update
|
||||||
|
call rds_recv_incoming() otherwise
|
||||||
|
note if ack is required
|
||||||
|
rds_recv_incoming()
|
||||||
|
drop duplicate packets
|
||||||
|
respond to pings
|
||||||
|
find the sock associated with this datagram
|
||||||
|
add to sock queue
|
||||||
|
wake up sock
|
||||||
|
do some congestion calculations
|
||||||
|
rds_recvmsg
|
||||||
|
copy data into user iovec
|
||||||
|
handle CMSGs
|
||||||
|
return to application
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
The existing interfaces for getting network packages time stamped are:
|
||||||
|
|
||||||
|
* SO_TIMESTAMP
|
||||||
|
Generate time stamp for each incoming packet using the (not necessarily
|
||||||
|
monotonous!) system time. Result is returned via recv_msg() in a
|
||||||
|
control message as timeval (usec resolution).
|
||||||
|
|
||||||
|
* SO_TIMESTAMPNS
|
||||||
|
Same time stamping mechanism as SO_TIMESTAMP, but returns result as
|
||||||
|
timespec (nsec resolution).
|
||||||
|
|
||||||
|
* IP_MULTICAST_LOOP + SO_TIMESTAMP[NS]
|
||||||
|
Only for multicasts: approximate send time stamp by receiving the looped
|
||||||
|
packet and using its receive time stamp.
|
||||||
|
|
||||||
|
The following interface complements the existing ones: receive time
|
||||||
|
stamps can be generated and returned for arbitrary packets and much
|
||||||
|
closer to the point where the packet is really sent. Time stamps can
|
||||||
|
be generated in software (as before) or in hardware (if the hardware
|
||||||
|
has such a feature).
|
||||||
|
|
||||||
|
SO_TIMESTAMPING:
|
||||||
|
|
||||||
|
Instructs the socket layer which kind of information is wanted. The
|
||||||
|
parameter is an integer with some of the following bits set. Setting
|
||||||
|
other bits is an error and doesn't change the current state.
|
||||||
|
|
||||||
|
SOF_TIMESTAMPING_TX_HARDWARE: try to obtain send time stamp in hardware
|
||||||
|
SOF_TIMESTAMPING_TX_SOFTWARE: if SOF_TIMESTAMPING_TX_HARDWARE is off or
|
||||||
|
fails, then do it in software
|
||||||
|
SOF_TIMESTAMPING_RX_HARDWARE: return the original, unmodified time stamp
|
||||||
|
as generated by the hardware
|
||||||
|
SOF_TIMESTAMPING_RX_SOFTWARE: if SOF_TIMESTAMPING_RX_HARDWARE is off or
|
||||||
|
fails, then do it in software
|
||||||
|
SOF_TIMESTAMPING_RAW_HARDWARE: return original raw hardware time stamp
|
||||||
|
SOF_TIMESTAMPING_SYS_HARDWARE: return hardware time stamp transformed to
|
||||||
|
the system time base
|
||||||
|
SOF_TIMESTAMPING_SOFTWARE: return system time stamp generated in
|
||||||
|
software
|
||||||
|
|
||||||
|
SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
|
||||||
|
SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
|
||||||
|
following control message:
|
||||||
|
struct scm_timestamping {
|
||||||
|
struct timespec systime;
|
||||||
|
struct timespec hwtimetrans;
|
||||||
|
struct timespec hwtimeraw;
|
||||||
|
};
|
||||||
|
|
||||||
|
recvmsg() can be used to get this control message for regular incoming
|
||||||
|
packets. For send time stamps the outgoing packet is looped back to
|
||||||
|
the socket's error queue with the send time stamp(s) attached. It can
|
||||||
|
be received with recvmsg(flags=MSG_ERRQUEUE). The call returns the
|
||||||
|
original outgoing packet data including all headers preprended down to
|
||||||
|
and including the link layer, the scm_timestamping control message and
|
||||||
|
a sock_extended_err control message with ee_errno==ENOMSG and
|
||||||
|
ee_origin==SO_EE_ORIGIN_TIMESTAMPING. A socket with such a pending
|
||||||
|
bounced packet is ready for reading as far as select() is concerned.
|
||||||
|
If the outgoing packet has to be fragmented, then only the first
|
||||||
|
fragment is time stamped and returned to the sending socket.
|
||||||
|
|
||||||
|
All three values correspond to the same event in time, but were
|
||||||
|
generated in different ways. Each of these values may be empty (= all
|
||||||
|
zero), in which case no such value was available. If the application
|
||||||
|
is not interested in some of these values, they can be left blank to
|
||||||
|
avoid the potential overhead of calculating them.
|
||||||
|
|
||||||
|
systime is the value of the system time at that moment. This
|
||||||
|
corresponds to the value also returned via SO_TIMESTAMP[NS]. If the
|
||||||
|
time stamp was generated by hardware, then this field is
|
||||||
|
empty. Otherwise it is filled in if SOF_TIMESTAMPING_SOFTWARE is
|
||||||
|
set.
|
||||||
|
|
||||||
|
hwtimeraw is the original hardware time stamp. Filled in if
|
||||||
|
SOF_TIMESTAMPING_RAW_HARDWARE is set. No assumptions about its
|
||||||
|
relation to system time should be made.
|
||||||
|
|
||||||
|
hwtimetrans is the hardware time stamp transformed so that it
|
||||||
|
corresponds as good as possible to system time. This correlation is
|
||||||
|
not perfect; as a consequence, sorting packets received via different
|
||||||
|
NICs by their hwtimetrans may differ from the order in which they were
|
||||||
|
received. hwtimetrans may be non-monotonic even for the same NIC.
|
||||||
|
Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support
|
||||||
|
by the network device and will be empty without that support.
|
||||||
|
|
||||||
|
|
||||||
|
SIOCSHWTSTAMP:
|
||||||
|
|
||||||
|
Hardware time stamping must also be initialized for each device driver
|
||||||
|
that is expected to do hardware time stamping. The parameter is:
|
||||||
|
|
||||||
|
struct hwtstamp_config {
|
||||||
|
int flags; /* no flags defined right now, must be zero */
|
||||||
|
int tx_type; /* HWTSTAMP_TX_* */
|
||||||
|
int rx_filter; /* HWTSTAMP_FILTER_* */
|
||||||
|
};
|
||||||
|
|
||||||
|
Desired behavior is passed into the kernel and to a specific device by
|
||||||
|
calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose
|
||||||
|
ifr_data points to a struct hwtstamp_config. The tx_type and
|
||||||
|
rx_filter are hints to the driver what it is expected to do. If
|
||||||
|
the requested fine-grained filtering for incoming packets is not
|
||||||
|
supported, the driver may time stamp more than just the requested types
|
||||||
|
of packets.
|
||||||
|
|
||||||
|
A driver which supports hardware time stamping shall update the struct
|
||||||
|
with the actual, possibly more permissive configuration. If the
|
||||||
|
requested packets cannot be time stamped, then nothing should be
|
||||||
|
changed and ERANGE shall be returned (in contrast to EINVAL, which
|
||||||
|
indicates that SIOCSHWTSTAMP is not supported at all).
|
||||||
|
|
||||||
|
Only a processes with admin rights may change the configuration. User
|
||||||
|
space is responsible to ensure that multiple processes don't interfere
|
||||||
|
with each other and that the settings are reset.
|
||||||
|
|
||||||
|
/* possible values for hwtstamp_config->tx_type */
|
||||||
|
enum {
|
||||||
|
/*
|
||||||
|
* no outgoing packet will need hardware time stamping;
|
||||||
|
* should a packet arrive which asks for it, no hardware
|
||||||
|
* time stamping will be done
|
||||||
|
*/
|
||||||
|
HWTSTAMP_TX_OFF,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enables hardware time stamping for outgoing packets;
|
||||||
|
* the sender of the packet decides which are to be
|
||||||
|
* time stamped by setting SOF_TIMESTAMPING_TX_SOFTWARE
|
||||||
|
* before sending the packet
|
||||||
|
*/
|
||||||
|
HWTSTAMP_TX_ON,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* possible values for hwtstamp_config->rx_filter */
|
||||||
|
enum {
|
||||||
|
/* time stamp no incoming packet at all */
|
||||||
|
HWTSTAMP_FILTER_NONE,
|
||||||
|
|
||||||
|
/* time stamp any incoming packet */
|
||||||
|
HWTSTAMP_FILTER_ALL,
|
||||||
|
|
||||||
|
/* return value: time stamp all packets requested plus some others */
|
||||||
|
HWTSTAMP_FILTER_SOME,
|
||||||
|
|
||||||
|
/* PTP v1, UDP, any kind of event packet */
|
||||||
|
HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
|
||||||
|
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DEVICE IMPLEMENTATION
|
||||||
|
|
||||||
|
A driver which supports hardware time stamping must support the
|
||||||
|
SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
|
||||||
|
in the skb with skb_hwtstamp_set().
|
||||||
|
|
||||||
|
Time stamps for outgoing packets are to be generated as follows:
|
||||||
|
- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
|
||||||
|
returns non-zero. If yes, then the driver is expected
|
||||||
|
to do hardware time stamping.
|
||||||
|
- If this is possible for the skb and requested, then declare
|
||||||
|
that the driver is doing the time stamping by calling
|
||||||
|
skb_hwtstamp_tx_in_progress(). A driver not supporting
|
||||||
|
hardware time stamping doesn't do that. A driver must never
|
||||||
|
touch sk_buff::tstamp! It is used to store how time stamping
|
||||||
|
for an outgoing packets is to be done.
|
||||||
|
- As soon as the driver has sent the packet and/or obtained a
|
||||||
|
hardware time stamp for it, it passes the time stamp back by
|
||||||
|
calling skb_hwtstamp_tx() with the original skb, the raw
|
||||||
|
hardware time stamp and a handle to the device (necessary
|
||||||
|
to convert the hardware time stamp to system time). If obtaining
|
||||||
|
the hardware time stamp somehow fails, then the driver should
|
||||||
|
not fall back to software time stamping. The rationale is that
|
||||||
|
this would occur at a later time in the processing pipeline
|
||||||
|
than other software time stamping and therefore could lead
|
||||||
|
to unexpected deltas between time stamps.
|
||||||
|
- If the driver did not call skb_hwtstamp_tx_in_progress(), then
|
||||||
|
dev_hard_start_xmit() checks whether software time stamping
|
||||||
|
is wanted as fallback and potentially generates the time stamp.
|
|
@ -0,0 +1 @@
|
||||||
|
timestamping
|
|
@ -0,0 +1,6 @@
|
||||||
|
CPPFLAGS = -I../../../include
|
||||||
|
|
||||||
|
timestamping: timestamping.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f timestamping
|
|
@ -0,0 +1,533 @@
|
||||||
|
/*
|
||||||
|
* This program demonstrates how the various time stamping features in
|
||||||
|
* the Linux kernel work. It emulates the behavior of a PTP
|
||||||
|
* implementation in stand-alone master mode by sending PTPv1 Sync
|
||||||
|
* multicasts once every second. It looks for similar packets, but
|
||||||
|
* beyond that doesn't actually implement PTP.
|
||||||
|
*
|
||||||
|
* Outgoing packets are time stamped with SO_TIMESTAMPING with or
|
||||||
|
* without hardware support.
|
||||||
|
*
|
||||||
|
* Incoming packets are time stamped with SO_TIMESTAMPING with or
|
||||||
|
* without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and
|
||||||
|
* SO_TIMESTAMP[NS].
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Intel Corporation.
|
||||||
|
* Author: Patrick Ohly <patrick.ohly@intel.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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.,
|
||||||
|
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include "asm/types.h"
|
||||||
|
#include "linux/net_tstamp.h"
|
||||||
|
#include "linux/errqueue.h"
|
||||||
|
|
||||||
|
#ifndef SO_TIMESTAMPING
|
||||||
|
# define SO_TIMESTAMPING 37
|
||||||
|
# define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SO_TIMESTAMPNS
|
||||||
|
# define SO_TIMESTAMPNS 35
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIOCGSTAMPNS
|
||||||
|
# define SIOCGSTAMPNS 0x8907
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIOCSHWTSTAMP
|
||||||
|
# define SIOCSHWTSTAMP 0x89b0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void usage(const char *error)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
printf("invalid option: %s\n", error);
|
||||||
|
printf("timestamping interface option*\n\n"
|
||||||
|
"Options:\n"
|
||||||
|
" IP_MULTICAST_LOOP - looping outgoing multicasts\n"
|
||||||
|
" SO_TIMESTAMP - normal software time stamping, ms resolution\n"
|
||||||
|
" SO_TIMESTAMPNS - more accurate software time stamping\n"
|
||||||
|
" SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n"
|
||||||
|
" SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n"
|
||||||
|
" SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n"
|
||||||
|
" SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
|
||||||
|
" SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
|
||||||
|
" SOF_TIMESTAMPING_SYS_HARDWARE - request reporting of transformed HW time stamps\n"
|
||||||
|
" SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
|
||||||
|
" SIOCGSTAMP - check last socket time stamp\n"
|
||||||
|
" SIOCGSTAMPNS - more accurate socket time stamp\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bail(const char *error)
|
||||||
|
{
|
||||||
|
printf("%s: %s\n", error, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char sync[] = {
|
||||||
|
0x00, 0x01, 0x00, 0x01,
|
||||||
|
0x5f, 0x44, 0x46, 0x4c,
|
||||||
|
0x54, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x01,
|
||||||
|
|
||||||
|
/* fake uuid */
|
||||||
|
0x00, 0x01,
|
||||||
|
0x02, 0x03, 0x04, 0x05,
|
||||||
|
|
||||||
|
0x00, 0x01, 0x00, 0x37,
|
||||||
|
0x00, 0x00, 0x00, 0x08,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x49, 0x05, 0xcd, 0x01,
|
||||||
|
0x29, 0xb1, 0x8d, 0xb0,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x01,
|
||||||
|
|
||||||
|
/* fake uuid */
|
||||||
|
0x00, 0x01,
|
||||||
|
0x02, 0x03, 0x04, 0x05,
|
||||||
|
|
||||||
|
0x00, 0x00, 0x00, 0x37,
|
||||||
|
0x00, 0x00, 0x00, 0x04,
|
||||||
|
0x44, 0x46, 0x4c, 0x54,
|
||||||
|
0x00, 0x00, 0xf0, 0x60,
|
||||||
|
0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0xf0, 0x60,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x04,
|
||||||
|
0x44, 0x46, 0x4c, 0x54,
|
||||||
|
0x00, 0x01,
|
||||||
|
|
||||||
|
/* fake uuid */
|
||||||
|
0x00, 0x01,
|
||||||
|
0x02, 0x03, 0x04, 0x05,
|
||||||
|
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len)
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = sendto(sock, sync, sizeof(sync), 0,
|
||||||
|
addr, addr_len);
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
if (res < 0)
|
||||||
|
printf("%s: %s\n", "send", strerror(errno));
|
||||||
|
else
|
||||||
|
printf("%ld.%06ld: sent %d bytes\n",
|
||||||
|
(long)now.tv_sec, (long)now.tv_usec,
|
||||||
|
res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printpacket(struct msghdr *msg, int res,
|
||||||
|
char *data,
|
||||||
|
int sock, int recvmsg_flags,
|
||||||
|
int siocgstamp, int siocgstampns)
|
||||||
|
{
|
||||||
|
struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
struct timeval tv;
|
||||||
|
struct timespec ts;
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
|
||||||
|
printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n",
|
||||||
|
(long)now.tv_sec, (long)now.tv_usec,
|
||||||
|
(recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
|
||||||
|
res,
|
||||||
|
inet_ntoa(from_addr->sin_addr),
|
||||||
|
msg->msg_controllen);
|
||||||
|
for (cmsg = CMSG_FIRSTHDR(msg);
|
||||||
|
cmsg;
|
||||||
|
cmsg = CMSG_NXTHDR(msg, cmsg)) {
|
||||||
|
printf(" cmsg len %d: ", cmsg->cmsg_len);
|
||||||
|
switch (cmsg->cmsg_level) {
|
||||||
|
case SOL_SOCKET:
|
||||||
|
printf("SOL_SOCKET ");
|
||||||
|
switch (cmsg->cmsg_type) {
|
||||||
|
case SO_TIMESTAMP: {
|
||||||
|
struct timeval *stamp =
|
||||||
|
(struct timeval *)CMSG_DATA(cmsg);
|
||||||
|
printf("SO_TIMESTAMP %ld.%06ld",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_usec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SO_TIMESTAMPNS: {
|
||||||
|
struct timespec *stamp =
|
||||||
|
(struct timespec *)CMSG_DATA(cmsg);
|
||||||
|
printf("SO_TIMESTAMPNS %ld.%09ld",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_nsec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SO_TIMESTAMPING: {
|
||||||
|
struct timespec *stamp =
|
||||||
|
(struct timespec *)CMSG_DATA(cmsg);
|
||||||
|
printf("SO_TIMESTAMPING ");
|
||||||
|
printf("SW %ld.%09ld ",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_nsec);
|
||||||
|
stamp++;
|
||||||
|
printf("HW transformed %ld.%09ld ",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_nsec);
|
||||||
|
stamp++;
|
||||||
|
printf("HW raw %ld.%09ld",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_nsec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("type %d", cmsg->cmsg_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IPPROTO_IP:
|
||||||
|
printf("IPPROTO_IP ");
|
||||||
|
switch (cmsg->cmsg_type) {
|
||||||
|
case IP_RECVERR: {
|
||||||
|
struct sock_extended_err *err =
|
||||||
|
(struct sock_extended_err *)CMSG_DATA(cmsg);
|
||||||
|
printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s",
|
||||||
|
strerror(err->ee_errno),
|
||||||
|
err->ee_origin,
|
||||||
|
#ifdef SO_EE_ORIGIN_TIMESTAMPING
|
||||||
|
err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ?
|
||||||
|
"bounced packet" : "unexpected origin"
|
||||||
|
#else
|
||||||
|
"probably SO_EE_ORIGIN_TIMESTAMPING"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
if (res < sizeof(sync))
|
||||||
|
printf(" => truncated data?!");
|
||||||
|
else if (!memcmp(sync, data + res - sizeof(sync),
|
||||||
|
sizeof(sync)))
|
||||||
|
printf(" => GOT OUR DATA BACK (HURRAY!)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IP_PKTINFO: {
|
||||||
|
struct in_pktinfo *pktinfo =
|
||||||
|
(struct in_pktinfo *)CMSG_DATA(cmsg);
|
||||||
|
printf("IP_PKTINFO interface index %u",
|
||||||
|
pktinfo->ipi_ifindex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("type %d", cmsg->cmsg_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("level %d type %d",
|
||||||
|
cmsg->cmsg_level,
|
||||||
|
cmsg->cmsg_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (siocgstamp) {
|
||||||
|
if (ioctl(sock, SIOCGSTAMP, &tv))
|
||||||
|
printf(" %s: %s\n", "SIOCGSTAMP", strerror(errno));
|
||||||
|
else
|
||||||
|
printf("SIOCGSTAMP %ld.%06ld\n",
|
||||||
|
(long)tv.tv_sec,
|
||||||
|
(long)tv.tv_usec);
|
||||||
|
}
|
||||||
|
if (siocgstampns) {
|
||||||
|
if (ioctl(sock, SIOCGSTAMPNS, &ts))
|
||||||
|
printf(" %s: %s\n", "SIOCGSTAMPNS", strerror(errno));
|
||||||
|
else
|
||||||
|
printf("SIOCGSTAMPNS %ld.%09ld\n",
|
||||||
|
(long)ts.tv_sec,
|
||||||
|
(long)ts.tv_nsec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recvpacket(int sock, int recvmsg_flags,
|
||||||
|
int siocgstamp, int siocgstampns)
|
||||||
|
{
|
||||||
|
char data[256];
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec entry;
|
||||||
|
struct sockaddr_in from_addr;
|
||||||
|
struct {
|
||||||
|
struct cmsghdr cm;
|
||||||
|
char control[512];
|
||||||
|
} control;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
memset(&msg, 0, sizeof(msg));
|
||||||
|
msg.msg_iov = &entry;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
entry.iov_base = data;
|
||||||
|
entry.iov_len = sizeof(data);
|
||||||
|
msg.msg_name = (caddr_t)&from_addr;
|
||||||
|
msg.msg_namelen = sizeof(from_addr);
|
||||||
|
msg.msg_control = &control;
|
||||||
|
msg.msg_controllen = sizeof(control);
|
||||||
|
|
||||||
|
res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT);
|
||||||
|
if (res < 0) {
|
||||||
|
printf("%s %s: %s\n",
|
||||||
|
"recvmsg",
|
||||||
|
(recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
printpacket(&msg, res, data,
|
||||||
|
sock, recvmsg_flags,
|
||||||
|
siocgstamp, siocgstampns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int so_timestamping_flags = 0;
|
||||||
|
int so_timestamp = 0;
|
||||||
|
int so_timestampns = 0;
|
||||||
|
int siocgstamp = 0;
|
||||||
|
int siocgstampns = 0;
|
||||||
|
int ip_multicast_loop = 0;
|
||||||
|
char *interface;
|
||||||
|
int i;
|
||||||
|
int enabled = 1;
|
||||||
|
int sock;
|
||||||
|
struct ifreq device;
|
||||||
|
struct ifreq hwtstamp;
|
||||||
|
struct hwtstamp_config hwconfig, hwconfig_requested;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
struct ip_mreq imr;
|
||||||
|
struct in_addr iaddr;
|
||||||
|
int val;
|
||||||
|
socklen_t len;
|
||||||
|
struct timeval next;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
usage(0);
|
||||||
|
interface = argv[1];
|
||||||
|
|
||||||
|
for (i = 2; i < argc; i++) {
|
||||||
|
if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
|
||||||
|
so_timestamp = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
|
||||||
|
so_timestampns = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "SIOCGSTAMP"))
|
||||||
|
siocgstamp = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "SIOCGSTAMPNS"))
|
||||||
|
siocgstampns = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP"))
|
||||||
|
ip_multicast_loop = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SYS_HARDWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_SYS_HARDWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||||
|
else
|
||||||
|
usage(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (socket < 0)
|
||||||
|
bail("socket");
|
||||||
|
|
||||||
|
memset(&device, 0, sizeof(device));
|
||||||
|
strncpy(device.ifr_name, interface, sizeof(device.ifr_name));
|
||||||
|
if (ioctl(sock, SIOCGIFADDR, &device) < 0)
|
||||||
|
bail("getting interface IP address");
|
||||||
|
|
||||||
|
memset(&hwtstamp, 0, sizeof(hwtstamp));
|
||||||
|
strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
|
||||||
|
hwtstamp.ifr_data = (void *)&hwconfig;
|
||||||
|
memset(&hwconfig, 0, sizeof(&hwconfig));
|
||||||
|
hwconfig.tx_type =
|
||||||
|
(so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
|
||||||
|
HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||||
|
hwconfig.rx_filter =
|
||||||
|
(so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
|
||||||
|
HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
|
||||||
|
hwconfig_requested = hwconfig;
|
||||||
|
if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
|
||||||
|
if ((errno == EINVAL || errno == ENOTSUP) &&
|
||||||
|
hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
|
||||||
|
hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
|
||||||
|
printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n");
|
||||||
|
else
|
||||||
|
bail("SIOCSHWTSTAMP");
|
||||||
|
}
|
||||||
|
printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n",
|
||||||
|
hwconfig_requested.tx_type, hwconfig.tx_type,
|
||||||
|
hwconfig_requested.rx_filter, hwconfig.rx_filter);
|
||||||
|
|
||||||
|
/* bind to PTP port */
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
addr.sin_port = htons(319 /* PTP event port */);
|
||||||
|
if (bind(sock,
|
||||||
|
(struct sockaddr *)&addr,
|
||||||
|
sizeof(struct sockaddr_in)) < 0)
|
||||||
|
bail("bind");
|
||||||
|
|
||||||
|
/* set multicast group for outgoing packets */
|
||||||
|
inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */
|
||||||
|
addr.sin_addr = iaddr;
|
||||||
|
imr.imr_multiaddr.s_addr = iaddr.s_addr;
|
||||||
|
imr.imr_interface.s_addr =
|
||||||
|
((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr;
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
|
&imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0)
|
||||||
|
bail("set multicast");
|
||||||
|
|
||||||
|
/* join multicast group, loop our own packet */
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||||
|
&imr, sizeof(struct ip_mreq)) < 0)
|
||||||
|
bail("join multicast group");
|
||||||
|
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
|
||||||
|
&ip_multicast_loop, sizeof(enabled)) < 0) {
|
||||||
|
bail("loop multicast");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set socket options for time stamping */
|
||||||
|
if (so_timestamp &&
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP,
|
||||||
|
&enabled, sizeof(enabled)) < 0)
|
||||||
|
bail("setsockopt SO_TIMESTAMP");
|
||||||
|
|
||||||
|
if (so_timestampns &&
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS,
|
||||||
|
&enabled, sizeof(enabled)) < 0)
|
||||||
|
bail("setsockopt SO_TIMESTAMPNS");
|
||||||
|
|
||||||
|
if (so_timestamping_flags &&
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,
|
||||||
|
&so_timestamping_flags,
|
||||||
|
sizeof(so_timestamping_flags)) < 0)
|
||||||
|
bail("setsockopt SO_TIMESTAMPING");
|
||||||
|
|
||||||
|
/* request IP_PKTINFO for debugging purposes */
|
||||||
|
if (setsockopt(sock, SOL_IP, IP_PKTINFO,
|
||||||
|
&enabled, sizeof(enabled)) < 0)
|
||||||
|
printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno));
|
||||||
|
|
||||||
|
/* verify socket options */
|
||||||
|
len = sizeof(val);
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0)
|
||||||
|
printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno));
|
||||||
|
else
|
||||||
|
printf("SO_TIMESTAMP %d\n", val);
|
||||||
|
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0)
|
||||||
|
printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS",
|
||||||
|
strerror(errno));
|
||||||
|
else
|
||||||
|
printf("SO_TIMESTAMPNS %d\n", val);
|
||||||
|
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) {
|
||||||
|
printf("%s: %s\n", "getsockopt SO_TIMESTAMPING",
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
printf("SO_TIMESTAMPING %d\n", val);
|
||||||
|
if (val != so_timestamping_flags)
|
||||||
|
printf(" not the expected value %d\n",
|
||||||
|
so_timestamping_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send packets forever every five seconds */
|
||||||
|
gettimeofday(&next, 0);
|
||||||
|
next.tv_sec = (next.tv_sec + 1) / 5 * 5;
|
||||||
|
next.tv_usec = 0;
|
||||||
|
while (1) {
|
||||||
|
struct timeval now;
|
||||||
|
struct timeval delta;
|
||||||
|
long delta_us;
|
||||||
|
int res;
|
||||||
|
fd_set readfs, errorfs;
|
||||||
|
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 +
|
||||||
|
(long)(next.tv_usec - now.tv_usec);
|
||||||
|
if (delta_us > 0) {
|
||||||
|
/* continue waiting for timeout or data */
|
||||||
|
delta.tv_sec = delta_us / 1000000;
|
||||||
|
delta.tv_usec = delta_us % 1000000;
|
||||||
|
|
||||||
|
FD_ZERO(&readfs);
|
||||||
|
FD_ZERO(&errorfs);
|
||||||
|
FD_SET(sock, &readfs);
|
||||||
|
FD_SET(sock, &errorfs);
|
||||||
|
printf("%ld.%06ld: select %ldus\n",
|
||||||
|
(long)now.tv_sec, (long)now.tv_usec,
|
||||||
|
delta_us);
|
||||||
|
res = select(sock + 1, &readfs, 0, &errorfs, &delta);
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
printf("%ld.%06ld: select returned: %d, %s\n",
|
||||||
|
(long)now.tv_sec, (long)now.tv_usec,
|
||||||
|
res,
|
||||||
|
res < 0 ? strerror(errno) : "success");
|
||||||
|
if (res > 0) {
|
||||||
|
if (FD_ISSET(sock, &readfs))
|
||||||
|
printf("ready for reading\n");
|
||||||
|
if (FD_ISSET(sock, &errorfs))
|
||||||
|
printf("has error\n");
|
||||||
|
recvpacket(sock, 0,
|
||||||
|
siocgstamp,
|
||||||
|
siocgstampns);
|
||||||
|
recvpacket(sock, MSG_ERRQUEUE,
|
||||||
|
siocgstamp,
|
||||||
|
siocgstampns);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* write one packet */
|
||||||
|
sendpacket(sock,
|
||||||
|
(struct sockaddr *)&addr,
|
||||||
|
sizeof(addr));
|
||||||
|
next.tv_sec += 5;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -35,30 +35,30 @@ Example:
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
|
compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
|
||||||
reg = <82a8 4>;
|
reg = <0x82a8 4>;
|
||||||
ranges = <0 8100 1a4>;
|
ranges = <0 0x8100 0x1a4>;
|
||||||
interrupt-parent = <&ipic>;
|
interrupt-parent = <&ipic>;
|
||||||
interrupts = <47 8>;
|
interrupts = <71 8>;
|
||||||
cell-index = <0>;
|
cell-index = <0>;
|
||||||
dma-channel@0 {
|
dma-channel@0 {
|
||||||
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
||||||
cell-index = <0>;
|
cell-index = <0>;
|
||||||
reg = <0 80>;
|
reg = <0 0x80>;
|
||||||
};
|
};
|
||||||
dma-channel@80 {
|
dma-channel@80 {
|
||||||
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
||||||
cell-index = <1>;
|
cell-index = <1>;
|
||||||
reg = <80 80>;
|
reg = <0x80 0x80>;
|
||||||
};
|
};
|
||||||
dma-channel@100 {
|
dma-channel@100 {
|
||||||
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
||||||
cell-index = <2>;
|
cell-index = <2>;
|
||||||
reg = <100 80>;
|
reg = <0x100 0x80>;
|
||||||
};
|
};
|
||||||
dma-channel@180 {
|
dma-channel@180 {
|
||||||
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
||||||
cell-index = <3>;
|
cell-index = <3>;
|
||||||
reg = <180 80>;
|
reg = <0x180 0x80>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,36 +93,36 @@ Example:
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
|
compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
|
||||||
reg = <21300 4>;
|
reg = <0x21300 4>;
|
||||||
ranges = <0 21100 200>;
|
ranges = <0 0x21100 0x200>;
|
||||||
cell-index = <0>;
|
cell-index = <0>;
|
||||||
dma-channel@0 {
|
dma-channel@0 {
|
||||||
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
||||||
reg = <0 80>;
|
reg = <0 0x80>;
|
||||||
cell-index = <0>;
|
cell-index = <0>;
|
||||||
interrupt-parent = <&mpic>;
|
interrupt-parent = <&mpic>;
|
||||||
interrupts = <14 2>;
|
interrupts = <20 2>;
|
||||||
};
|
};
|
||||||
dma-channel@80 {
|
dma-channel@80 {
|
||||||
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
||||||
reg = <80 80>;
|
reg = <0x80 0x80>;
|
||||||
cell-index = <1>;
|
cell-index = <1>;
|
||||||
interrupt-parent = <&mpic>;
|
interrupt-parent = <&mpic>;
|
||||||
interrupts = <15 2>;
|
interrupts = <21 2>;
|
||||||
};
|
};
|
||||||
dma-channel@100 {
|
dma-channel@100 {
|
||||||
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
||||||
reg = <100 80>;
|
reg = <0x100 0x80>;
|
||||||
cell-index = <2>;
|
cell-index = <2>;
|
||||||
interrupt-parent = <&mpic>;
|
interrupt-parent = <&mpic>;
|
||||||
interrupts = <16 2>;
|
interrupts = <22 2>;
|
||||||
};
|
};
|
||||||
dma-channel@180 {
|
dma-channel@180 {
|
||||||
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
||||||
reg = <180 80>;
|
reg = <0x180 0x80>;
|
||||||
cell-index = <3>;
|
cell-index = <3>;
|
||||||
interrupt-parent = <&mpic>;
|
interrupt-parent = <&mpic>;
|
||||||
interrupts = <17 2>;
|
interrupts = <23 2>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
* Freescale Enhanced Secure Digital Host Controller (eSDHC)
|
||||||
|
|
||||||
|
The Enhanced Secure Digital Host Controller provides an interface
|
||||||
|
for MMC, SD, and SDIO types of memory cards.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : should be
|
||||||
|
"fsl,<chip>-esdhc", "fsl,mpc8379-esdhc" for MPC83xx processors.
|
||||||
|
"fsl,<chip>-esdhc", "fsl,mpc8536-esdhc" for MPC85xx processors.
|
||||||
|
- reg : should contain eSDHC registers location and length.
|
||||||
|
- interrupts : should contain eSDHC interrupt.
|
||||||
|
- interrupt-parent : interrupt source phandle.
|
||||||
|
- clock-frequency : specifies eSDHC base clock frequency.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
sdhci@2e000 {
|
||||||
|
compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
|
||||||
|
reg = <0x2e000 0x1000>;
|
||||||
|
interrupts = <42 0x8>;
|
||||||
|
interrupt-parent = <&ipic>;
|
||||||
|
/* Filled in by U-Boot */
|
||||||
|
clock-frequency = <0>;
|
||||||
|
};
|
|
@ -4,44 +4,56 @@ The SSI is a serial device that communicates with audio codecs. It can
|
||||||
be programmed in AC97, I2S, left-justified, or right-justified modes.
|
be programmed in AC97, I2S, left-justified, or right-justified modes.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : compatible list, containing "fsl,ssi"
|
- compatible: Compatible list, contains "fsl,ssi".
|
||||||
- cell-index : the SSI, <0> = SSI1, <1> = SSI2, and so on
|
- cell-index: The SSI, <0> = SSI1, <1> = SSI2, and so on.
|
||||||
- reg : offset and length of the register set for the device
|
- reg: Offset and length of the register set for the device.
|
||||||
- interrupts : <a b> where a is the interrupt number and b is a
|
- interrupts: <a b> where a is the interrupt number and b is a
|
||||||
field that represents an encoding of the sense and
|
field that represents an encoding of the sense and
|
||||||
level information for the interrupt. This should be
|
level information for the interrupt. This should be
|
||||||
encoded based on the information in section 2)
|
encoded based on the information in section 2)
|
||||||
depending on the type of interrupt controller you
|
depending on the type of interrupt controller you
|
||||||
have.
|
have.
|
||||||
- interrupt-parent : the phandle for the interrupt controller that
|
- interrupt-parent: The phandle for the interrupt controller that
|
||||||
services interrupts for this device.
|
services interrupts for this device.
|
||||||
- fsl,mode : the operating mode for the SSI interface
|
- fsl,mode: The operating mode for the SSI interface.
|
||||||
"i2s-slave" - I2S mode, SSI is clock slave
|
"i2s-slave" - I2S mode, SSI is clock slave
|
||||||
"i2s-master" - I2S mode, SSI is clock master
|
"i2s-master" - I2S mode, SSI is clock master
|
||||||
"lj-slave" - left-justified mode, SSI is clock slave
|
"lj-slave" - left-justified mode, SSI is clock slave
|
||||||
"lj-master" - l.j. mode, SSI is clock master
|
"lj-master" - l.j. mode, SSI is clock master
|
||||||
"rj-slave" - right-justified mode, SSI is clock slave
|
"rj-slave" - right-justified mode, SSI is clock slave
|
||||||
"rj-master" - r.j., SSI is clock master
|
"rj-master" - r.j., SSI is clock master
|
||||||
"ac97-slave" - AC97 mode, SSI is clock slave
|
"ac97-slave" - AC97 mode, SSI is clock slave
|
||||||
"ac97-master" - AC97 mode, SSI is clock master
|
"ac97-master" - AC97 mode, SSI is clock master
|
||||||
- fsl,playback-dma: phandle to a node for the DMA channel to use for
|
- fsl,playback-dma: Phandle to a node for the DMA channel to use for
|
||||||
playback of audio. This is typically dictated by SOC
|
playback of audio. This is typically dictated by SOC
|
||||||
design. See the notes below.
|
design. See the notes below.
|
||||||
- fsl,capture-dma: phandle to a node for the DMA channel to use for
|
- fsl,capture-dma: Phandle to a node for the DMA channel to use for
|
||||||
capture (recording) of audio. This is typically dictated
|
capture (recording) of audio. This is typically dictated
|
||||||
by SOC design. See the notes below.
|
by SOC design. See the notes below.
|
||||||
|
- fsl,fifo-depth: The number of elements in the transmit and receive FIFOs.
|
||||||
|
This number is the maximum allowed value for SFCSR[TFWM0].
|
||||||
|
- fsl,ssi-asynchronous:
|
||||||
|
If specified, the SSI is to be programmed in asynchronous
|
||||||
|
mode. In this mode, pins SRCK, STCK, SRFS, and STFS must
|
||||||
|
all be connected to valid signals. In synchronous mode,
|
||||||
|
SRCK and SRFS are ignored. Asynchronous mode allows
|
||||||
|
playback and capture to use different sample sizes and
|
||||||
|
sample rates. Some drivers may require that SRCK and STCK
|
||||||
|
be connected together, and SRFS and STFS be connected
|
||||||
|
together. This would still allow different sample sizes,
|
||||||
|
but not different sample rates.
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
- codec-handle : phandle to a 'codec' node that defines an audio
|
- codec-handle: Phandle to a 'codec' node that defines an audio
|
||||||
codec connected to this SSI. This node is typically
|
codec connected to this SSI. This node is typically
|
||||||
a child of an I2C or other control node.
|
a child of an I2C or other control node.
|
||||||
|
|
||||||
Child 'codec' node required properties:
|
Child 'codec' node required properties:
|
||||||
- compatible : compatible list, contains the name of the codec
|
- compatible: Compatible list, contains the name of the codec
|
||||||
|
|
||||||
Child 'codec' node optional properties:
|
Child 'codec' node optional properties:
|
||||||
- clock-frequency : The frequency of the input clock, which typically
|
- clock-frequency: The frequency of the input clock, which typically comes
|
||||||
comes from an on-board dedicated oscillator.
|
from an on-board dedicated oscillator.
|
||||||
|
|
||||||
Notes on fsl,playback-dma and fsl,capture-dma:
|
Notes on fsl,playback-dma and fsl,capture-dma:
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,12 @@ Properties:
|
||||||
hardware.
|
hardware.
|
||||||
- fsl,magic-packet : If present, indicates that the hardware supports
|
- fsl,magic-packet : If present, indicates that the hardware supports
|
||||||
waking up via magic packet.
|
waking up via magic packet.
|
||||||
|
- bd-stash : If present, indicates that the hardware supports stashing
|
||||||
|
buffer descriptors in the L2.
|
||||||
|
- rx-stash-len : Denotes the number of bytes of a received buffer to stash
|
||||||
|
in the L2.
|
||||||
|
- rx-stash-idx : Denotes the index of the first byte from the received
|
||||||
|
buffer to stash in the L2.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
ethernet@24000 {
|
ethernet@24000 {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
MMC/SD/SDIO slot directly connected to a SPI bus
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : should be "mmc-spi-slot".
|
||||||
|
- reg : should specify SPI address (chip-select number).
|
||||||
|
- spi-max-frequency : maximum frequency for this device (Hz).
|
||||||
|
- voltage-ranges : two cells are required, first cell specifies minimum
|
||||||
|
slot voltage (mV), second cell specifies maximum slot voltage (mV).
|
||||||
|
Several ranges could be specified.
|
||||||
|
- gpios : (optional) may specify GPIOs in this order: Card-Detect GPIO,
|
||||||
|
Write-Protect GPIO.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
mmc-slot@0 {
|
||||||
|
compatible = "fsl,mpc8323rdb-mmc-slot",
|
||||||
|
"mmc-spi-slot";
|
||||||
|
reg = <0>;
|
||||||
|
gpios = <&qe_pio_d 14 1
|
||||||
|
&qe_pio_d 15 0>;
|
||||||
|
voltage-ranges = <3300 3300>;
|
||||||
|
spi-max-frequency = <50000000>;
|
||||||
|
};
|
|
@ -2,8 +2,6 @@
|
||||||
- this file.
|
- this file.
|
||||||
sched-arch.txt
|
sched-arch.txt
|
||||||
- CPU Scheduler implementation hints for architecture specific code.
|
- CPU Scheduler implementation hints for architecture specific code.
|
||||||
sched-coding.txt
|
|
||||||
- reference for various scheduler-related methods in the O(1) scheduler.
|
|
||||||
sched-design-CFS.txt
|
sched-design-CFS.txt
|
||||||
- goals, design and implementation of the Complete Fair Scheduler.
|
- goals, design and implementation of the Complete Fair Scheduler.
|
||||||
sched-domains.txt
|
sched-domains.txt
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
Reference for various scheduler-related methods in the O(1) scheduler
|
|
||||||
Robert Love <rml@tech9.net>, MontaVista Software
|
|
||||||
|
|
||||||
|
|
||||||
Note most of these methods are local to kernel/sched.c - this is by design.
|
|
||||||
The scheduler is meant to be self-contained and abstracted away. This document
|
|
||||||
is primarily for understanding the scheduler, not interfacing to it. Some of
|
|
||||||
the discussed interfaces, however, are general process/scheduling methods.
|
|
||||||
They are typically defined in include/linux/sched.h.
|
|
||||||
|
|
||||||
|
|
||||||
Main Scheduling Methods
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
void load_balance(runqueue_t *this_rq, int idle)
|
|
||||||
Attempts to pull tasks from one cpu to another to balance cpu usage,
|
|
||||||
if needed. This method is called explicitly if the runqueues are
|
|
||||||
imbalanced or periodically by the timer tick. Prior to calling,
|
|
||||||
the current runqueue must be locked and interrupts disabled.
|
|
||||||
|
|
||||||
void schedule()
|
|
||||||
The main scheduling function. Upon return, the highest priority
|
|
||||||
process will be active.
|
|
||||||
|
|
||||||
|
|
||||||
Locking
|
|
||||||
-------
|
|
||||||
|
|
||||||
Each runqueue has its own lock, rq->lock. When multiple runqueues need
|
|
||||||
to be locked, lock acquires must be ordered by ascending &runqueue value.
|
|
||||||
|
|
||||||
A specific runqueue is locked via
|
|
||||||
|
|
||||||
task_rq_lock(task_t pid, unsigned long *flags)
|
|
||||||
|
|
||||||
which disables preemption, disables interrupts, and locks the runqueue pid is
|
|
||||||
running on. Likewise,
|
|
||||||
|
|
||||||
task_rq_unlock(task_t pid, unsigned long *flags)
|
|
||||||
|
|
||||||
unlocks the runqueue pid is running on, restores interrupts to their previous
|
|
||||||
state, and reenables preemption.
|
|
||||||
|
|
||||||
The routines
|
|
||||||
|
|
||||||
double_rq_lock(runqueue_t *rq1, runqueue_t *rq2)
|
|
||||||
|
|
||||||
and
|
|
||||||
|
|
||||||
double_rq_unlock(runqueue_t *rq1, runqueue_t *rq2)
|
|
||||||
|
|
||||||
safely lock and unlock, respectively, the two specified runqueues. They do
|
|
||||||
not, however, disable and restore interrupts. Users are required to do so
|
|
||||||
manually before and after calls.
|
|
||||||
|
|
||||||
|
|
||||||
Values
|
|
||||||
------
|
|
||||||
|
|
||||||
MAX_PRIO
|
|
||||||
The maximum priority of the system, stored in the task as task->prio.
|
|
||||||
Lower priorities are higher. Normal (non-RT) priorities range from
|
|
||||||
MAX_RT_PRIO to (MAX_PRIO - 1).
|
|
||||||
MAX_RT_PRIO
|
|
||||||
The maximum real-time priority of the system. Valid RT priorities
|
|
||||||
range from 0 to (MAX_RT_PRIO - 1).
|
|
||||||
MAX_USER_RT_PRIO
|
|
||||||
The maximum real-time priority that is exported to user-space. Should
|
|
||||||
always be equal to or less than MAX_RT_PRIO. Setting it less allows
|
|
||||||
kernel threads to have higher priorities than any user-space task.
|
|
||||||
MIN_TIMESLICE
|
|
||||||
MAX_TIMESLICE
|
|
||||||
Respectively, the minimum and maximum timeslices (quanta) of a process.
|
|
||||||
|
|
||||||
Data
|
|
||||||
----
|
|
||||||
|
|
||||||
struct runqueue
|
|
||||||
The main per-CPU runqueue data structure.
|
|
||||||
struct task_struct
|
|
||||||
The main per-process data structure.
|
|
||||||
|
|
||||||
|
|
||||||
General Methods
|
|
||||||
---------------
|
|
||||||
|
|
||||||
cpu_rq(cpu)
|
|
||||||
Returns the runqueue of the specified cpu.
|
|
||||||
this_rq()
|
|
||||||
Returns the runqueue of the current cpu.
|
|
||||||
task_rq(pid)
|
|
||||||
Returns the runqueue which holds the specified pid.
|
|
||||||
cpu_curr(cpu)
|
|
||||||
Returns the task currently running on the given cpu.
|
|
||||||
rt_task(pid)
|
|
||||||
Returns true if pid is real-time, false if not.
|
|
||||||
|
|
||||||
|
|
||||||
Process Control Methods
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
void set_user_nice(task_t *p, long nice)
|
|
||||||
Sets the "nice" value of task p to the given value.
|
|
||||||
int setscheduler(pid_t pid, int policy, struct sched_param *param)
|
|
||||||
Sets the scheduling policy and parameters for the given pid.
|
|
||||||
int set_cpus_allowed(task_t *p, unsigned long new_mask)
|
|
||||||
Sets a given task's CPU affinity and migrates it to a proper cpu.
|
|
||||||
Callers must have a valid reference to the task and assure the
|
|
||||||
task not exit prematurely. No locks can be held during the call.
|
|
||||||
set_task_state(tsk, state_value)
|
|
||||||
Sets the given task's state to the given value.
|
|
||||||
set_current_state(state_value)
|
|
||||||
Sets the current task's state to the given value.
|
|
||||||
void set_tsk_need_resched(struct task_struct *tsk)
|
|
||||||
Sets need_resched in the given task.
|
|
||||||
void clear_tsk_need_resched(struct task_struct *tsk)
|
|
||||||
Clears need_resched in the given task.
|
|
||||||
void set_need_resched()
|
|
||||||
Sets need_resched in the current task.
|
|
||||||
void clear_need_resched()
|
|
||||||
Clears need_resched in the current task.
|
|
||||||
int need_resched()
|
|
||||||
Returns true if need_resched is set in the current task, false
|
|
||||||
otherwise.
|
|
||||||
yield()
|
|
||||||
Place the current process at the end of the runqueue and call schedule.
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
The OSD Standard
|
||||||
|
================
|
||||||
|
OSD (Object-Based Storage Device) is a T10 SCSI command set that is designed
|
||||||
|
to provide efficient operation of input/output logical units that manage the
|
||||||
|
allocation, placement, and accessing of variable-size data-storage containers,
|
||||||
|
called objects. Objects are intended to contain operating system and application
|
||||||
|
constructs. Each object has associated attributes attached to it, which are
|
||||||
|
integral part of the object and provide metadata about the object. The standard
|
||||||
|
defines some common obligatory attributes, but user attributes can be added as
|
||||||
|
needed.
|
||||||
|
|
||||||
|
See: http://www.t10.org/ftp/t10/drafts/osd2/ for the latest draft for OSD 2
|
||||||
|
or search the web for "OSD SCSI"
|
||||||
|
|
||||||
|
OSD in the Linux Kernel
|
||||||
|
=======================
|
||||||
|
osd-initiator:
|
||||||
|
The main component of OSD in Kernel is the osd-initiator library. Its main
|
||||||
|
user is intended to be the pNFS-over-objects layout driver, which uses objects
|
||||||
|
as its back-end data storage. Other clients are the other osd parts listed below.
|
||||||
|
|
||||||
|
osd-uld:
|
||||||
|
This is a SCSI ULD that registers for OSD type devices and provides a testing
|
||||||
|
platform, both for the in-kernel initiator as well as connected targets. It
|
||||||
|
currently has no useful user-mode API, though it could have if need be.
|
||||||
|
|
||||||
|
exofs:
|
||||||
|
Is an OSD based Linux file system. It uses the osd-initiator and osd-uld,
|
||||||
|
to export a usable file system for users.
|
||||||
|
See Documentation/filesystems/exofs.txt for more details
|
||||||
|
|
||||||
|
osd target:
|
||||||
|
There are no current plans for an OSD target implementation in kernel. For all
|
||||||
|
needs, a user-mode target that is based on the scsi tgt target framework is
|
||||||
|
available from Ohio Supercomputer Center (OSC) at:
|
||||||
|
http://www.open-osd.org/bin/view/Main/OscOsdProject
|
||||||
|
There are several other target implementations. See http://open-osd.org for more
|
||||||
|
links.
|
||||||
|
|
||||||
|
Files and Folders
|
||||||
|
=================
|
||||||
|
This is the complete list of files included in this work:
|
||||||
|
include/scsi/
|
||||||
|
osd_initiator.h Main API for the initiator library
|
||||||
|
osd_types.h Common OSD types
|
||||||
|
osd_sec.h Security Manager API
|
||||||
|
osd_protocol.h Wire definitions of the OSD standard protocol
|
||||||
|
osd_attributes.h Wire definitions of OSD attributes
|
||||||
|
|
||||||
|
drivers/scsi/osd/
|
||||||
|
osd_initiator.c OSD-Initiator library implementation
|
||||||
|
osd_uld.c The OSD scsi ULD
|
||||||
|
osd_ktest.{h,c} In-kernel test suite (called by osd_uld)
|
||||||
|
osd_debug.h Some printk macros
|
||||||
|
Makefile For both in-tree and out-of-tree compilation
|
||||||
|
Kconfig Enables inclusion of the different pieces
|
||||||
|
osd_test.c User-mode application to call the kernel tests
|
||||||
|
|
||||||
|
The OSD-Initiator Library
|
||||||
|
=========================
|
||||||
|
osd_initiator is a low level implementation of an osd initiator encoder.
|
||||||
|
But even though, it should be intuitive and easy to use. Perhaps over time an
|
||||||
|
higher lever will form that automates some of the more common recipes.
|
||||||
|
|
||||||
|
init/fini:
|
||||||
|
- osd_dev_init() associates a scsi_device with an osd_dev structure
|
||||||
|
and initializes some global pools. This should be done once per scsi_device
|
||||||
|
(OSD LUN). The osd_dev structure is needed for calling osd_start_request().
|
||||||
|
|
||||||
|
- osd_dev_fini() cleans up before a osd_dev/scsi_device destruction.
|
||||||
|
|
||||||
|
OSD commands encoding, execution, and decoding of results:
|
||||||
|
|
||||||
|
struct osd_request's is used to iteratively encode an OSD command and carry
|
||||||
|
its state throughout execution. Each request goes through these stages:
|
||||||
|
|
||||||
|
a. osd_start_request() allocates the request.
|
||||||
|
|
||||||
|
b. Any of the osd_req_* methods is used to encode a request of the specified
|
||||||
|
type.
|
||||||
|
|
||||||
|
c. osd_req_add_{get,set}_attr_* may be called to add get/set attributes to the
|
||||||
|
CDB. "List" or "Page" mode can be used exclusively. The attribute-list API
|
||||||
|
can be called multiple times on the same request. However, only one
|
||||||
|
attribute-page can be read, as mandated by the OSD standard.
|
||||||
|
|
||||||
|
d. osd_finalize_request() computes offsets into the data-in and data-out buffers
|
||||||
|
and signs the request using the provided capability key and integrity-
|
||||||
|
check parameters.
|
||||||
|
|
||||||
|
e. osd_execute_request() may be called to execute the request via the block
|
||||||
|
layer and wait for its completion. The request can be executed
|
||||||
|
asynchronously by calling the block layer API directly.
|
||||||
|
|
||||||
|
f. After execution, osd_req_decode_sense() can be called to decode the request's
|
||||||
|
sense information.
|
||||||
|
|
||||||
|
g. osd_req_decode_get_attr() may be called to retrieve osd_add_get_attr_list()
|
||||||
|
values.
|
||||||
|
|
||||||
|
h. osd_end_request() must be called to deallocate the request and any resource
|
||||||
|
associated with it. Note that osd_end_request cleans up the request at any
|
||||||
|
stage and it must always be called after a successful osd_start_request().
|
||||||
|
|
||||||
|
osd_request's structure:
|
||||||
|
|
||||||
|
The OSD standard defines a complex structure of IO segments pointed to by
|
||||||
|
members in the CDB. Up to 3 segments can be deployed in the IN-Buffer and up to
|
||||||
|
4 in the OUT-Buffer. The ASCII illustration below depicts a secure-read with
|
||||||
|
associated get+set of attributes-lists. Other combinations very on the same
|
||||||
|
basic theme. From no-segments-used up to all-segments-used.
|
||||||
|
|
||||||
|
|________OSD-CDB__________|
|
||||||
|
| |
|
||||||
|
|read_len (offset=0) -|---------\
|
||||||
|
| | |
|
||||||
|
|get_attrs_list_length | |
|
||||||
|
|get_attrs_list_offset -|----\ |
|
||||||
|
| | | |
|
||||||
|
|retrieved_attrs_alloc_len| | |
|
||||||
|
|retrieved_attrs_offset -|----|----|-\
|
||||||
|
| | | | |
|
||||||
|
|set_attrs_list_length | | | |
|
||||||
|
|set_attrs_list_offset -|-\ | | |
|
||||||
|
| | | | | |
|
||||||
|
|in_data_integ_offset -|-|--|----|-|-\
|
||||||
|
|out_data_integ_offset -|-|--|--\ | | |
|
||||||
|
\_________________________/ | | | | | |
|
||||||
|
| | | | | |
|
||||||
|
|_______OUT-BUFFER________| | | | | | |
|
||||||
|
| Set attr list |</ | | | | |
|
||||||
|
| | | | | | |
|
||||||
|
|-------------------------| | | | | |
|
||||||
|
| Get attr descriptors |<---/ | | | |
|
||||||
|
| | | | | |
|
||||||
|
|-------------------------| | | | |
|
||||||
|
| Out-data integrity |<------/ | | |
|
||||||
|
| | | | |
|
||||||
|
\_________________________/ | | |
|
||||||
|
| | |
|
||||||
|
|________IN-BUFFER________| | | |
|
||||||
|
| In-Data read |<--------/ | |
|
||||||
|
| | | |
|
||||||
|
|-------------------------| | |
|
||||||
|
| Get attr list |<----------/ |
|
||||||
|
| | |
|
||||||
|
|-------------------------| |
|
||||||
|
| In-data integrity |<------------/
|
||||||
|
| |
|
||||||
|
\_________________________/
|
||||||
|
|
||||||
|
A block device request can carry bidirectional payload by means of associating
|
||||||
|
a bidi_read request with a main write-request. Each in/out request is described
|
||||||
|
by a chain of BIOs associated with each request.
|
||||||
|
The CDB is of a SCSI VARLEN CDB format, as described by OSD standard.
|
||||||
|
The OSD standard also mandates alignment restrictions at start of each segment.
|
||||||
|
|
||||||
|
In the code, in struct osd_request, there are two _osd_io_info structures to
|
||||||
|
describe the IN/OUT buffers above, two BIOs for the data payload and up to five
|
||||||
|
_osd_req_data_segment structures to hold the different segments allocation and
|
||||||
|
information.
|
||||||
|
|
||||||
|
Important: We have chosen to disregard the assumption that a BIO-chain (and
|
||||||
|
the resulting sg-list) describes a linear memory buffer. Meaning only first and
|
||||||
|
last scatter chain can be incomplete and all the middle chains are of PAGE_SIZE.
|
||||||
|
For us, a scatter-gather-list, as its name implies and as used by the Networking
|
||||||
|
layer, is to describe a vector of buffers that will be transferred to/from the
|
||||||
|
wire. It works very well with current iSCSI transport. iSCSI is currently the
|
||||||
|
only deployed OSD transport. In the future we anticipate SAS and FC attached OSD
|
||||||
|
devices as well.
|
||||||
|
|
||||||
|
The OSD Testing ULD
|
||||||
|
===================
|
||||||
|
TODO: More user-mode control on tests.
|
||||||
|
|
||||||
|
Authors, Mailing list
|
||||||
|
=====================
|
||||||
|
Please communicate with us on any deployment of osd, whether using this code
|
||||||
|
or not.
|
||||||
|
|
||||||
|
Any problems, questions, bug reports, lonely OSD nights, please email:
|
||||||
|
OSD Dev List <osd-dev@open-osd.org>
|
||||||
|
|
||||||
|
More up-to-date information can be found on:
|
||||||
|
http://open-osd.org
|
||||||
|
|
||||||
|
Boaz Harrosh <bharrosh@panasas.com>
|
||||||
|
Benny Halevy <bhalevy@panasas.com>
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
Weber, R., "SCSI Object-Based Storage Device Commands",
|
||||||
|
T10/1355-D ANSI/INCITS 400-2004,
|
||||||
|
http://www.t10.org/ftp/t10/drafts/osd/osd-r10.pdf
|
||||||
|
|
||||||
|
Weber, R., "SCSI Object-Based Storage Device Commands -2 (OSD-2)"
|
||||||
|
T10/1729-D, Working Draft, rev. 3
|
||||||
|
http://www.t10.org/ftp/t10/drafts/osd2/osd2r03.pdf
|
|
@ -346,6 +346,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
sbirq - IRQ # for CMI8330 chip (SB16)
|
sbirq - IRQ # for CMI8330 chip (SB16)
|
||||||
sbdma8 - 8bit DMA # for CMI8330 chip (SB16)
|
sbdma8 - 8bit DMA # for CMI8330 chip (SB16)
|
||||||
sbdma16 - 16bit DMA # for CMI8330 chip (SB16)
|
sbdma16 - 16bit DMA # for CMI8330 chip (SB16)
|
||||||
|
fmport - (optional) OPL3 I/O port
|
||||||
|
mpuport - (optional) MPU401 I/O port
|
||||||
|
mpuirq - (optional) MPU401 irq #
|
||||||
|
|
||||||
This module supports multiple cards and autoprobe.
|
This module supports multiple cards and autoprobe.
|
||||||
|
|
||||||
|
@ -388,34 +391,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
|
|
||||||
The power-management is supported.
|
The power-management is supported.
|
||||||
|
|
||||||
Module snd-cs4232
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Module for sound cards based on CS4232/CS4232A ISA chips.
|
|
||||||
|
|
||||||
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
|
|
||||||
|
|
||||||
with isapnp=0, the following options are available:
|
|
||||||
|
|
||||||
port - port # for CS4232 chip (PnP setup - 0x534)
|
|
||||||
cport - control port # for CS4232 chip (PnP setup - 0x120,0x210,0xf00)
|
|
||||||
mpu_port - port # for MPU-401 UART (PnP setup - 0x300), -1 = disable
|
|
||||||
fm_port - FM port # for CS4232 chip (PnP setup - 0x388), -1 = disable
|
|
||||||
irq - IRQ # for CS4232 chip (5,7,9,11,12,15)
|
|
||||||
mpu_irq - IRQ # for MPU-401 UART (9,11,12,15)
|
|
||||||
dma1 - first DMA # for CS4232 chip (0,1,3)
|
|
||||||
dma2 - second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
|
|
||||||
|
|
||||||
This module supports multiple cards. This module does not support autoprobe
|
|
||||||
(if ISA PnP is not used) thus main port must be specified!!! Other ports are
|
|
||||||
optional.
|
|
||||||
|
|
||||||
The power-management is supported.
|
|
||||||
|
|
||||||
Module snd-cs4236
|
Module snd-cs4236
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Module for sound cards based on CS4235/CS4236/CS4236B/CS4237B/
|
Module for sound cards based on CS4232/CS4232A,
|
||||||
|
CS4235/CS4236/CS4236B/CS4237B/
|
||||||
CS4238B/CS4239 ISA chips.
|
CS4238B/CS4239 ISA chips.
|
||||||
|
|
||||||
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
|
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
|
||||||
|
@ -437,6 +417,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
|
|
||||||
The power-management is supported.
|
The power-management is supported.
|
||||||
|
|
||||||
|
This module is aliased as snd-cs4232 since it provides the old
|
||||||
|
snd-cs4232 functionality, too.
|
||||||
|
|
||||||
Module snd-cs4281
|
Module snd-cs4281
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
@ -606,6 +589,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
|
Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
|
||||||
|
|
||||||
port - port # for ES-1688 chip (0x220,0x240,0x260)
|
port - port # for ES-1688 chip (0x220,0x240,0x260)
|
||||||
|
fm_port - port # for OPL3 (option; share the same port as default)
|
||||||
mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
|
mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
|
||||||
irq - IRQ # for ES-1688 chip (5,7,9,10)
|
irq - IRQ # for ES-1688 chip (5,7,9,10)
|
||||||
mpu_irq - IRQ # for MPU-401 port (5,7,9,10)
|
mpu_irq - IRQ # for MPU-401 port (5,7,9,10)
|
||||||
|
@ -757,6 +741,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
model - force the model name
|
model - force the model name
|
||||||
position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
|
position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
|
||||||
probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
|
probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
|
||||||
|
When the bit 8 (0x100) is set, the lower 8 bits are used
|
||||||
|
as the "fixed" codec slots; i.e. the driver probes the
|
||||||
|
slots regardless what hardware reports back
|
||||||
probe_only - Only probing and no codec initialization (default=off);
|
probe_only - Only probing and no codec initialization (default=off);
|
||||||
Useful to check the initial codec status for debugging
|
Useful to check the initial codec status for debugging
|
||||||
bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
|
bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
|
||||||
|
@ -1185,6 +1172,54 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
|
|
||||||
This module supports multiple devices and PnP.
|
This module supports multiple devices and PnP.
|
||||||
|
|
||||||
|
Module snd-msnd-classic
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Module for Turtle Beach MultiSound Classic, Tahiti or Monterey
|
||||||
|
soundcards.
|
||||||
|
|
||||||
|
io - Port # for msnd-classic card
|
||||||
|
irq - IRQ # for msnd-classic card
|
||||||
|
mem - Memory address (0xb0000, 0xc8000, 0xd0000, 0xd8000,
|
||||||
|
0xe0000 or 0xe8000)
|
||||||
|
write_ndelay - enable write ndelay (default = 1)
|
||||||
|
calibrate_signal - calibrate signal (default = 0)
|
||||||
|
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
|
||||||
|
digital - Digital daughterboard present (default = 0)
|
||||||
|
cfg - Config port (0x250, 0x260 or 0x270) default = PnP
|
||||||
|
reset - Reset all devices
|
||||||
|
mpu_io - MPU401 I/O port
|
||||||
|
mpu_irq - MPU401 irq#
|
||||||
|
ide_io0 - IDE port #0
|
||||||
|
ide_io1 - IDE port #1
|
||||||
|
ide_irq - IDE irq#
|
||||||
|
joystick_io - Joystick I/O port
|
||||||
|
|
||||||
|
The driver requires firmware files "turtlebeach/msndinit.bin" and
|
||||||
|
"turtlebeach/msndperm.bin" in the proper firmware directory.
|
||||||
|
|
||||||
|
See Documentation/sound/oss/MultiSound for important information
|
||||||
|
about this driver. Note that it has been discontinued, but the
|
||||||
|
Voyetra Turtle Beach knowledge base entry for it is still available
|
||||||
|
at
|
||||||
|
http://www.turtlebeach.com/site/kb_ftp/790.asp
|
||||||
|
|
||||||
|
Module snd-msnd-pinnacle
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Module for Turtle Beach MultiSound Pinnacle/Fiji soundcards.
|
||||||
|
|
||||||
|
io - Port # for pinnacle/fiji card
|
||||||
|
irq - IRQ # for pinnalce/fiji card
|
||||||
|
mem - Memory address (0xb0000, 0xc8000, 0xd0000, 0xd8000,
|
||||||
|
0xe0000 or 0xe8000)
|
||||||
|
write_ndelay - enable write ndelay (default = 1)
|
||||||
|
calibrate_signal - calibrate signal (default = 0)
|
||||||
|
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
|
||||||
|
|
||||||
|
The driver requires firmware files "turtlebeach/pndspini.bin" and
|
||||||
|
"turtlebeach/pndsperm.bin" in the proper firmware directory.
|
||||||
|
|
||||||
Module snd-mtpav
|
Module snd-mtpav
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -1824,7 +1859,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Module for sound cards based on the Asus AV100/AV200 chips,
|
Module for sound cards based on the Asus AV100/AV200 chips,
|
||||||
i.e., Xonar D1, DX, D2, D2X and HDAV1.3 (Deluxe).
|
i.e., Xonar D1, DX, D2, D2X, HDAV1.3 (Deluxe), and Essence STX.
|
||||||
|
|
||||||
This module supports autoprobe and multiple cards.
|
This module supports autoprobe and multiple cards.
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ ALC262
|
||||||
sony-assamd Sony ASSAMD
|
sony-assamd Sony ASSAMD
|
||||||
toshiba-s06 Toshiba S06
|
toshiba-s06 Toshiba S06
|
||||||
toshiba-rx1 Toshiba RX1
|
toshiba-rx1 Toshiba RX1
|
||||||
|
tyan Tyan Thunder n6650W (S2915-E)
|
||||||
ultra Samsung Q1 Ultra Vista model
|
ultra Samsung Q1 Ultra Vista model
|
||||||
lenovo-3000 Lenovo 3000 y410
|
lenovo-3000 Lenovo 3000 y410
|
||||||
nec NEC Versa S9100
|
nec NEC Versa S9100
|
||||||
|
@ -261,6 +262,8 @@ Conexant 5051
|
||||||
=============
|
=============
|
||||||
laptop Basic Laptop config (default)
|
laptop Basic Laptop config (default)
|
||||||
hp HP Spartan laptop
|
hp HP Spartan laptop
|
||||||
|
hp-dv6736 HP dv6736
|
||||||
|
lenovo-x200 Lenovo X200 laptop
|
||||||
|
|
||||||
STAC9200
|
STAC9200
|
||||||
========
|
========
|
||||||
|
@ -278,6 +281,7 @@ STAC9200
|
||||||
gateway-m4 Gateway laptops with EAPD control
|
gateway-m4 Gateway laptops with EAPD control
|
||||||
gateway-m4-2 Gateway laptops with EAPD control
|
gateway-m4-2 Gateway laptops with EAPD control
|
||||||
panasonic Panasonic CF-74
|
panasonic Panasonic CF-74
|
||||||
|
auto BIOS setup (default)
|
||||||
|
|
||||||
STAC9205/9254
|
STAC9205/9254
|
||||||
=============
|
=============
|
||||||
|
@ -285,6 +289,8 @@ STAC9205/9254
|
||||||
dell-m42 Dell (unknown)
|
dell-m42 Dell (unknown)
|
||||||
dell-m43 Dell Precision
|
dell-m43 Dell Precision
|
||||||
dell-m44 Dell Inspiron
|
dell-m44 Dell Inspiron
|
||||||
|
eapd Keep EAPD on (e.g. Gateway T1616)
|
||||||
|
auto BIOS setup (default)
|
||||||
|
|
||||||
STAC9220/9221
|
STAC9220/9221
|
||||||
=============
|
=============
|
||||||
|
@ -308,6 +314,7 @@ STAC9220/9221
|
||||||
dell-d82 Dell (unknown)
|
dell-d82 Dell (unknown)
|
||||||
dell-m81 Dell (unknown)
|
dell-m81 Dell (unknown)
|
||||||
dell-m82 Dell XPS M1210
|
dell-m82 Dell XPS M1210
|
||||||
|
auto BIOS setup (default)
|
||||||
|
|
||||||
STAC9202/9250/9251
|
STAC9202/9250/9251
|
||||||
==================
|
==================
|
||||||
|
@ -319,6 +326,7 @@ STAC9202/9250/9251
|
||||||
m3 Some Gateway MX series laptops
|
m3 Some Gateway MX series laptops
|
||||||
m5 Some Gateway MX series laptops (MP6954)
|
m5 Some Gateway MX series laptops (MP6954)
|
||||||
m6 Some Gateway NX series laptops
|
m6 Some Gateway NX series laptops
|
||||||
|
auto BIOS setup (default)
|
||||||
|
|
||||||
STAC9227/9228/9229/927x
|
STAC9227/9228/9229/927x
|
||||||
=======================
|
=======================
|
||||||
|
@ -328,6 +336,7 @@ STAC9227/9228/9229/927x
|
||||||
5stack D965 5stack + SPDIF
|
5stack D965 5stack + SPDIF
|
||||||
dell-3stack Dell Dimension E520
|
dell-3stack Dell Dimension E520
|
||||||
dell-bios Fixes with Dell BIOS setup
|
dell-bios Fixes with Dell BIOS setup
|
||||||
|
auto BIOS setup (default)
|
||||||
|
|
||||||
STAC92HD71B*
|
STAC92HD71B*
|
||||||
============
|
============
|
||||||
|
@ -335,7 +344,10 @@ STAC92HD71B*
|
||||||
dell-m4-1 Dell desktops
|
dell-m4-1 Dell desktops
|
||||||
dell-m4-2 Dell desktops
|
dell-m4-2 Dell desktops
|
||||||
dell-m4-3 Dell desktops
|
dell-m4-3 Dell desktops
|
||||||
hp-m4 HP dv laptops
|
hp-m4 HP mini 1000
|
||||||
|
hp-dv5 HP dv series
|
||||||
|
hp-hdx HP HDX series
|
||||||
|
auto BIOS setup (default)
|
||||||
|
|
||||||
STAC92HD73*
|
STAC92HD73*
|
||||||
===========
|
===========
|
||||||
|
@ -345,13 +357,16 @@ STAC92HD73*
|
||||||
dell-m6-dmic Dell desktops/laptops with digital mics
|
dell-m6-dmic Dell desktops/laptops with digital mics
|
||||||
dell-m6 Dell desktops/laptops with both type of mics
|
dell-m6 Dell desktops/laptops with both type of mics
|
||||||
dell-eq Dell desktops/laptops
|
dell-eq Dell desktops/laptops
|
||||||
|
auto BIOS setup (default)
|
||||||
|
|
||||||
STAC92HD83*
|
STAC92HD83*
|
||||||
===========
|
===========
|
||||||
ref Reference board
|
ref Reference board
|
||||||
mic-ref Reference board with power managment for ports
|
mic-ref Reference board with power managment for ports
|
||||||
|
dell-s14 Dell laptop
|
||||||
|
auto BIOS setup (default)
|
||||||
|
|
||||||
STAC9872
|
STAC9872
|
||||||
========
|
========
|
||||||
vaio Setup for VAIO FE550G/SZ110
|
vaio VAIO laptop without SPDIF
|
||||||
vaio-ar Setup for VAIO AR
|
auto BIOS setup (default)
|
||||||
|
|
|
@ -109,6 +109,13 @@ slot, pass `probe_mask=1`. For the first and the third slots, pass
|
||||||
Since 2.6.29 kernel, the driver has a more robust probing method, so
|
Since 2.6.29 kernel, the driver has a more robust probing method, so
|
||||||
this error might happen rarely, though.
|
this error might happen rarely, though.
|
||||||
|
|
||||||
|
On a machine with a broken BIOS, sometimes you need to force the
|
||||||
|
driver to probe the codec slots the hardware doesn't report for use.
|
||||||
|
In such a case, turn the bit 8 (0x100) of `probe_mask` option on.
|
||||||
|
Then the rest 8 bits are passed as the codec slots to probe
|
||||||
|
unconditionally. For example, `probe_mask=0x103` will force to probe
|
||||||
|
the codec slots 0 and 1 no matter what the hardware reports.
|
||||||
|
|
||||||
|
|
||||||
Interrupt Handling
|
Interrupt Handling
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -358,10 +365,26 @@ modelname::
|
||||||
to this file.
|
to this file.
|
||||||
init_verbs::
|
init_verbs::
|
||||||
The extra verbs to execute at initialization. You can add a verb by
|
The extra verbs to execute at initialization. You can add a verb by
|
||||||
writing to this file. Pass tree numbers, nid, verb and parameter.
|
writing to this file. Pass three numbers: nid, verb and parameter
|
||||||
|
(separated with a space).
|
||||||
hints::
|
hints::
|
||||||
Shows hint strings for codec parsers for any use. Right now it's
|
Shows / stores hint strings for codec parsers for any use.
|
||||||
not used.
|
Its format is `key = value`. For example, passing `hp_detect = yes`
|
||||||
|
to IDT/STAC codec parser will result in the disablement of the
|
||||||
|
headphone detection.
|
||||||
|
init_pin_configs::
|
||||||
|
Shows the initial pin default config values set by BIOS.
|
||||||
|
driver_pin_configs::
|
||||||
|
Shows the pin default values set by the codec parser explicitly.
|
||||||
|
This doesn't show all pin values but only the changed values by
|
||||||
|
the parser. That is, if the parser doesn't change the pin default
|
||||||
|
config values by itself, this will contain nothing.
|
||||||
|
user_pin_configs::
|
||||||
|
Shows the pin default config values to override the BIOS setup.
|
||||||
|
Writing this (with two numbers, NID and value) appends the new
|
||||||
|
value. The given will be used instead of the initial BIOS value at
|
||||||
|
the next reconfiguration time. Note that this config will override
|
||||||
|
even the driver pin configs, too.
|
||||||
reconfig::
|
reconfig::
|
||||||
Triggers the codec re-configuration. When any value is written to
|
Triggers the codec re-configuration. When any value is written to
|
||||||
this file, the driver re-initialize and parses the codec tree
|
this file, the driver re-initialize and parses the codec tree
|
||||||
|
@ -371,6 +394,14 @@ clear::
|
||||||
Resets the codec, removes the mixer elements and PCM stuff of the
|
Resets the codec, removes the mixer elements and PCM stuff of the
|
||||||
specified codec, and clear all init verbs and hints.
|
specified codec, and clear all init verbs and hints.
|
||||||
|
|
||||||
|
For example, when you want to change the pin default configuration
|
||||||
|
value of the pin widget 0x14 to 0x9993013f, and let the driver
|
||||||
|
re-configure based on that state, run like below:
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
# echo 0x14 0x9993013f > /sys/class/sound/hwC0D0/user_pin_configs
|
||||||
|
# echo 1 > /sys/class/sound/hwC0D0/reconfig
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
Power-Saving
|
Power-Saving
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
@ -461,6 +492,16 @@ run with `--no-upload` option, and attach the generated file.
|
||||||
There are some other useful options. See `--help` option output for
|
There are some other useful options. See `--help` option output for
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
When a probe error occurs or when the driver obviously assigns a
|
||||||
|
mismatched model, it'd be helpful to load the driver with
|
||||||
|
`probe_only=1` option (at best after the cold reboot) and run
|
||||||
|
alsa-info at this state. With this option, the driver won't configure
|
||||||
|
the mixer and PCM but just tries to probe the codec slot. After
|
||||||
|
probing, the proc file is available, so you can get the raw codec
|
||||||
|
information before modified by the driver. Of course, the driver
|
||||||
|
isn't usable with `probe_only=1`. But you can continue the
|
||||||
|
configuration via hwdep sysfs file if hda-reconfig option is enabled.
|
||||||
|
|
||||||
|
|
||||||
hda-verb
|
hda-verb
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
|
@ -116,6 +116,9 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
|
||||||
SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
|
SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
|
||||||
ARRAY_SIZE(wm8731_output_mixer_controls)),
|
ARRAY_SIZE(wm8731_output_mixer_controls)),
|
||||||
|
|
||||||
|
If you dont want the mixer elements prefixed with the name of the mixer widget,
|
||||||
|
you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same
|
||||||
|
as for SND_SOC_DAPM_MIXER.
|
||||||
|
|
||||||
2.3 Platform/Machine domain Widgets
|
2.3 Platform/Machine domain Widgets
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
To configure the Crystal CS423x sound chip and activate its DSP functions,
|
|
||||||
modules may be loaded in this order:
|
|
||||||
|
|
||||||
modprobe sound
|
|
||||||
insmod ad1848
|
|
||||||
insmod uart401
|
|
||||||
insmod cs4232 io=* irq=* dma=* dma2=*
|
|
||||||
|
|
||||||
This is the meaning of the parameters:
|
|
||||||
|
|
||||||
io--I/O address of the Windows Sound System (normally 0x534)
|
|
||||||
irq--IRQ of this device
|
|
||||||
dma and dma2--DMA channels (DMA2 may be 0)
|
|
||||||
|
|
||||||
On some cards, the board attempts to do non-PnP setup, and fails. If you
|
|
||||||
have problems, use Linux' PnP facilities.
|
|
||||||
|
|
||||||
To get MIDI facilities add
|
|
||||||
|
|
||||||
insmod opl3 io=*
|
|
||||||
|
|
||||||
where "io" is the I/O address of the OPL3 synthesizer. This will be shown
|
|
||||||
in /proc/sys/pnp and is normally 0x388.
|
|
|
@ -80,7 +80,7 @@ Notes:
|
||||||
additional features.
|
additional features.
|
||||||
|
|
||||||
2. The commercial OSS driver may be obtained from the site:
|
2. The commercial OSS driver may be obtained from the site:
|
||||||
http://www/opensound.com. This may be used for cards that
|
http://www.opensound.com. This may be used for cards that
|
||||||
are unsupported by the kernel driver, or may be used
|
are unsupported by the kernel driver, or may be used
|
||||||
by other operating systems.
|
by other operating systems.
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,8 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
|
||||||
|
|
||||||
'i' - Send a SIGKILL to all processes, except for init.
|
'i' - Send a SIGKILL to all processes, except for init.
|
||||||
|
|
||||||
|
'j' - Forcibly "Just thaw it" - filesystems frozen by the FIFREEZE ioctl.
|
||||||
|
|
||||||
'k' - Secure Access Key (SAK) Kills all programs on the current virtual
|
'k' - Secure Access Key (SAK) Kills all programs on the current virtual
|
||||||
console. NOTE: See important comments below in SAK section.
|
console. NOTE: See important comments below in SAK section.
|
||||||
|
|
||||||
|
@ -160,6 +162,9 @@ t'E'rm and k'I'll are useful if you have some sort of runaway process you
|
||||||
are unable to kill any other way, especially if it's spawning other
|
are unable to kill any other way, especially if it's spawning other
|
||||||
processes.
|
processes.
|
||||||
|
|
||||||
|
"'J'ust thaw it" is useful if your system becomes unresponsive due to a frozen
|
||||||
|
(probably root) filesystem via the FIFREEZE ioctl.
|
||||||
|
|
||||||
* Sometimes SysRq seems to get 'stuck' after using it, what can I do?
|
* Sometimes SysRq seems to get 'stuck' after using it, what can I do?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
That happens to me, also. I've found that tapping shift, alt, and control
|
That happens to me, also. I've found that tapping shift, alt, and control
|
||||||
|
|
|
@ -229,16 +229,26 @@ struct usbmon_packet {
|
||||||
int status; /* 28: */
|
int status; /* 28: */
|
||||||
unsigned int length; /* 32: Length of data (submitted or actual) */
|
unsigned int length; /* 32: Length of data (submitted or actual) */
|
||||||
unsigned int len_cap; /* 36: Delivered length */
|
unsigned int len_cap; /* 36: Delivered length */
|
||||||
unsigned char setup[8]; /* 40: Only for Control 'S' */
|
union { /* 40: */
|
||||||
}; /* 48 bytes total */
|
unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
|
||||||
|
struct iso_rec { /* Only for ISO */
|
||||||
|
int error_count;
|
||||||
|
int numdesc;
|
||||||
|
} iso;
|
||||||
|
} s;
|
||||||
|
int interval; /* 48: Only for Interrupt and ISO */
|
||||||
|
int start_frame; /* 52: For ISO */
|
||||||
|
unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */
|
||||||
|
unsigned int ndesc; /* 60: Actual number of ISO descriptors */
|
||||||
|
}; /* 64 total length */
|
||||||
|
|
||||||
These events can be received from a character device by reading with read(2),
|
These events can be received from a character device by reading with read(2),
|
||||||
with an ioctl(2), or by accessing the buffer with mmap.
|
with an ioctl(2), or by accessing the buffer with mmap. However, read(2)
|
||||||
|
only returns first 48 bytes for compatibility reasons.
|
||||||
|
|
||||||
The character device is usually called /dev/usbmonN, where N is the USB bus
|
The character device is usually called /dev/usbmonN, where N is the USB bus
|
||||||
number. Number zero (/dev/usbmon0) is special and means "all buses".
|
number. Number zero (/dev/usbmon0) is special and means "all buses".
|
||||||
However, this feature is not implemented yet. Note that specific naming
|
Note that specific naming policy is set by your Linux distribution.
|
||||||
policy is set by your Linux distribution.
|
|
||||||
|
|
||||||
If you create /dev/usbmon0 by hand, make sure that it is owned by root
|
If you create /dev/usbmon0 by hand, make sure that it is owned by root
|
||||||
and has mode 0600. Otherwise, unpriviledged users will be able to snoop
|
and has mode 0600. Otherwise, unpriviledged users will be able to snoop
|
||||||
|
@ -279,9 +289,10 @@ size is out of [unspecified] bounds for this kernel, the call fails with
|
||||||
This call returns the current size of the buffer in bytes.
|
This call returns the current size of the buffer in bytes.
|
||||||
|
|
||||||
MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg)
|
MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg)
|
||||||
|
MON_IOCX_GETX, defined as _IOW(MON_IOC_MAGIC, 10, struct mon_get_arg)
|
||||||
|
|
||||||
This call waits for events to arrive if none were in the kernel buffer,
|
These calls wait for events to arrive if none were in the kernel buffer,
|
||||||
then returns the first event. Its argument is a pointer to the following
|
then return the first event. The argument is a pointer to the following
|
||||||
structure:
|
structure:
|
||||||
|
|
||||||
struct mon_get_arg {
|
struct mon_get_arg {
|
||||||
|
@ -294,6 +305,8 @@ Before the call, hdr, data, and alloc should be filled. Upon return, the area
|
||||||
pointed by hdr contains the next event structure, and the data buffer contains
|
pointed by hdr contains the next event structure, and the data buffer contains
|
||||||
the data, if any. The event is removed from the kernel buffer.
|
the data, if any. The event is removed from the kernel buffer.
|
||||||
|
|
||||||
|
The MON_IOCX_GET copies 48 bytes, MON_IOCX_GETX copies 64 bytes.
|
||||||
|
|
||||||
MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg)
|
MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg)
|
||||||
|
|
||||||
This ioctl is primarily used when the application accesses the buffer
|
This ioctl is primarily used when the application accesses the buffer
|
||||||
|
|
|
@ -135,7 +135,7 @@
|
||||||
134 -> Adlink RTV24
|
134 -> Adlink RTV24
|
||||||
135 -> DViCO FusionHDTV 5 Lite [18ac:d500]
|
135 -> DViCO FusionHDTV 5 Lite [18ac:d500]
|
||||||
136 -> Acorp Y878F [9511:1540]
|
136 -> Acorp Y878F [9511:1540]
|
||||||
137 -> Conceptronic CTVFMi v2
|
137 -> Conceptronic CTVFMi v2 [036e:109e]
|
||||||
138 -> Prolink Pixelview PV-BT878P+ (Rev.2E)
|
138 -> Prolink Pixelview PV-BT878P+ (Rev.2E)
|
||||||
139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
|
139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
|
||||||
140 -> Osprey 440 [0070:ff07]
|
140 -> Osprey 440 [0070:ff07]
|
||||||
|
@ -154,3 +154,7 @@
|
||||||
153 -> PHYTEC VD-012 (bt878)
|
153 -> PHYTEC VD-012 (bt878)
|
||||||
154 -> PHYTEC VD-012-X1 (bt878)
|
154 -> PHYTEC VD-012-X1 (bt878)
|
||||||
155 -> PHYTEC VD-012-X2 (bt878)
|
155 -> PHYTEC VD-012-X2 (bt878)
|
||||||
|
156 -> IVCE-8784 [0000:f050,0001:f050,0002:f050,0003:f050]
|
||||||
|
157 -> Geovision GV-800(S) (master) [800a:763d]
|
||||||
|
158 -> Geovision GV-800(S) (slave) [800b:763d,800c:763d,800d:763d]
|
||||||
|
159 -> ProVideo PV183 [1830:1540,1831:1540,1832:1540,1833:1540,1834:1540,1835:1540,1836:1540,1837:1540]
|
||||||
|
|
|
@ -12,3 +12,7 @@
|
||||||
11 -> DViCO FusionHDTV DVB-T Dual Express [18ac:db78]
|
11 -> DViCO FusionHDTV DVB-T Dual Express [18ac:db78]
|
||||||
12 -> Leadtek Winfast PxDVR3200 H [107d:6681]
|
12 -> Leadtek Winfast PxDVR3200 H [107d:6681]
|
||||||
13 -> Compro VideoMate E650F [185b:e800]
|
13 -> Compro VideoMate E650F [185b:e800]
|
||||||
|
14 -> TurboSight TBS 6920 [6920:8888]
|
||||||
|
15 -> TeVii S470 [d470:9022]
|
||||||
|
16 -> DVBWorld DVB-S2 2005 [0001:2005]
|
||||||
|
17 -> NetUP Dual DVB-S2 CI [1b55:2a2c]
|
||||||
|
|
|
@ -77,3 +77,4 @@
|
||||||
76 -> SATTRADE ST4200 DVB-S/S2 [b200:4200]
|
76 -> SATTRADE ST4200 DVB-S/S2 [b200:4200]
|
||||||
77 -> TBS 8910 DVB-S [8910:8888]
|
77 -> TBS 8910 DVB-S [8910:8888]
|
||||||
78 -> Prof 6200 DVB-S [b022:3022]
|
78 -> Prof 6200 DVB-S [b022:3022]
|
||||||
|
79 -> Terratec Cinergy HT PCI MKII [153b:1177]
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
6 -> Terratec Cinergy 200 USB (em2800)
|
6 -> Terratec Cinergy 200 USB (em2800)
|
||||||
7 -> Leadtek Winfast USB II (em2800) [0413:6023]
|
7 -> Leadtek Winfast USB II (em2800) [0413:6023]
|
||||||
8 -> Kworld USB2800 (em2800)
|
8 -> Kworld USB2800 (em2800)
|
||||||
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
|
9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,2304:0207,2304:021a]
|
||||||
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
|
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
|
||||||
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
|
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
|
||||||
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
|
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
|
||||||
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
||||||
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
||||||
15 -> V-Gear PocketTV (em2800)
|
15 -> V-Gear PocketTV (em2800)
|
||||||
16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b]
|
16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b]
|
||||||
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
|
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
|
||||||
|
@ -30,7 +30,6 @@
|
||||||
30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
|
30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
|
||||||
31 -> Usbgear VD204v9 (em2821)
|
31 -> Usbgear VD204v9 (em2821)
|
||||||
32 -> Supercomp USB 2.0 TV (em2821)
|
32 -> Supercomp USB 2.0 TV (em2821)
|
||||||
33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0 (em2821)
|
|
||||||
34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f]
|
34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f]
|
||||||
35 -> Typhoon DVD Maker (em2860)
|
35 -> Typhoon DVD Maker (em2860)
|
||||||
36 -> NetGMBH Cam (em2860)
|
36 -> NetGMBH Cam (em2860)
|
||||||
|
@ -58,3 +57,7 @@
|
||||||
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
|
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
|
||||||
60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f]
|
60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f]
|
||||||
61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840)
|
61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840)
|
||||||
|
62 -> Gadmei TVR200 (em2820/em2840)
|
||||||
|
63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303]
|
||||||
|
64 -> Easy Cap Capture DC-60 (em2860)
|
||||||
|
65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515]
|
||||||
|
|
|
@ -153,3 +153,5 @@
|
||||||
152 -> Asus Tiger Rev:1.00 [1043:4857]
|
152 -> Asus Tiger Rev:1.00 [1043:4857]
|
||||||
153 -> Kworld Plus TV Analog Lite PCI [17de:7128]
|
153 -> Kworld Plus TV Analog Lite PCI [17de:7128]
|
||||||
154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d]
|
154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d]
|
||||||
|
155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid [0070:6706,0070:6708]
|
||||||
|
156 -> Hauppauge WinTV-HVR1110r3 [0070:6707,0070:6709,0070:670a]
|
||||||
|
|
|
@ -401,8 +401,7 @@ Additional notes for software developers:
|
||||||
first set the correct norm. Well, it seems logically correct: TV
|
first set the correct norm. Well, it seems logically correct: TV
|
||||||
standard is "more constant" for current country than geometry
|
standard is "more constant" for current country than geometry
|
||||||
settings of a variety of TV capture cards which may work in ITU or
|
settings of a variety of TV capture cards which may work in ITU or
|
||||||
square pixel format. Remember that users now can lock the norm to
|
square pixel format.
|
||||||
avoid any ambiguity.
|
|
||||||
--
|
--
|
||||||
Please note that lavplay/lavrec are also included in the MJPEG-tools
|
Please note that lavplay/lavrec are also included in the MJPEG-tools
|
||||||
(http://mjpeg.sf.net/).
|
(http://mjpeg.sf.net/).
|
||||||
|
|
|
@ -81,16 +81,6 @@ tuner.o
|
||||||
pal=[bdgil] select PAL variant (used for some tuners
|
pal=[bdgil] select PAL variant (used for some tuners
|
||||||
only, important for the audio carrier).
|
only, important for the audio carrier).
|
||||||
|
|
||||||
tvmixer.o
|
|
||||||
registers a mixer device for the TV card's volume/bass/treble
|
|
||||||
controls (requires a i2c audio control chip like the msp3400).
|
|
||||||
|
|
||||||
insmod args:
|
|
||||||
debug=1 print some debug info to the syslog.
|
|
||||||
devnr=n allocate device #n (0 == /dev/mixer,
|
|
||||||
1 = /dev/mixer1, ...), default is to
|
|
||||||
use the first free one.
|
|
||||||
|
|
||||||
tvaudio.o
|
tvaudio.o
|
||||||
new, experimental module which is supported to provide a single
|
new, experimental module which is supported to provide a single
|
||||||
driver for all simple i2c audio control chips (tda/tea*).
|
driver for all simple i2c audio control chips (tda/tea*).
|
||||||
|
|
|
@ -63,8 +63,8 @@ If you have some knowledge and spare time, please try to fix this
|
||||||
yourself (patches very welcome of course...) You know: The linux
|
yourself (patches very welcome of course...) You know: The linux
|
||||||
slogan is "Do it yourself".
|
slogan is "Do it yourself".
|
||||||
|
|
||||||
There is a mailing list: video4linux-list@redhat.com.
|
There is a mailing list: linux-media@vger.kernel.org
|
||||||
https://listman.redhat.com/mailman/listinfo/video4linux-list
|
http://vger.kernel.org/vger-lists.html#linux-media
|
||||||
|
|
||||||
If you have trouble with some specific TV card, try to ask there
|
If you have trouble with some specific TV card, try to ask there
|
||||||
instead of mailing me directly. The chance that someone with the
|
instead of mailing me directly. The chance that someone with the
|
||||||
|
|
|
@ -32,6 +32,10 @@ Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
|
||||||
The width of a frame is always 720 pixels, regardless of the actual specified
|
The width of a frame is always 720 pixels, regardless of the actual specified
|
||||||
width.
|
width.
|
||||||
|
|
||||||
|
If the height is not a multiple of 32 lines, then the captured video is
|
||||||
|
missing macroblocks at the end and is unusable. So the height must be a
|
||||||
|
multiple of 32.
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -32,6 +32,7 @@ spca561 041e:403b Creative Webcam Vista (VF0010)
|
||||||
zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250)
|
zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250)
|
||||||
ov519 041e:4052 Creative Live! VISTA IM
|
ov519 041e:4052 Creative Live! VISTA IM
|
||||||
zc3xx 041e:4053 Creative Live!Cam Video IM
|
zc3xx 041e:4053 Creative Live!Cam Video IM
|
||||||
|
vc032x 041e:405b Creative Live! Cam Notebook Ultra (VC0130)
|
||||||
ov519 041e:405f Creative Live! VISTA VF0330
|
ov519 041e:405f Creative Live! VISTA VF0330
|
||||||
ov519 041e:4060 Creative Live! VISTA VF0350
|
ov519 041e:4060 Creative Live! VISTA VF0350
|
||||||
ov519 041e:4061 Creative Live! VISTA VF0400
|
ov519 041e:4061 Creative Live! VISTA VF0400
|
||||||
|
@ -193,6 +194,7 @@ spca500 084d:0003 D-Link DSC-350
|
||||||
spca500 08ca:0103 Aiptek PocketDV
|
spca500 08ca:0103 Aiptek PocketDV
|
||||||
sunplus 08ca:0104 Aiptek PocketDVII 1.3
|
sunplus 08ca:0104 Aiptek PocketDVII 1.3
|
||||||
sunplus 08ca:0106 Aiptek Pocket DV3100+
|
sunplus 08ca:0106 Aiptek Pocket DV3100+
|
||||||
|
mr97310a 08ca:0111 Aiptek PenCam VGA+
|
||||||
sunplus 08ca:2008 Aiptek Mini PenCam 2 M
|
sunplus 08ca:2008 Aiptek Mini PenCam 2 M
|
||||||
sunplus 08ca:2010 Aiptek PocketCam 3M
|
sunplus 08ca:2010 Aiptek PocketCam 3M
|
||||||
sunplus 08ca:2016 Aiptek PocketCam 2 Mega
|
sunplus 08ca:2016 Aiptek PocketCam 2 Mega
|
||||||
|
@ -215,6 +217,7 @@ pac207 093a:2468 PAC207
|
||||||
pac207 093a:2470 Genius GF112
|
pac207 093a:2470 Genius GF112
|
||||||
pac207 093a:2471 Genius VideoCam ge111
|
pac207 093a:2471 Genius VideoCam ge111
|
||||||
pac207 093a:2472 Genius VideoCam ge110
|
pac207 093a:2472 Genius VideoCam ge110
|
||||||
|
pac207 093a:2474 Genius iLook 111
|
||||||
pac207 093a:2476 Genius e-Messenger 112
|
pac207 093a:2476 Genius e-Messenger 112
|
||||||
pac7311 093a:2600 PAC7311 Typhoon
|
pac7311 093a:2600 PAC7311 Typhoon
|
||||||
pac7311 093a:2601 Philips SPC 610 NC
|
pac7311 093a:2601 Philips SPC 610 NC
|
||||||
|
@ -279,6 +282,7 @@ spca561 10fd:7e50 FlyCam Usb 100
|
||||||
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
|
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
|
||||||
ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201)
|
ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201)
|
||||||
pac207 145f:013a Trust WB-1300N
|
pac207 145f:013a Trust WB-1300N
|
||||||
|
vc032x 15b8:6001 HP 2.0 Megapixel
|
||||||
vc032x 15b8:6002 HP 2.0 Megapixel rz406aa
|
vc032x 15b8:6002 HP 2.0 Megapixel rz406aa
|
||||||
spca501 1776:501c Arowana 300K CMOS Camera
|
spca501 1776:501c Arowana 300K CMOS Camera
|
||||||
t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
|
t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers
|
Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers
|
||||||
|
|
||||||
Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
|
Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
|
||||||
|
|
||||||
|
|
||||||
Information from Silicon Labs
|
Information from Silicon Labs
|
||||||
|
@ -41,7 +41,7 @@ chips are known to work:
|
||||||
- 10c4:818a: Silicon Labs USB FM Radio Reference Design
|
- 10c4:818a: Silicon Labs USB FM Radio Reference Design
|
||||||
- 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
|
- 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
|
||||||
- 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
|
- 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
|
||||||
- 10c5:819a: DealExtreme USB Radio
|
- 10c5:819a: Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
|
||||||
|
|
||||||
|
|
||||||
Software
|
Software
|
||||||
|
@ -52,6 +52,7 @@ Testing is usually done with most application under Debian/testing:
|
||||||
- gradio - GTK FM radio tuner
|
- gradio - GTK FM radio tuner
|
||||||
- kradio - Comfortable Radio Application for KDE
|
- kradio - Comfortable Radio Application for KDE
|
||||||
- radio - ncurses-based radio application
|
- radio - ncurses-based radio application
|
||||||
|
- mplayer - The Ultimate Movie Player For Linux
|
||||||
|
|
||||||
There is also a library libv4l, which can be used. It's going to have a function
|
There is also a library libv4l, which can be used. It's going to have a function
|
||||||
for frequency seeking, either by using hardware functionality as in radio-si470x
|
for frequency seeking, either by using hardware functionality as in radio-si470x
|
||||||
|
@ -69,7 +70,7 @@ Audio Listing
|
||||||
USB Audio is provided by the ALSA snd_usb_audio module. It is recommended to
|
USB Audio is provided by the ALSA snd_usb_audio module. It is recommended to
|
||||||
also select SND_USB_AUDIO, as this is required to get sound from the radio. For
|
also select SND_USB_AUDIO, as this is required to get sound from the radio. For
|
||||||
listing you have to redirect the sound, for example using one of the following
|
listing you have to redirect the sound, for example using one of the following
|
||||||
commands.
|
commands. Please adjust the audio devices to your needs (/dev/dsp* and hw:x,x).
|
||||||
|
|
||||||
If you just want to test audio (very poor quality):
|
If you just want to test audio (very poor quality):
|
||||||
cat /dev/dsp1 > /dev/dsp
|
cat /dev/dsp1 > /dev/dsp
|
||||||
|
@ -80,6 +81,10 @@ sox -2 --endian little -r 96000 -t oss /dev/dsp1 -t oss /dev/dsp
|
||||||
If you use arts try:
|
If you use arts try:
|
||||||
arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B -
|
arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B -
|
||||||
|
|
||||||
|
If you use mplayer try:
|
||||||
|
mplayer -radio adevice=hw=1.0:arate=96000 \
|
||||||
|
-rawaudio rate=96000 \
|
||||||
|
radio://<frequency>/capture
|
||||||
|
|
||||||
Module Parameters
|
Module Parameters
|
||||||
=================
|
=================
|
||||||
|
|
|
@ -47,7 +47,9 @@ All drivers have the following structure:
|
||||||
3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and
|
3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and
|
||||||
/dev/vtxX) and keeping track of device-node specific data.
|
/dev/vtxX) and keeping track of device-node specific data.
|
||||||
|
|
||||||
4) Filehandle-specific structs containing per-filehandle data.
|
4) Filehandle-specific structs containing per-filehandle data;
|
||||||
|
|
||||||
|
5) video buffer handling.
|
||||||
|
|
||||||
This is a rough schematic of how it all relates:
|
This is a rough schematic of how it all relates:
|
||||||
|
|
||||||
|
@ -82,12 +84,20 @@ You must register the device instance:
|
||||||
v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
|
v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
|
||||||
|
|
||||||
Registration will initialize the v4l2_device struct and link dev->driver_data
|
Registration will initialize the v4l2_device struct and link dev->driver_data
|
||||||
to v4l2_dev. Registration will also set v4l2_dev->name to a value derived from
|
to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived
|
||||||
dev (driver name followed by the bus_id, to be precise). You may change the
|
from dev (driver name followed by the bus_id, to be precise). If you set it
|
||||||
name after registration if you want.
|
up before calling v4l2_device_register then it will be untouched. If dev is
|
||||||
|
NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
|
||||||
|
|
||||||
The first 'dev' argument is normally the struct device pointer of a pci_dev,
|
The first 'dev' argument is normally the struct device pointer of a pci_dev,
|
||||||
usb_device or platform_device.
|
usb_device or platform_device. It is rare for dev to be NULL, but it happens
|
||||||
|
with ISA devices or when one device creates multiple PCI devices, thus making
|
||||||
|
it impossible to associate v4l2_dev with a particular parent.
|
||||||
|
|
||||||
|
You can also supply a notify() callback that can be called by sub-devices to
|
||||||
|
notify you of events. Whether you need to set this depends on the sub-device.
|
||||||
|
Any notifications a sub-device supports must be defined in a header in
|
||||||
|
include/media/<subdevice>.h.
|
||||||
|
|
||||||
You unregister with:
|
You unregister with:
|
||||||
|
|
||||||
|
@ -95,6 +105,17 @@ You unregister with:
|
||||||
|
|
||||||
Unregistering will also automatically unregister all subdevs from the device.
|
Unregistering will also automatically unregister all subdevs from the device.
|
||||||
|
|
||||||
|
If you have a hotpluggable device (e.g. a USB device), then when a disconnect
|
||||||
|
happens the parent device becomes invalid. Since v4l2_device has a pointer to
|
||||||
|
that parent device it has to be cleared as well to mark that the parent is
|
||||||
|
gone. To do this call:
|
||||||
|
|
||||||
|
v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
|
||||||
|
|
||||||
|
This does *not* unregister the subdevs, so you still need to call the
|
||||||
|
v4l2_device_unregister() function for that. If your driver is not hotpluggable,
|
||||||
|
then there is no need to call v4l2_device_disconnect().
|
||||||
|
|
||||||
Sometimes you need to iterate over all devices registered by a specific
|
Sometimes you need to iterate over all devices registered by a specific
|
||||||
driver. This is usually the case if multiple device drivers use the same
|
driver. This is usually the case if multiple device drivers use the same
|
||||||
hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
|
hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
|
||||||
|
@ -134,7 +155,7 @@ The recommended approach is as follows:
|
||||||
|
|
||||||
static atomic_t drv_instance = ATOMIC_INIT(0);
|
static atomic_t drv_instance = ATOMIC_INIT(0);
|
||||||
|
|
||||||
static int __devinit drv_probe(struct pci_dev *dev,
|
static int __devinit drv_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *pci_id)
|
const struct pci_device_id *pci_id)
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
|
@ -218,7 +239,7 @@ to add new ops and categories.
|
||||||
|
|
||||||
A sub-device driver initializes the v4l2_subdev struct using:
|
A sub-device driver initializes the v4l2_subdev struct using:
|
||||||
|
|
||||||
v4l2_subdev_init(subdev, &ops);
|
v4l2_subdev_init(sd, &ops);
|
||||||
|
|
||||||
Afterwards you need to initialize subdev->name with a unique name and set the
|
Afterwards you need to initialize subdev->name with a unique name and set the
|
||||||
module owner. This is done for you if you use the i2c helper functions.
|
module owner. This is done for you if you use the i2c helper functions.
|
||||||
|
@ -226,7 +247,7 @@ module owner. This is done for you if you use the i2c helper functions.
|
||||||
A device (bridge) driver needs to register the v4l2_subdev with the
|
A device (bridge) driver needs to register the v4l2_subdev with the
|
||||||
v4l2_device:
|
v4l2_device:
|
||||||
|
|
||||||
int err = v4l2_device_register_subdev(device, subdev);
|
int err = v4l2_device_register_subdev(v4l2_dev, sd);
|
||||||
|
|
||||||
This can fail if the subdev module disappeared before it could be registered.
|
This can fail if the subdev module disappeared before it could be registered.
|
||||||
After this function was called successfully the subdev->dev field points to
|
After this function was called successfully the subdev->dev field points to
|
||||||
|
@ -234,17 +255,17 @@ the v4l2_device.
|
||||||
|
|
||||||
You can unregister a sub-device using:
|
You can unregister a sub-device using:
|
||||||
|
|
||||||
v4l2_device_unregister_subdev(subdev);
|
v4l2_device_unregister_subdev(sd);
|
||||||
|
|
||||||
Afterwards the subdev module can be unloaded and subdev->dev == NULL.
|
Afterwards the subdev module can be unloaded and sd->dev == NULL.
|
||||||
|
|
||||||
You can call an ops function either directly:
|
You can call an ops function either directly:
|
||||||
|
|
||||||
err = subdev->ops->core->g_chip_ident(subdev, &chip);
|
err = sd->ops->core->g_chip_ident(sd, &chip);
|
||||||
|
|
||||||
but it is better and easier to use this macro:
|
but it is better and easier to use this macro:
|
||||||
|
|
||||||
err = v4l2_subdev_call(subdev, core, g_chip_ident, &chip);
|
err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
|
||||||
|
|
||||||
The macro will to the right NULL pointer checks and returns -ENODEV if subdev
|
The macro will to the right NULL pointer checks and returns -ENODEV if subdev
|
||||||
is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is
|
is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is
|
||||||
|
@ -252,19 +273,19 @@ NULL, or the actual result of the subdev->ops->core->g_chip_ident ops.
|
||||||
|
|
||||||
It is also possible to call all or a subset of the sub-devices:
|
It is also possible to call all or a subset of the sub-devices:
|
||||||
|
|
||||||
v4l2_device_call_all(dev, 0, core, g_chip_ident, &chip);
|
v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
|
||||||
|
|
||||||
Any subdev that does not support this ops is skipped and error results are
|
Any subdev that does not support this ops is skipped and error results are
|
||||||
ignored. If you want to check for errors use this:
|
ignored. If you want to check for errors use this:
|
||||||
|
|
||||||
err = v4l2_device_call_until_err(dev, 0, core, g_chip_ident, &chip);
|
err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
|
||||||
|
|
||||||
Any error except -ENOIOCTLCMD will exit the loop with that error. If no
|
Any error except -ENOIOCTLCMD will exit the loop with that error. If no
|
||||||
errors (except -ENOIOCTLCMD) occured, then 0 is returned.
|
errors (except -ENOIOCTLCMD) occured, then 0 is returned.
|
||||||
|
|
||||||
The second argument to both calls is a group ID. If 0, then all subdevs are
|
The second argument to both calls is a group ID. If 0, then all subdevs are
|
||||||
called. If non-zero, then only those whose group ID match that value will
|
called. If non-zero, then only those whose group ID match that value will
|
||||||
be called. Before a bridge driver registers a subdev it can set subdev->grp_id
|
be called. Before a bridge driver registers a subdev it can set sd->grp_id
|
||||||
to whatever value it wants (it's 0 by default). This value is owned by the
|
to whatever value it wants (it's 0 by default). This value is owned by the
|
||||||
bridge driver and the sub-device driver will never modify or use it.
|
bridge driver and the sub-device driver will never modify or use it.
|
||||||
|
|
||||||
|
@ -276,6 +297,11 @@ e.g. AUDIO_CONTROLLER and specify that as the group ID value when calling
|
||||||
v4l2_device_call_all(). That ensures that it will only go to the subdev
|
v4l2_device_call_all(). That ensures that it will only go to the subdev
|
||||||
that needs it.
|
that needs it.
|
||||||
|
|
||||||
|
If the sub-device needs to notify its v4l2_device parent of an event, then
|
||||||
|
it can call v4l2_subdev_notify(sd, notification, arg). This macro checks
|
||||||
|
whether there is a notify() callback defined and returns -ENODEV if not.
|
||||||
|
Otherwise the result of the notify() call is returned.
|
||||||
|
|
||||||
The advantage of using v4l2_subdev is that it is a generic struct and does
|
The advantage of using v4l2_subdev is that it is a generic struct and does
|
||||||
not contain any knowledge about the underlying hardware. So a driver might
|
not contain any knowledge about the underlying hardware. So a driver might
|
||||||
contain several subdevs that use an I2C bus, but also a subdev that is
|
contain several subdevs that use an I2C bus, but also a subdev that is
|
||||||
|
@ -340,6 +366,12 @@ Make sure to call v4l2_device_unregister_subdev(sd) when the remove() callback
|
||||||
is called. This will unregister the sub-device from the bridge driver. It is
|
is called. This will unregister the sub-device from the bridge driver. It is
|
||||||
safe to call this even if the sub-device was never registered.
|
safe to call this even if the sub-device was never registered.
|
||||||
|
|
||||||
|
You need to do this because when the bridge driver destroys the i2c adapter
|
||||||
|
the remove() callbacks are called of the i2c devices on that adapter.
|
||||||
|
After that the corresponding v4l2_subdev structures are invalid, so they
|
||||||
|
have to be unregistered first. Calling v4l2_device_unregister_subdev(sd)
|
||||||
|
from the remove() callback ensures that this is always done correctly.
|
||||||
|
|
||||||
|
|
||||||
The bridge driver also has some helper functions it can use:
|
The bridge driver also has some helper functions it can use:
|
||||||
|
|
||||||
|
@ -349,8 +381,8 @@ This loads the given module (can be NULL if no module needs to be loaded) and
|
||||||
calls i2c_new_device() with the given i2c_adapter and chip/address arguments.
|
calls i2c_new_device() with the given i2c_adapter and chip/address arguments.
|
||||||
If all goes well, then it registers the subdev with the v4l2_device. It gets
|
If all goes well, then it registers the subdev with the v4l2_device. It gets
|
||||||
the v4l2_device by calling i2c_get_adapdata(adapter), so you should make sure
|
the v4l2_device by calling i2c_get_adapdata(adapter), so you should make sure
|
||||||
that adapdata is set to v4l2_device when you setup the i2c_adapter in your
|
to call i2c_set_adapdata(adapter, v4l2_device) when you setup the i2c_adapter
|
||||||
driver.
|
in your driver.
|
||||||
|
|
||||||
You can also use v4l2_i2c_new_probed_subdev() which is very similar to
|
You can also use v4l2_i2c_new_probed_subdev() which is very similar to
|
||||||
v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses
|
v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses
|
||||||
|
@ -358,6 +390,14 @@ that it should probe. Internally it calls i2c_new_probed_device().
|
||||||
|
|
||||||
Both functions return NULL if something went wrong.
|
Both functions return NULL if something went wrong.
|
||||||
|
|
||||||
|
Note that the chipid you pass to v4l2_i2c_new_(probed_)subdev() is usually
|
||||||
|
the same as the module name. It allows you to specify a chip variant, e.g.
|
||||||
|
"saa7114" or "saa7115". In general though the i2c driver autodetects this.
|
||||||
|
The use of chipid is something that needs to be looked at more closely at a
|
||||||
|
later date. It differs between i2c drivers and as such can be confusing.
|
||||||
|
To see which chip variants are supported you can look in the i2c driver code
|
||||||
|
for the i2c_device_id table. This lists all the possibilities.
|
||||||
|
|
||||||
|
|
||||||
struct video_device
|
struct video_device
|
||||||
-------------------
|
-------------------
|
||||||
|
@ -396,6 +436,15 @@ You should also set these fields:
|
||||||
- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
|
- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
|
||||||
(highly recommended to use this and it might become compulsory in the
|
(highly recommended to use this and it might become compulsory in the
|
||||||
future!), then set this to your v4l2_ioctl_ops struct.
|
future!), then set this to your v4l2_ioctl_ops struct.
|
||||||
|
- parent: you only set this if v4l2_device was registered with NULL as
|
||||||
|
the parent device struct. This only happens in cases where one hardware
|
||||||
|
device has multiple PCI devices that all share the same v4l2_device core.
|
||||||
|
|
||||||
|
The cx88 driver is an example of this: one core v4l2_device struct, but
|
||||||
|
it is used by both an raw video PCI device (cx8800) and a MPEG PCI device
|
||||||
|
(cx8802). Since the v4l2_device cannot be associated with a particular
|
||||||
|
PCI device it is setup without a parent device. But when the struct
|
||||||
|
video_device is setup you do know which parent PCI device to use.
|
||||||
|
|
||||||
If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or
|
If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or
|
||||||
.ioctl to video_ioctl2 in your v4l2_file_operations struct.
|
.ioctl to video_ioctl2 in your v4l2_file_operations struct.
|
||||||
|
@ -499,8 +548,8 @@ There are a few useful helper functions:
|
||||||
|
|
||||||
You can set/get driver private data in the video_device struct using:
|
You can set/get driver private data in the video_device struct using:
|
||||||
|
|
||||||
void *video_get_drvdata(struct video_device *dev);
|
void *video_get_drvdata(struct video_device *vdev);
|
||||||
void video_set_drvdata(struct video_device *dev, void *data);
|
void video_set_drvdata(struct video_device *vdev, void *data);
|
||||||
|
|
||||||
Note that you can safely call video_set_drvdata() before calling
|
Note that you can safely call video_set_drvdata() before calling
|
||||||
video_register_device().
|
video_register_device().
|
||||||
|
@ -519,3 +568,103 @@ void *video_drvdata(struct file *file);
|
||||||
You can go from a video_device struct to the v4l2_device struct using:
|
You can go from a video_device struct to the v4l2_device struct using:
|
||||||
|
|
||||||
struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
|
struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
|
||||||
|
|
||||||
|
video buffer helper functions
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
The v4l2 core API provides a standard method for dealing with video
|
||||||
|
buffers. Those methods allow a driver to implement read(), mmap() and
|
||||||
|
overlay() on a consistent way.
|
||||||
|
|
||||||
|
There are currently methods for using video buffers on devices that
|
||||||
|
supports DMA with scatter/gather method (videobuf-dma-sg), DMA with
|
||||||
|
linear access (videobuf-dma-contig), and vmalloced buffers, mostly
|
||||||
|
used on USB drivers (videobuf-vmalloc).
|
||||||
|
|
||||||
|
Any driver using videobuf should provide operations (callbacks) for
|
||||||
|
four handlers:
|
||||||
|
|
||||||
|
ops->buf_setup - calculates the size of the video buffers and avoid they
|
||||||
|
to waste more than some maximum limit of RAM;
|
||||||
|
ops->buf_prepare - fills the video buffer structs and calls
|
||||||
|
videobuf_iolock() to alloc and prepare mmaped memory;
|
||||||
|
ops->buf_queue - advices the driver that another buffer were
|
||||||
|
requested (by read() or by QBUF);
|
||||||
|
ops->buf_release - frees any buffer that were allocated.
|
||||||
|
|
||||||
|
In order to use it, the driver need to have a code (generally called at
|
||||||
|
interrupt context) that will properly handle the buffer request lists,
|
||||||
|
announcing that a new buffer were filled.
|
||||||
|
|
||||||
|
The irq handling code should handle the videobuf task lists, in order
|
||||||
|
to advice videobuf that a new frame were filled, in order to honor to a
|
||||||
|
request. The code is generally like this one:
|
||||||
|
if (list_empty(&dma_q->active))
|
||||||
|
return;
|
||||||
|
|
||||||
|
buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue);
|
||||||
|
|
||||||
|
if (!waitqueue_active(&buf->vb.done))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Some logic to handle the buf may be needed here */
|
||||||
|
|
||||||
|
list_del(&buf->vb.queue);
|
||||||
|
do_gettimeofday(&buf->vb.ts);
|
||||||
|
wake_up(&buf->vb.done);
|
||||||
|
|
||||||
|
Those are the videobuffer functions used on drivers, implemented on
|
||||||
|
videobuf-core:
|
||||||
|
|
||||||
|
- Videobuf init functions
|
||||||
|
videobuf_queue_sg_init()
|
||||||
|
Initializes the videobuf infrastructure. This function should be
|
||||||
|
called before any other videobuf function on drivers that uses DMA
|
||||||
|
Scatter/Gather buffers.
|
||||||
|
|
||||||
|
videobuf_queue_dma_contig_init
|
||||||
|
Initializes the videobuf infrastructure. This function should be
|
||||||
|
called before any other videobuf function on drivers that need DMA
|
||||||
|
contiguous buffers.
|
||||||
|
|
||||||
|
videobuf_queue_vmalloc_init()
|
||||||
|
Initializes the videobuf infrastructure. This function should be
|
||||||
|
called before any other videobuf function on USB (and other drivers)
|
||||||
|
that need a vmalloced type of videobuf.
|
||||||
|
|
||||||
|
- videobuf_iolock()
|
||||||
|
Prepares the videobuf memory for the proper method (read, mmap, overlay).
|
||||||
|
|
||||||
|
- videobuf_queue_is_busy()
|
||||||
|
Checks if a videobuf is streaming.
|
||||||
|
|
||||||
|
- videobuf_queue_cancel()
|
||||||
|
Stops video handling.
|
||||||
|
|
||||||
|
- videobuf_mmap_free()
|
||||||
|
frees mmap buffers.
|
||||||
|
|
||||||
|
- videobuf_stop()
|
||||||
|
Stops video handling, ends mmap and frees mmap and other buffers.
|
||||||
|
|
||||||
|
- V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls:
|
||||||
|
videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(),
|
||||||
|
videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff().
|
||||||
|
|
||||||
|
- V4L1 api function (corresponds to VIDIOCMBUF ioctl):
|
||||||
|
videobuf_cgmbuf()
|
||||||
|
This function is used to provide backward compatibility with V4L1
|
||||||
|
API.
|
||||||
|
|
||||||
|
- Some help functions for read()/poll() operations:
|
||||||
|
videobuf_read_stream()
|
||||||
|
For continuous stream read()
|
||||||
|
videobuf_read_one()
|
||||||
|
For snapshot read()
|
||||||
|
videobuf_poll_stream()
|
||||||
|
polling help function
|
||||||
|
|
||||||
|
The better way to understand it is to take a look at vivi driver. One
|
||||||
|
of the main reasons for vivi is to be a videobuf usage example. the
|
||||||
|
vivi_thread_tick() does the task that the IRQ callback would do on PCI
|
||||||
|
drivers (or the irq callback on USB).
|
||||||
|
|
|
@ -105,8 +105,8 @@ int main(int argc, char ** argv)
|
||||||
struct video_picture vpic;
|
struct video_picture vpic;
|
||||||
|
|
||||||
unsigned char *buffer, *src;
|
unsigned char *buffer, *src;
|
||||||
int bpp = 24, r, g, b;
|
int bpp = 24, r = 0, g = 0, b = 0;
|
||||||
unsigned int i, src_depth;
|
unsigned int i, src_depth = 16;
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
perror(VIDEO_DEV);
|
perror(VIDEO_DEV);
|
||||||
|
|
|
@ -65,3 +65,4 @@ Vendor Product Distributor Model
|
||||||
0x06d6 0x003b Trust Powerc@m 970Z
|
0x06d6 0x003b Trust Powerc@m 970Z
|
||||||
0x0a17 0x004e Pentax Optio 50
|
0x0a17 0x004e Pentax Optio 50
|
||||||
0x041e 0x405d Creative DiVi CAM 516
|
0x041e 0x405d Creative DiVi CAM 516
|
||||||
|
0x08ca 0x2102 Aiptek DV T300
|
||||||
|
|
113
MAINTAINERS
113
MAINTAINERS
|
@ -357,6 +357,7 @@ S: Odd Fixes for 2.4; Maintained for 2.6.
|
||||||
P: Ivan Kokshaysky
|
P: Ivan Kokshaysky
|
||||||
M: ink@jurassic.park.msu.ru
|
M: ink@jurassic.park.msu.ru
|
||||||
S: Maintained for 2.4; PCI support for 2.6.
|
S: Maintained for 2.4; PCI support for 2.6.
|
||||||
|
L: linux-alpha@vger.kernel.org
|
||||||
|
|
||||||
AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
|
AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
|
||||||
P: Thomas Dahlmann
|
P: Thomas Dahlmann
|
||||||
|
@ -502,6 +503,13 @@ P: Richard Purdie
|
||||||
M: rpurdie@rpsys.net
|
M: rpurdie@rpsys.net
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
|
||||||
|
P: Paulius Zaleckas
|
||||||
|
M: paulius.zaleckas@teltonika.lt
|
||||||
|
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||||
|
T: git gitorious.org/linux-gemini/mainline.git
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
|
ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
|
||||||
P: Daniel Ribeiro
|
P: Daniel Ribeiro
|
||||||
M: drwyrm@gmail.com
|
M: drwyrm@gmail.com
|
||||||
|
@ -513,6 +521,12 @@ L: openezx-devel@lists.openezx.org (subscribers-only)
|
||||||
W: http://www.openezx.org/
|
W: http://www.openezx.org/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
ARM/FARADAY FA526 PORT
|
||||||
|
P: Paulius Zaleckas
|
||||||
|
M: paulius.zaleckas@teltonika.lt
|
||||||
|
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
|
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
|
||||||
P: Sascha Hauer
|
P: Sascha Hauer
|
||||||
M: kernel@pengutronix.de
|
M: kernel@pengutronix.de
|
||||||
|
@ -622,7 +636,7 @@ P: Dirk Opfer
|
||||||
M: dirk@opfer-online.de
|
M: dirk@opfer-online.de
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
ARM/PALMTX SUPPORT
|
ARM/PALMTX,PALMT5,PALMLD SUPPORT
|
||||||
P: Marek Vasut
|
P: Marek Vasut
|
||||||
M: marek.vasut@gmail.com
|
M: marek.vasut@gmail.com
|
||||||
W: http://hackndev.com
|
W: http://hackndev.com
|
||||||
|
@ -765,6 +779,14 @@ L: linux-wireless@vger.kernel.org
|
||||||
L: ath9k-devel@lists.ath9k.org
|
L: ath9k-devel@lists.ath9k.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
|
ATHEROS AR9170 WIRELESS DRIVER
|
||||||
|
P: Christian Lamparter
|
||||||
|
M: chunkeey@web.de
|
||||||
|
L: linux-wireless@vger.kernel.org
|
||||||
|
W: http://wireless.kernel.org/en/users/Drivers/ar9170
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/net/wireless/ar9170/
|
||||||
|
|
||||||
ATI_REMOTE2 DRIVER
|
ATI_REMOTE2 DRIVER
|
||||||
P: Ville Syrjala
|
P: Ville Syrjala
|
||||||
M: syrjala@sci.fi
|
M: syrjala@sci.fi
|
||||||
|
@ -1011,6 +1033,8 @@ L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
BROADCOM TG3 GIGABIT ETHERNET DRIVER
|
BROADCOM TG3 GIGABIT ETHERNET DRIVER
|
||||||
|
P: Matt Carlson
|
||||||
|
M: mcarlson@broadcom.com
|
||||||
P: Michael Chan
|
P: Michael Chan
|
||||||
M: mchan@broadcom.com
|
M: mchan@broadcom.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
|
@ -1040,7 +1064,6 @@ BTTV VIDEO4LINUX DRIVER
|
||||||
P: Mauro Carvalho Chehab
|
P: Mauro Carvalho Chehab
|
||||||
M: mchehab@infradead.org
|
M: mchehab@infradead.org
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
L: video4linux-list@redhat.com
|
|
||||||
W: http://linuxtv.org
|
W: http://linuxtv.org
|
||||||
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
|
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
@ -1269,6 +1292,12 @@ L: linux-crypto@vger.kernel.org
|
||||||
T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
|
T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
CRYPTOGRAPHIC RANDOM NUMBER GENERATOR
|
||||||
|
P: Neil Horman
|
||||||
|
M: nhorman@tuxdriver.com
|
||||||
|
L: linux-crypto@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
CS5535 Audio ALSA driver
|
CS5535 Audio ALSA driver
|
||||||
P: Jaya Kumar
|
P: Jaya Kumar
|
||||||
M: jayakumar.alsa@gmail.com
|
M: jayakumar.alsa@gmail.com
|
||||||
|
@ -2173,25 +2202,12 @@ L: linux-ide@vger.kernel.org
|
||||||
T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
|
T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
IDE/ATAPI CDROM DRIVER
|
IDE/ATAPI DRIVERS
|
||||||
P: Borislav Petkov
|
P: Borislav Petkov
|
||||||
M: petkovbb@gmail.com
|
M: petkovbb@gmail.com
|
||||||
L: linux-ide@vger.kernel.org
|
L: linux-ide@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
IDE/ATAPI FLOPPY DRIVERS
|
|
||||||
P: Paul Bristow
|
|
||||||
M: Paul Bristow <paul@paulbristow.net>
|
|
||||||
W: http://paulbristow.net/linux/idefloppy.html
|
|
||||||
L: linux-kernel@vger.kernel.org
|
|
||||||
S: Maintained
|
|
||||||
|
|
||||||
IDE/ATAPI TAPE DRIVERS
|
|
||||||
P: Gadi Oxman
|
|
||||||
M: Gadi Oxman <gadio@netvision.net.il>
|
|
||||||
L: linux-kernel@vger.kernel.org
|
|
||||||
S: Maintained
|
|
||||||
|
|
||||||
IDLE-I7300
|
IDLE-I7300
|
||||||
P: Andy Henroid
|
P: Andy Henroid
|
||||||
M: andrew.d.henroid@intel.com
|
M: andrew.d.henroid@intel.com
|
||||||
|
@ -2216,6 +2232,11 @@ M: stefanr@s5r6.in-berlin.de
|
||||||
L: linux1394-devel@lists.sourceforge.net
|
L: linux1394-devel@lists.sourceforge.net
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
|
||||||
|
P: Mimi Zohar
|
||||||
|
M: zohar@us.ibm.com
|
||||||
|
S: Supported
|
||||||
|
|
||||||
IMS TWINTURBO FRAMEBUFFER DRIVER
|
IMS TWINTURBO FRAMEBUFFER DRIVER
|
||||||
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
|
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||||
S: Orphan
|
S: Orphan
|
||||||
|
@ -2832,7 +2853,7 @@ P: Roman Zippel
|
||||||
M: zippel@linux-m68k.org
|
M: zippel@linux-m68k.org
|
||||||
L: linux-m68k@lists.linux-m68k.org
|
L: linux-m68k@lists.linux-m68k.org
|
||||||
W: http://www.linux-m68k.org/
|
W: http://www.linux-m68k.org/
|
||||||
W: http://linux-m68k-cvs.ubb.ca/
|
T: git git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
M68K ON APPLE MACINTOSH
|
M68K ON APPLE MACINTOSH
|
||||||
|
@ -3289,6 +3310,16 @@ L: orinoco-devel@lists.sourceforge.net
|
||||||
W: http://www.nongnu.org/orinoco/
|
W: http://www.nongnu.org/orinoco/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
OSD LIBRARY
|
||||||
|
P: Boaz Harrosh
|
||||||
|
M: bharrosh@panasas.com
|
||||||
|
P: Benny Halevy
|
||||||
|
M: bhalevy@panasas.com
|
||||||
|
L: osd-dev@open-osd.org
|
||||||
|
W: http://open-osd.org
|
||||||
|
T: git://git.open-osd.org/open-osd.git
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
P54 WIRELESS DRIVER
|
P54 WIRELESS DRIVER
|
||||||
P: Michael Wu
|
P: Michael Wu
|
||||||
M: flamingice@sourmilk.net
|
M: flamingice@sourmilk.net
|
||||||
|
@ -3539,6 +3570,22 @@ M: linux@arm.linux.org.uk
|
||||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
PXA168 SUPPORT
|
||||||
|
P: Eric Miao
|
||||||
|
M: eric.miao@marvell.com
|
||||||
|
P: Jason Chagas
|
||||||
|
M: jason.chagas@marvell.com
|
||||||
|
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||||
|
T: git kernel.org:/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
|
||||||
|
S: Supported
|
||||||
|
|
||||||
|
PXA910 SUPPORT
|
||||||
|
P: Eric Miao
|
||||||
|
M: eric.miao@marvell.com
|
||||||
|
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||||
|
T: git kernel.org:/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
|
||||||
|
S: Supported
|
||||||
|
|
||||||
PXA MMCI DRIVER
|
PXA MMCI DRIVER
|
||||||
S: Orphan
|
S: Orphan
|
||||||
|
|
||||||
|
@ -3589,7 +3636,7 @@ S: Maintained
|
||||||
RALINK RT2X00 WIRELESS LAN DRIVER
|
RALINK RT2X00 WIRELESS LAN DRIVER
|
||||||
P: rt2x00 project
|
P: rt2x00 project
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
L: rt2400-devel@lists.sourceforge.net
|
L: users@rt2x00.serialmonkey.com
|
||||||
W: http://rt2x00.serialmonkey.com/
|
W: http://rt2x00.serialmonkey.com/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git kernel.org:/pub/scm/linux/kernel/git/ivd/rt2x00.git
|
T: git kernel.org:/pub/scm/linux/kernel/git/ivd/rt2x00.git
|
||||||
|
@ -3635,6 +3682,12 @@ M: florian.fainelli@telecomint.eu
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
RDS - RELIABLE DATAGRAM SOCKETS
|
||||||
|
P: Andy Grover
|
||||||
|
M: andy.grover@oracle.com
|
||||||
|
L: rds-devel@oss.oracle.com
|
||||||
|
S: Supported
|
||||||
|
|
||||||
READ-COPY UPDATE (RCU)
|
READ-COPY UPDATE (RCU)
|
||||||
P: Dipankar Sarma
|
P: Dipankar Sarma
|
||||||
M: dipankar@in.ibm.com
|
M: dipankar@in.ibm.com
|
||||||
|
@ -3726,6 +3779,15 @@ L: linux-s390@vger.kernel.org
|
||||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
|
S390 ZCRYPT DRIVER
|
||||||
|
P: Felix Beck
|
||||||
|
M: felix.beck@de.ibm.com
|
||||||
|
P: Ralph Wuerthner
|
||||||
|
M: ralph.wuerthner@de.ibm.com
|
||||||
|
M: linux390@de.ibm.com
|
||||||
|
L: linux-s390@vger.kernel.org
|
||||||
|
S: Supported
|
||||||
|
|
||||||
S390 ZFCP DRIVER
|
S390 ZFCP DRIVER
|
||||||
P: Christof Schmitt
|
P: Christof Schmitt
|
||||||
M: christof.schmitt@de.ibm.com
|
M: christof.schmitt@de.ibm.com
|
||||||
|
@ -3844,6 +3906,7 @@ M: jmorris@namei.org
|
||||||
L: linux-kernel@vger.kernel.org
|
L: linux-kernel@vger.kernel.org
|
||||||
L: linux-security-module@vger.kernel.org (suggested Cc:)
|
L: linux-security-module@vger.kernel.org (suggested Cc:)
|
||||||
T: git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
|
T: git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
|
||||||
|
W: http://security.wiki.kernel.org/
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
SECURITY CONTACT
|
SECURITY CONTACT
|
||||||
|
@ -4285,6 +4348,19 @@ L: tlan-devel@lists.sourceforge.net (subscribers-only)
|
||||||
W: http://sourceforge.net/projects/tlan/
|
W: http://sourceforge.net/projects/tlan/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
TOMOYO SECURITY MODULE
|
||||||
|
P: Kentaro Takeda
|
||||||
|
M: takedakn@nttdata.co.jp
|
||||||
|
P: Tetsuo Handa
|
||||||
|
M: penguin-kernel@I-love.SAKURA.ne.jp
|
||||||
|
L: linux-kernel@vger.kernel.org (kernel issues)
|
||||||
|
L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English)
|
||||||
|
L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese)
|
||||||
|
L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
|
||||||
|
W: http://tomoyo.sourceforge.jp/
|
||||||
|
T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches/
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
TOSHIBA ACPI EXTRAS DRIVER
|
TOSHIBA ACPI EXTRAS DRIVER
|
||||||
P: John Belmonte
|
P: John Belmonte
|
||||||
M: toshiba_acpi@memebeam.org
|
M: toshiba_acpi@memebeam.org
|
||||||
|
@ -4746,7 +4822,6 @@ VIDEO FOR LINUX (V4L)
|
||||||
P: Mauro Carvalho Chehab
|
P: Mauro Carvalho Chehab
|
||||||
M: mchehab@infradead.org
|
M: mchehab@infradead.org
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
L: video4linux-list@redhat.com
|
|
||||||
W: http://linuxtv.org
|
W: http://linuxtv.org
|
||||||
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
|
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
|
@ -106,3 +106,5 @@ config HAVE_CLK
|
||||||
The <linux/clk.h> calls support software clock gating and
|
The <linux/clk.h> calls support software clock gating and
|
||||||
thus are a key power management tool on many systems.
|
thus are a key power management tool on many systems.
|
||||||
|
|
||||||
|
config HAVE_DMA_API_DEBUG
|
||||||
|
bool
|
||||||
|
|
|
@ -80,7 +80,7 @@ struct alpha_machine_vector
|
||||||
void (*update_irq_hw)(unsigned long, unsigned long, int);
|
void (*update_irq_hw)(unsigned long, unsigned long, int);
|
||||||
void (*ack_irq)(unsigned long);
|
void (*ack_irq)(unsigned long);
|
||||||
void (*device_interrupt)(unsigned long vector);
|
void (*device_interrupt)(unsigned long vector);
|
||||||
void (*machine_check)(u64 vector, u64 la);
|
void (*machine_check)(unsigned long vector, unsigned long la);
|
||||||
|
|
||||||
void (*smp_callin)(void);
|
void (*smp_callin)(void);
|
||||||
void (*init_arch)(void);
|
void (*init_arch)(void);
|
||||||
|
|
|
@ -273,4 +273,18 @@ struct pci_dev *alpha_gendev_to_pci(struct device *dev);
|
||||||
|
|
||||||
extern struct pci_dev *isa_bridge;
|
extern struct pci_dev *isa_bridge;
|
||||||
|
|
||||||
|
extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
|
||||||
|
size_t count);
|
||||||
|
extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
|
||||||
|
size_t count);
|
||||||
|
extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
|
||||||
|
struct vm_area_struct *vma,
|
||||||
|
enum pci_mmap_state mmap_state);
|
||||||
|
extern void pci_adjust_legacy_attr(struct pci_bus *bus,
|
||||||
|
enum pci_mmap_state mmap_type);
|
||||||
|
#define HAVE_PCI_LEGACY 1
|
||||||
|
|
||||||
|
extern int pci_create_resource_files(struct pci_dev *dev);
|
||||||
|
extern void pci_remove_resource_files(struct pci_dev *dev);
|
||||||
|
|
||||||
#endif /* __ALPHA_PCI_H */
|
#endif /* __ALPHA_PCI_H */
|
||||||
|
|
|
@ -62,6 +62,9 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
||||||
* have to define SOCK_NONBLOCK to a different value here.
|
* have to define SOCK_NONBLOCK to a different value here.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -309,519 +309,72 @@ extern int __min_ipl;
|
||||||
#define tbia() __tbi(-2, /* no second argument */)
|
#define tbia() __tbi(-2, /* no second argument */)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Atomic exchange.
|
* Atomic exchange routines.
|
||||||
* Since it can be used to implement critical sections
|
|
||||||
* it must clobber "memory" (also for interrupts in UP).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline unsigned long
|
#define __ASM__MB
|
||||||
__xchg_u8(volatile char *m, unsigned long val)
|
#define ____xchg(type, args...) __xchg ## type ## _local(args)
|
||||||
{
|
#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args)
|
||||||
unsigned long ret, tmp, addr64;
|
#include <asm/xchg.h>
|
||||||
|
|
||||||
__asm__ __volatile__(
|
#define xchg_local(ptr,x) \
|
||||||
" andnot %4,7,%3\n"
|
({ \
|
||||||
" insbl %1,%4,%1\n"
|
__typeof__(*(ptr)) _x_ = (x); \
|
||||||
"1: ldq_l %2,0(%3)\n"
|
(__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
|
||||||
" extbl %2,%4,%0\n"
|
sizeof(*(ptr))); \
|
||||||
" mskbl %2,%4,%2\n"
|
|
||||||
" or %1,%2,%2\n"
|
|
||||||
" stq_c %2,0(%3)\n"
|
|
||||||
" beq %2,2f\n"
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" mb\n"
|
|
||||||
#endif
|
|
||||||
".subsection 2\n"
|
|
||||||
"2: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
|
|
||||||
: "r" ((long)m), "1" (val) : "memory");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__xchg_u16(volatile short *m, unsigned long val)
|
|
||||||
{
|
|
||||||
unsigned long ret, tmp, addr64;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
" andnot %4,7,%3\n"
|
|
||||||
" inswl %1,%4,%1\n"
|
|
||||||
"1: ldq_l %2,0(%3)\n"
|
|
||||||
" extwl %2,%4,%0\n"
|
|
||||||
" mskwl %2,%4,%2\n"
|
|
||||||
" or %1,%2,%2\n"
|
|
||||||
" stq_c %2,0(%3)\n"
|
|
||||||
" beq %2,2f\n"
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" mb\n"
|
|
||||||
#endif
|
|
||||||
".subsection 2\n"
|
|
||||||
"2: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
|
|
||||||
: "r" ((long)m), "1" (val) : "memory");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__xchg_u32(volatile int *m, unsigned long val)
|
|
||||||
{
|
|
||||||
unsigned long dummy;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldl_l %0,%4\n"
|
|
||||||
" bis $31,%3,%1\n"
|
|
||||||
" stl_c %1,%2\n"
|
|
||||||
" beq %1,2f\n"
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" mb\n"
|
|
||||||
#endif
|
|
||||||
".subsection 2\n"
|
|
||||||
"2: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (val), "=&r" (dummy), "=m" (*m)
|
|
||||||
: "rI" (val), "m" (*m) : "memory");
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__xchg_u64(volatile long *m, unsigned long val)
|
|
||||||
{
|
|
||||||
unsigned long dummy;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldq_l %0,%4\n"
|
|
||||||
" bis $31,%3,%1\n"
|
|
||||||
" stq_c %1,%2\n"
|
|
||||||
" beq %1,2f\n"
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" mb\n"
|
|
||||||
#endif
|
|
||||||
".subsection 2\n"
|
|
||||||
"2: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (val), "=&r" (dummy), "=m" (*m)
|
|
||||||
: "rI" (val), "m" (*m) : "memory");
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function doesn't exist, so you'll get a linker error
|
|
||||||
if something tries to do an invalid xchg(). */
|
|
||||||
extern void __xchg_called_with_bad_pointer(void);
|
|
||||||
|
|
||||||
#define __xchg(ptr, x, size) \
|
|
||||||
({ \
|
|
||||||
unsigned long __xchg__res; \
|
|
||||||
volatile void *__xchg__ptr = (ptr); \
|
|
||||||
switch (size) { \
|
|
||||||
case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \
|
|
||||||
case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \
|
|
||||||
case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \
|
|
||||||
case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \
|
|
||||||
default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
|
|
||||||
} \
|
|
||||||
__xchg__res; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define xchg(ptr,x) \
|
|
||||||
({ \
|
|
||||||
__typeof__(*(ptr)) _x_ = (x); \
|
|
||||||
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
static inline unsigned long
|
#define cmpxchg_local(ptr, o, n) \
|
||||||
__xchg_u8_local(volatile char *m, unsigned long val)
|
({ \
|
||||||
{
|
__typeof__(*(ptr)) _o_ = (o); \
|
||||||
unsigned long ret, tmp, addr64;
|
__typeof__(*(ptr)) _n_ = (n); \
|
||||||
|
(__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
|
||||||
__asm__ __volatile__(
|
(unsigned long)_n_, \
|
||||||
" andnot %4,7,%3\n"
|
sizeof(*(ptr))); \
|
||||||
" insbl %1,%4,%1\n"
|
|
||||||
"1: ldq_l %2,0(%3)\n"
|
|
||||||
" extbl %2,%4,%0\n"
|
|
||||||
" mskbl %2,%4,%2\n"
|
|
||||||
" or %1,%2,%2\n"
|
|
||||||
" stq_c %2,0(%3)\n"
|
|
||||||
" beq %2,2f\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"2: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
|
|
||||||
: "r" ((long)m), "1" (val) : "memory");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__xchg_u16_local(volatile short *m, unsigned long val)
|
|
||||||
{
|
|
||||||
unsigned long ret, tmp, addr64;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
" andnot %4,7,%3\n"
|
|
||||||
" inswl %1,%4,%1\n"
|
|
||||||
"1: ldq_l %2,0(%3)\n"
|
|
||||||
" extwl %2,%4,%0\n"
|
|
||||||
" mskwl %2,%4,%2\n"
|
|
||||||
" or %1,%2,%2\n"
|
|
||||||
" stq_c %2,0(%3)\n"
|
|
||||||
" beq %2,2f\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"2: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
|
|
||||||
: "r" ((long)m), "1" (val) : "memory");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__xchg_u32_local(volatile int *m, unsigned long val)
|
|
||||||
{
|
|
||||||
unsigned long dummy;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldl_l %0,%4\n"
|
|
||||||
" bis $31,%3,%1\n"
|
|
||||||
" stl_c %1,%2\n"
|
|
||||||
" beq %1,2f\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"2: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (val), "=&r" (dummy), "=m" (*m)
|
|
||||||
: "rI" (val), "m" (*m) : "memory");
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__xchg_u64_local(volatile long *m, unsigned long val)
|
|
||||||
{
|
|
||||||
unsigned long dummy;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldq_l %0,%4\n"
|
|
||||||
" bis $31,%3,%1\n"
|
|
||||||
" stq_c %1,%2\n"
|
|
||||||
" beq %1,2f\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"2: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (val), "=&r" (dummy), "=m" (*m)
|
|
||||||
: "rI" (val), "m" (*m) : "memory");
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __xchg_local(ptr, x, size) \
|
|
||||||
({ \
|
|
||||||
unsigned long __xchg__res; \
|
|
||||||
volatile void *__xchg__ptr = (ptr); \
|
|
||||||
switch (size) { \
|
|
||||||
case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \
|
|
||||||
case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \
|
|
||||||
case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \
|
|
||||||
case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \
|
|
||||||
default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
|
|
||||||
} \
|
|
||||||
__xchg__res; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define xchg_local(ptr,x) \
|
|
||||||
({ \
|
|
||||||
__typeof__(*(ptr)) _x_ = (x); \
|
|
||||||
(__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
|
|
||||||
sizeof(*(ptr))); \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
#define cmpxchg64_local(ptr, o, n) \
|
||||||
* Atomic compare and exchange. Compare OLD with MEM, if identical,
|
({ \
|
||||||
* store NEW in MEM. Return the initial value in MEM. Success is
|
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
|
||||||
* indicated by comparing RETURN with OLD.
|
cmpxchg_local((ptr), (o), (n)); \
|
||||||
*
|
})
|
||||||
* The memory barrier should be placed in SMP only when we actually
|
|
||||||
* make the change. If we don't change anything (so if the returned
|
#ifdef CONFIG_SMP
|
||||||
* prev is equal to old) then we aren't acquiring anything new and
|
#undef __ASM__MB
|
||||||
* we don't need any memory barrier as far I can tell.
|
#define __ASM__MB "\tmb\n"
|
||||||
*/
|
#endif
|
||||||
|
#undef ____xchg
|
||||||
|
#undef ____cmpxchg
|
||||||
|
#define ____xchg(type, args...) __xchg ##type(args)
|
||||||
|
#define ____cmpxchg(type, args...) __cmpxchg ##type(args)
|
||||||
|
#include <asm/xchg.h>
|
||||||
|
|
||||||
|
#define xchg(ptr,x) \
|
||||||
|
({ \
|
||||||
|
__typeof__(*(ptr)) _x_ = (x); \
|
||||||
|
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \
|
||||||
|
sizeof(*(ptr))); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define cmpxchg(ptr, o, n) \
|
||||||
|
({ \
|
||||||
|
__typeof__(*(ptr)) _o_ = (o); \
|
||||||
|
__typeof__(*(ptr)) _n_ = (n); \
|
||||||
|
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
|
||||||
|
(unsigned long)_n_, sizeof(*(ptr)));\
|
||||||
|
})
|
||||||
|
|
||||||
|
#define cmpxchg64(ptr, o, n) \
|
||||||
|
({ \
|
||||||
|
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
|
||||||
|
cmpxchg((ptr), (o), (n)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#undef __ASM__MB
|
||||||
|
#undef ____cmpxchg
|
||||||
|
|
||||||
#define __HAVE_ARCH_CMPXCHG 1
|
#define __HAVE_ARCH_CMPXCHG 1
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__cmpxchg_u8(volatile char *m, long old, long new)
|
|
||||||
{
|
|
||||||
unsigned long prev, tmp, cmp, addr64;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
" andnot %5,7,%4\n"
|
|
||||||
" insbl %1,%5,%1\n"
|
|
||||||
"1: ldq_l %2,0(%4)\n"
|
|
||||||
" extbl %2,%5,%0\n"
|
|
||||||
" cmpeq %0,%6,%3\n"
|
|
||||||
" beq %3,2f\n"
|
|
||||||
" mskbl %2,%5,%2\n"
|
|
||||||
" or %1,%2,%2\n"
|
|
||||||
" stq_c %2,0(%4)\n"
|
|
||||||
" beq %2,3f\n"
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" mb\n"
|
|
||||||
#endif
|
|
||||||
"2:\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"3: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
|
|
||||||
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__cmpxchg_u16(volatile short *m, long old, long new)
|
|
||||||
{
|
|
||||||
unsigned long prev, tmp, cmp, addr64;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
" andnot %5,7,%4\n"
|
|
||||||
" inswl %1,%5,%1\n"
|
|
||||||
"1: ldq_l %2,0(%4)\n"
|
|
||||||
" extwl %2,%5,%0\n"
|
|
||||||
" cmpeq %0,%6,%3\n"
|
|
||||||
" beq %3,2f\n"
|
|
||||||
" mskwl %2,%5,%2\n"
|
|
||||||
" or %1,%2,%2\n"
|
|
||||||
" stq_c %2,0(%4)\n"
|
|
||||||
" beq %2,3f\n"
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" mb\n"
|
|
||||||
#endif
|
|
||||||
"2:\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"3: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
|
|
||||||
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__cmpxchg_u32(volatile int *m, int old, int new)
|
|
||||||
{
|
|
||||||
unsigned long prev, cmp;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldl_l %0,%5\n"
|
|
||||||
" cmpeq %0,%3,%1\n"
|
|
||||||
" beq %1,2f\n"
|
|
||||||
" mov %4,%1\n"
|
|
||||||
" stl_c %1,%2\n"
|
|
||||||
" beq %1,3f\n"
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" mb\n"
|
|
||||||
#endif
|
|
||||||
"2:\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"3: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
|
|
||||||
: "r"((long) old), "r"(new), "m"(*m) : "memory");
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
|
|
||||||
{
|
|
||||||
unsigned long prev, cmp;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldq_l %0,%5\n"
|
|
||||||
" cmpeq %0,%3,%1\n"
|
|
||||||
" beq %1,2f\n"
|
|
||||||
" mov %4,%1\n"
|
|
||||||
" stq_c %1,%2\n"
|
|
||||||
" beq %1,3f\n"
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
" mb\n"
|
|
||||||
#endif
|
|
||||||
"2:\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"3: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
|
|
||||||
: "r"((long) old), "r"(new), "m"(*m) : "memory");
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function doesn't exist, so you'll get a linker error
|
|
||||||
if something tries to do an invalid cmpxchg(). */
|
|
||||||
extern void __cmpxchg_called_with_bad_pointer(void);
|
|
||||||
|
|
||||||
static __always_inline unsigned long
|
|
||||||
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
|
||||||
{
|
|
||||||
switch (size) {
|
|
||||||
case 1:
|
|
||||||
return __cmpxchg_u8(ptr, old, new);
|
|
||||||
case 2:
|
|
||||||
return __cmpxchg_u16(ptr, old, new);
|
|
||||||
case 4:
|
|
||||||
return __cmpxchg_u32(ptr, old, new);
|
|
||||||
case 8:
|
|
||||||
return __cmpxchg_u64(ptr, old, new);
|
|
||||||
}
|
|
||||||
__cmpxchg_called_with_bad_pointer();
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define cmpxchg(ptr, o, n) \
|
|
||||||
({ \
|
|
||||||
__typeof__(*(ptr)) _o_ = (o); \
|
|
||||||
__typeof__(*(ptr)) _n_ = (n); \
|
|
||||||
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
|
|
||||||
(unsigned long)_n_, sizeof(*(ptr))); \
|
|
||||||
})
|
|
||||||
#define cmpxchg64(ptr, o, n) \
|
|
||||||
({ \
|
|
||||||
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
|
|
||||||
cmpxchg((ptr), (o), (n)); \
|
|
||||||
})
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__cmpxchg_u8_local(volatile char *m, long old, long new)
|
|
||||||
{
|
|
||||||
unsigned long prev, tmp, cmp, addr64;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
" andnot %5,7,%4\n"
|
|
||||||
" insbl %1,%5,%1\n"
|
|
||||||
"1: ldq_l %2,0(%4)\n"
|
|
||||||
" extbl %2,%5,%0\n"
|
|
||||||
" cmpeq %0,%6,%3\n"
|
|
||||||
" beq %3,2f\n"
|
|
||||||
" mskbl %2,%5,%2\n"
|
|
||||||
" or %1,%2,%2\n"
|
|
||||||
" stq_c %2,0(%4)\n"
|
|
||||||
" beq %2,3f\n"
|
|
||||||
"2:\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"3: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
|
|
||||||
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__cmpxchg_u16_local(volatile short *m, long old, long new)
|
|
||||||
{
|
|
||||||
unsigned long prev, tmp, cmp, addr64;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
" andnot %5,7,%4\n"
|
|
||||||
" inswl %1,%5,%1\n"
|
|
||||||
"1: ldq_l %2,0(%4)\n"
|
|
||||||
" extwl %2,%5,%0\n"
|
|
||||||
" cmpeq %0,%6,%3\n"
|
|
||||||
" beq %3,2f\n"
|
|
||||||
" mskwl %2,%5,%2\n"
|
|
||||||
" or %1,%2,%2\n"
|
|
||||||
" stq_c %2,0(%4)\n"
|
|
||||||
" beq %2,3f\n"
|
|
||||||
"2:\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"3: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
|
|
||||||
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__cmpxchg_u32_local(volatile int *m, int old, int new)
|
|
||||||
{
|
|
||||||
unsigned long prev, cmp;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldl_l %0,%5\n"
|
|
||||||
" cmpeq %0,%3,%1\n"
|
|
||||||
" beq %1,2f\n"
|
|
||||||
" mov %4,%1\n"
|
|
||||||
" stl_c %1,%2\n"
|
|
||||||
" beq %1,3f\n"
|
|
||||||
"2:\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"3: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
|
|
||||||
: "r"((long) old), "r"(new), "m"(*m) : "memory");
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new)
|
|
||||||
{
|
|
||||||
unsigned long prev, cmp;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldq_l %0,%5\n"
|
|
||||||
" cmpeq %0,%3,%1\n"
|
|
||||||
" beq %1,2f\n"
|
|
||||||
" mov %4,%1\n"
|
|
||||||
" stq_c %1,%2\n"
|
|
||||||
" beq %1,3f\n"
|
|
||||||
"2:\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"3: br 1b\n"
|
|
||||||
".previous"
|
|
||||||
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
|
|
||||||
: "r"((long) old), "r"(new), "m"(*m) : "memory");
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __always_inline unsigned long
|
|
||||||
__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
|
|
||||||
int size)
|
|
||||||
{
|
|
||||||
switch (size) {
|
|
||||||
case 1:
|
|
||||||
return __cmpxchg_u8_local(ptr, old, new);
|
|
||||||
case 2:
|
|
||||||
return __cmpxchg_u16_local(ptr, old, new);
|
|
||||||
case 4:
|
|
||||||
return __cmpxchg_u32_local(ptr, old, new);
|
|
||||||
case 8:
|
|
||||||
return __cmpxchg_u64_local(ptr, old, new);
|
|
||||||
}
|
|
||||||
__cmpxchg_called_with_bad_pointer();
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define cmpxchg_local(ptr, o, n) \
|
|
||||||
({ \
|
|
||||||
__typeof__(*(ptr)) _o_ = (o); \
|
|
||||||
__typeof__(*(ptr)) _n_ = (n); \
|
|
||||||
(__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
|
|
||||||
(unsigned long)_n_, sizeof(*(ptr))); \
|
|
||||||
})
|
|
||||||
#define cmpxchg64_local(ptr, o, n) \
|
|
||||||
({ \
|
|
||||||
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
|
|
||||||
cmpxchg_local((ptr), (o), (n)); \
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#define arch_align_stack(x) (x)
|
#define arch_align_stack(x) (x)
|
||||||
|
|
|
@ -8,7 +8,12 @@
|
||||||
* not a major issue. However, for interoperability, libraries still
|
* not a major issue. However, for interoperability, libraries still
|
||||||
* need to be careful to avoid a name clashes.
|
* need to be careful to avoid a name clashes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
#include <asm-generic/int-ll64.h>
|
||||||
|
#else
|
||||||
#include <asm-generic/int-l64.h>
|
#include <asm-generic/int-l64.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue