mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 05:34:00 +08:00
Merge /pub/scm/linux/kernel/git/torvalds/linux-2.6
This commit is contained in:
commit
48a7afe314
2
.mailmap
2
.mailmap
@ -67,6 +67,8 @@ Koushik <raghavendra.koushik@neterion.com>
|
||||
Leonid I Ananiev <leonid.i.ananiev@intel.com>
|
||||
Linas Vepstas <linas@austin.ibm.com>
|
||||
Matthieu CASTET <castet.matthieu@free.fr>
|
||||
Michael Buesch <mb@bu3sch.de>
|
||||
Michael Buesch <mbuesch@freenet.de>
|
||||
Michel Dänzer <michel@tungstengraphics.com>
|
||||
Mitesh shah <mshah@teja.com>
|
||||
Morten Welinder <terra@gnome.org>
|
||||
|
22
CREDITS
22
CREDITS
@ -317,6 +317,12 @@ S: 2322 37th Ave SW
|
||||
S: Seattle, Washington 98126-2010
|
||||
S: USA
|
||||
|
||||
N: Johannes Berg
|
||||
E: johannes@sipsolutions.net
|
||||
W: http://johannes.sipsolutions.net/
|
||||
P: 1024D/9AB78CA5 AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5
|
||||
D: powerpc & 802.11 hacker
|
||||
|
||||
N: Stephen R. van den Berg (AKA BuGless)
|
||||
E: berg@pool.informatik.rwth-aachen.de
|
||||
D: General kernel, gcc, and libc hacker
|
||||
@ -2286,14 +2292,14 @@ S: D-90453 Nuernberg
|
||||
S: Germany
|
||||
|
||||
N: Arnaldo Carvalho de Melo
|
||||
E: acme@mandriva.com
|
||||
E: acme@ghostprotocols.net
|
||||
E: arnaldo.melo@gmail.com
|
||||
E: acme@redhat.com
|
||||
W: http://oops.ghostprotocols.net:81/blog/
|
||||
P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01
|
||||
D: IPX, LLC, DCCP, cyc2x, wl3501_cs, net/ hacks
|
||||
S: Mandriva
|
||||
S: R. Tocantins, 89 - Cristo Rei
|
||||
S: 80050-430 - Curitiba - Paraná
|
||||
S: R. Brasílio Itiberê, 4270/1010 - Água Verde
|
||||
S: 80240-060 - Curitiba - Paraná
|
||||
S: Brazil
|
||||
|
||||
N: Karsten Merker
|
||||
@ -3295,6 +3301,14 @@ S: 12725 SW Millikan Way, Suite 400
|
||||
S: Beaverton, Oregon 97005
|
||||
S: USA
|
||||
|
||||
N: Li Yang
|
||||
E: leoli@freescale.com
|
||||
D: Freescale Highspeed USB device driver
|
||||
D: Freescale QE SoC support and Ethernet driver
|
||||
S: B-1206 Jingmao Guojigongyu
|
||||
S: 16 Baliqiao Nanjie, Beijing 101100
|
||||
S: People's Repulic of China
|
||||
|
||||
N: Marcelo Tosatti
|
||||
E: marcelo@kvack.org
|
||||
D: v2.4 kernel maintainer
|
||||
|
9
Documentation/ABI/obsolete/dv1394
Normal file
9
Documentation/ABI/obsolete/dv1394
Normal file
@ -0,0 +1,9 @@
|
||||
What: dv1394 (a.k.a. "OHCI-DV I/O support" for FireWire)
|
||||
Contact: linux1394-devel@lists.sourceforge.net
|
||||
Description:
|
||||
New application development should use raw1394 + userspace libraries
|
||||
instead, notably libiec61883 which is functionally equivalent.
|
||||
|
||||
Users:
|
||||
ffmpeg/libavformat (used by a variety of media players)
|
||||
dvgrab v1.x (replaced by dvgrab2 on top of raw1394 and resp. libraries)
|
41
Documentation/ABI/testing/sysfs-bus-usb
Normal file
41
Documentation/ABI/testing/sysfs-bus-usb
Normal file
@ -0,0 +1,41 @@
|
||||
What: /sys/bus/usb/devices/.../power/autosuspend
|
||||
Date: March 2007
|
||||
KernelVersion: 2.6.21
|
||||
Contact: Alan Stern <stern@rowland.harvard.edu>
|
||||
Description:
|
||||
Each USB device directory will contain a file named
|
||||
power/autosuspend. This file holds the time (in seconds)
|
||||
the device must be idle before it will be autosuspended.
|
||||
0 means the device will be autosuspended as soon as
|
||||
possible. Negative values will prevent the device from
|
||||
being autosuspended at all, and writing a negative value
|
||||
will resume the device if it is already suspended.
|
||||
|
||||
The autosuspend delay for newly-created devices is set to
|
||||
the value of the usbcore.autosuspend module parameter.
|
||||
|
||||
What: /sys/bus/usb/devices/.../power/level
|
||||
Date: March 2007
|
||||
KernelVersion: 2.6.21
|
||||
Contact: Alan Stern <stern@rowland.harvard.edu>
|
||||
Description:
|
||||
Each USB device directory will contain a file named
|
||||
power/level. This file holds a power-level setting for
|
||||
the device, one of "on", "auto", or "suspend".
|
||||
|
||||
"on" means that the device is not allowed to autosuspend,
|
||||
although normal suspends for system sleep will still
|
||||
be honored. "auto" means the device will autosuspend
|
||||
and autoresume in the usual manner, according to the
|
||||
capabilities of its driver. "suspend" means the device
|
||||
is forced into a suspended state and it will not autoresume
|
||||
in response to I/O requests. However remote-wakeup requests
|
||||
from the device may still be enabled (the remote-wakeup
|
||||
setting is controlled separately by the power/wakeup
|
||||
attribute).
|
||||
|
||||
During normal use, devices should be left in the "auto"
|
||||
level. The other levels are meant for administrative uses.
|
||||
If you want to suspend a device immediately but leave it
|
||||
free to wake up in response to I/O requests, you should
|
||||
write "0" to power/autosuspend.
|
@ -236,6 +236,12 @@ X!Ilib/string.c
|
||||
!Enet/core/dev.c
|
||||
!Enet/ethernet/eth.c
|
||||
!Iinclude/linux/etherdevice.h
|
||||
!Edrivers/net/phy/phy.c
|
||||
!Idrivers/net/phy/phy.c
|
||||
!Edrivers/net/phy/phy_device.c
|
||||
!Idrivers/net/phy/phy_device.c
|
||||
!Edrivers/net/phy/mdio_bus.c
|
||||
!Idrivers/net/phy/mdio_bus.c
|
||||
<!-- FIXME: Removed for now since no structured comments in source
|
||||
X!Enet/core/wireless.c
|
||||
-->
|
||||
|
@ -557,6 +557,9 @@ Set some flags:
|
||||
Add some cpus:
|
||||
# /bin/echo 0-7 > cpus
|
||||
|
||||
Add some mems:
|
||||
# /bin/echo 0-7 > mems
|
||||
|
||||
Now attach your shell to this cpuset:
|
||||
# /bin/echo $$ > tasks
|
||||
|
||||
|
@ -6,6 +6,18 @@ be removed from this file.
|
||||
|
||||
---------------------------
|
||||
|
||||
What: V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP
|
||||
When: October 2007
|
||||
Why: Broken attempt to set MPEG compression parameters. These ioctls are
|
||||
not able to implement the wide variety of parameters that can be set
|
||||
by hardware MPEG encoders. A new MPEG control mechanism was created
|
||||
in kernel 2.6.18 that replaces these ioctls. See the V4L2 specification
|
||||
(section 1.9: Extended controls) for more information on this topic.
|
||||
Who: Hans Verkuil <hverkuil@xs4all.nl> and
|
||||
Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: /sys/devices/.../power/state
|
||||
dev->power.power_state
|
||||
dpm_runtime_{suspend,resume)()
|
||||
@ -39,17 +51,6 @@ Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: dv1394 driver (CONFIG_IEEE1394_DV1394)
|
||||
When: June 2007
|
||||
Why: Replaced by raw1394 + userspace libraries, notably libiec61883. This
|
||||
shift of application support has been indicated on www.linux1394.org
|
||||
and developers' mailinglists for quite some time. Major applications
|
||||
have been converted, with the exception of ffmpeg and hence xine.
|
||||
Piped output of dvgrab2 is a partial equivalent to dv1394.
|
||||
Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
|
||||
When: December 2006
|
||||
Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
|
||||
@ -145,15 +146,6 @@ Who: Arjan van de Ven <arjan@linux.intel.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: mount/umount uevents
|
||||
When: February 2007
|
||||
Why: These events are not correct, and do not properly let userspace know
|
||||
when a file system has been mounted or unmounted. Userspace should
|
||||
poll the /proc/mounts file instead to detect this properly.
|
||||
Who: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: USB driver API moves to EXPORT_SYMBOL_GPL
|
||||
When: February 2008
|
||||
Files: include/linux/usb.h, drivers/usb/core/driver.c
|
||||
@ -222,15 +214,6 @@ Who: Adrian Bunk <bunk@stusta.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: IPv4 only connection tracking/NAT/helpers
|
||||
When: 2.6.22
|
||||
Why: The new layer 3 independant connection tracking replaces the old
|
||||
IPv4 only version. After some stabilization of the new code the
|
||||
old one will be removed.
|
||||
Who: Patrick McHardy <kaber@trash.net>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: ACPI hooks (X86_SPEEDSTEP_CENTRINO_ACPI) in speedstep-centrino driver
|
||||
When: December 2006
|
||||
Why: Speedstep-centrino driver with ACPI hooks and acpi-cpufreq driver are
|
||||
@ -305,18 +288,6 @@ Who: Richard Purdie <rpurdie@rpsys.net>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: Wireless extensions over netlink (CONFIG_NET_WIRELESS_RTNETLINK)
|
||||
When: with the merge of wireless-dev, 2.6.22 or later
|
||||
Why: The option/code is
|
||||
* not enabled on most kernels
|
||||
* not required by any userspace tools (except an experimental one,
|
||||
and even there only for some parts, others use ioctl)
|
||||
* pointless since wext is no longer evolving and the ioctl
|
||||
interface needs to be kept
|
||||
Who: Johannes Berg <johannes@sipsolutions.net>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: i8xx_tco watchdog driver
|
||||
When: in 2.6.22
|
||||
Why: the i8xx_tco watchdog driver has been replaced by the iTCO_wdt
|
||||
@ -324,3 +295,22 @@ Why: the i8xx_tco watchdog driver has been replaced by the iTCO_wdt
|
||||
Who: Wim Van Sebroeck <wim@iguana.be>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: Multipath cached routing support in ipv4
|
||||
When: in 2.6.23
|
||||
Why: Code was merged, then submitter immediately disappeared leaving
|
||||
us with no maintainer and lots of bugs. The code should not have
|
||||
been merged in the first place, and many aspects of it's
|
||||
implementation are blocking more critical core networking
|
||||
development. It's marked EXPERIMENTAL and no distribution
|
||||
enables it because it cause obscure crashes due to unfixable bugs
|
||||
(interfaces don't return errors so memory allocation can't be
|
||||
handled, calling contexts of these interfaces make handling
|
||||
errors impossible too because they get called after we've
|
||||
totally commited to creating a route object, for example).
|
||||
This problem has existed for years and no forward progress
|
||||
has ever been made, and nobody steps up to try and salvage
|
||||
this code, so we're going to finally just get rid of it.
|
||||
Who: David S. Miller <davem@davemloft.net>
|
||||
|
||||
---------------------------
|
||||
|
@ -1,31 +1,82 @@
|
||||
====================
|
||||
kAFS: AFS FILESYSTEM
|
||||
====================
|
||||
|
||||
ABOUT
|
||||
Contents:
|
||||
|
||||
- Overview.
|
||||
- Usage.
|
||||
- Mountpoints.
|
||||
- Proc filesystem.
|
||||
- The cell database.
|
||||
- Security.
|
||||
- Examples.
|
||||
|
||||
|
||||
========
|
||||
OVERVIEW
|
||||
========
|
||||
|
||||
This filesystem provides a fairly simple secure AFS filesystem driver. It is
|
||||
under development and does not yet provide the full feature set. The features
|
||||
it does support include:
|
||||
|
||||
(*) Security (currently only AFS kaserver and KerberosIV tickets).
|
||||
|
||||
(*) File reading.
|
||||
|
||||
(*) Automounting.
|
||||
|
||||
It does not yet support the following AFS features:
|
||||
|
||||
(*) Write support.
|
||||
|
||||
(*) Local caching.
|
||||
|
||||
(*) pioctl() system call.
|
||||
|
||||
|
||||
===========
|
||||
COMPILATION
|
||||
===========
|
||||
|
||||
The filesystem should be enabled by turning on the kernel configuration
|
||||
options:
|
||||
|
||||
CONFIG_AF_RXRPC - The RxRPC protocol transport
|
||||
CONFIG_RXKAD - The RxRPC Kerberos security handler
|
||||
CONFIG_AFS - The AFS filesystem
|
||||
|
||||
Additionally, the following can be turned on to aid debugging:
|
||||
|
||||
CONFIG_AF_RXRPC_DEBUG - Permit AF_RXRPC debugging to be enabled
|
||||
CONFIG_AFS_DEBUG - Permit AFS debugging to be enabled
|
||||
|
||||
They permit the debugging messages to be turned on dynamically by manipulating
|
||||
the masks in the following files:
|
||||
|
||||
/sys/module/af_rxrpc/parameters/debug
|
||||
/sys/module/afs/parameters/debug
|
||||
|
||||
|
||||
=====
|
||||
|
||||
This filesystem provides a fairly simple AFS filesystem driver. It is under
|
||||
development and only provides very basic facilities. It does not yet support
|
||||
the following AFS features:
|
||||
|
||||
(*) Write support.
|
||||
(*) Communications security.
|
||||
(*) Local caching.
|
||||
(*) pioctl() system call.
|
||||
(*) Automatic mounting of embedded mountpoints.
|
||||
|
||||
|
||||
USAGE
|
||||
=====
|
||||
|
||||
When inserting the driver modules the root cell must be specified along with a
|
||||
list of volume location server IP addresses:
|
||||
|
||||
insmod rxrpc.o
|
||||
insmod af_rxrpc.o
|
||||
insmod rxkad.o
|
||||
insmod kafs.o rootcell=cambridge.redhat.com:172.16.18.73:172.16.18.91
|
||||
|
||||
The first module is a driver for the RxRPC remote operation protocol, and the
|
||||
second is the actual filesystem driver for the AFS filesystem.
|
||||
The first module is the AF_RXRPC network protocol driver. This provides the
|
||||
RxRPC remote operation protocol and may also be accessed from userspace. See:
|
||||
|
||||
Documentation/networking/rxrpc.txt
|
||||
|
||||
The second module is the kerberos RxRPC security driver, and the third module
|
||||
is the actual filesystem driver for the AFS filesystem.
|
||||
|
||||
Once the module has been loaded, more modules can be added by the following
|
||||
procedure:
|
||||
@ -33,7 +84,7 @@ procedure:
|
||||
echo add grand.central.org 18.7.14.88:128.2.191.224 >/proc/fs/afs/cells
|
||||
|
||||
Where the parameters to the "add" command are the name of a cell and a list of
|
||||
volume location servers within that cell.
|
||||
volume location servers within that cell, with the latter separated by colons.
|
||||
|
||||
Filesystems can be mounted anywhere by commands similar to the following:
|
||||
|
||||
@ -42,11 +93,6 @@ Filesystems can be mounted anywhere by commands similar to the following:
|
||||
mount -t afs "#root.afs." /afs
|
||||
mount -t afs "#root.cell." /afs/cambridge
|
||||
|
||||
NB: When using this on Linux 2.4, the mount command has to be different,
|
||||
since the filesystem doesn't have access to the device name argument:
|
||||
|
||||
mount -t afs none /afs -ovol="#root.afs."
|
||||
|
||||
Where the initial character is either a hash or a percent symbol depending on
|
||||
whether you definitely want a R/W volume (hash) or whether you'd prefer a R/O
|
||||
volume, but are willing to use a R/W volume instead (percent).
|
||||
@ -60,55 +106,66 @@ named volume will be looked up in the cell specified during insmod.
|
||||
Additional cells can be added through /proc (see later section).
|
||||
|
||||
|
||||
===========
|
||||
MOUNTPOINTS
|
||||
===========
|
||||
|
||||
AFS has a concept of mountpoints. These are specially formatted symbolic links
|
||||
(of the same form as the "device name" passed to mount). kAFS presents these
|
||||
to the user as directories that have special properties:
|
||||
AFS has a concept of mountpoints. In AFS terms, these are specially formatted
|
||||
symbolic links (of the same form as the "device name" passed to mount). kAFS
|
||||
presents these to the user as directories that have a follow-link capability
|
||||
(ie: symbolic link semantics). If anyone attempts to access them, they will
|
||||
automatically cause the target volume to be mounted (if possible) on that site.
|
||||
|
||||
(*) They cannot be listed. Running a program like "ls" on them will incur an
|
||||
EREMOTE error (Object is remote).
|
||||
Automatically mounted filesystems will be automatically unmounted approximately
|
||||
twenty minutes after they were last used. Alternatively they can be unmounted
|
||||
directly with the umount() system call.
|
||||
|
||||
(*) Other objects can't be looked up inside of them. This also incurs an
|
||||
EREMOTE error.
|
||||
Manually unmounting an AFS volume will cause any idle submounts upon it to be
|
||||
culled first. If all are culled, then the requested volume will also be
|
||||
unmounted, otherwise error EBUSY will be returned.
|
||||
|
||||
(*) They can be queried with the readlink() system call, which will return
|
||||
the name of the mountpoint to which they point. The "readlink" program
|
||||
will also work.
|
||||
This can be used by the administrator to attempt to unmount the whole AFS tree
|
||||
mounted on /afs in one go by doing:
|
||||
|
||||
(*) They can be mounted on (which symbolic links can't).
|
||||
umount /afs
|
||||
|
||||
|
||||
===============
|
||||
PROC FILESYSTEM
|
||||
===============
|
||||
|
||||
The rxrpc module creates a number of files in various places in the /proc
|
||||
filesystem:
|
||||
|
||||
(*) Firstly, some information files are made available in a directory called
|
||||
"/proc/net/rxrpc/". These list the extant transport endpoint, peer,
|
||||
connection and call records.
|
||||
|
||||
(*) Secondly, some control files are made available in a directory called
|
||||
"/proc/sys/rxrpc/". Currently, all these files can be used for is to
|
||||
turn on various levels of tracing.
|
||||
|
||||
The AFS modules creates a "/proc/fs/afs/" directory and populates it:
|
||||
|
||||
(*) A "cells" file that lists cells currently known to the afs module.
|
||||
(*) A "cells" file that lists cells currently known to the afs module and
|
||||
their usage counts:
|
||||
|
||||
[root@andromeda ~]# cat /proc/fs/afs/cells
|
||||
USE NAME
|
||||
3 cambridge.redhat.com
|
||||
|
||||
(*) A directory per cell that contains files that list volume location
|
||||
servers, volumes, and active servers known within that cell.
|
||||
|
||||
[root@andromeda ~]# cat /proc/fs/afs/cambridge.redhat.com/servers
|
||||
USE ADDR STATE
|
||||
4 172.16.18.91 0
|
||||
[root@andromeda ~]# cat /proc/fs/afs/cambridge.redhat.com/vlservers
|
||||
ADDRESS
|
||||
172.16.18.91
|
||||
[root@andromeda ~]# cat /proc/fs/afs/cambridge.redhat.com/volumes
|
||||
USE STT VLID[0] VLID[1] VLID[2] NAME
|
||||
1 Val 20000000 20000001 20000002 root.afs
|
||||
|
||||
|
||||
=================
|
||||
THE CELL DATABASE
|
||||
=================
|
||||
|
||||
The filesystem maintains an internal database of all the cells it knows and
|
||||
the IP addresses of the volume location servers for those cells. The cell to
|
||||
which the computer belongs is added to the database when insmod is performed
|
||||
by the "rootcell=" argument.
|
||||
The filesystem maintains an internal database of all the cells it knows and the
|
||||
IP addresses of the volume location servers for those cells. The cell to which
|
||||
the system belongs is added to the database when insmod is performed by the
|
||||
"rootcell=" argument or, if compiled in, using a "kafs.rootcell=" argument on
|
||||
the kernel command line.
|
||||
|
||||
Further cells can be added by commands similar to the following:
|
||||
|
||||
@ -118,20 +175,65 @@ Further cells can be added by commands similar to the following:
|
||||
No other cell database operations are available at this time.
|
||||
|
||||
|
||||
========
|
||||
SECURITY
|
||||
========
|
||||
|
||||
Secure operations are initiated by acquiring a key using the klog program. A
|
||||
very primitive klog program is available at:
|
||||
|
||||
http://people.redhat.com/~dhowells/rxrpc/klog.c
|
||||
|
||||
This should be compiled by:
|
||||
|
||||
make klog LDLIBS="-lcrypto -lcrypt -lkrb4 -lkeyutils"
|
||||
|
||||
And then run as:
|
||||
|
||||
./klog
|
||||
|
||||
Assuming it's successful, this adds a key of type RxRPC, named for the service
|
||||
and cell, eg: "afs@<cellname>". This can be viewed with the keyctl program or
|
||||
by cat'ing /proc/keys:
|
||||
|
||||
[root@andromeda ~]# keyctl show
|
||||
Session Keyring
|
||||
-3 --alswrv 0 0 keyring: _ses.3268
|
||||
2 --alswrv 0 0 \_ keyring: _uid.0
|
||||
111416553 --als--v 0 0 \_ rxrpc: afs@CAMBRIDGE.REDHAT.COM
|
||||
|
||||
Currently the username, realm, password and proposed ticket lifetime are
|
||||
compiled in to the program.
|
||||
|
||||
It is not required to acquire a key before using AFS facilities, but if one is
|
||||
not acquired then all operations will be governed by the anonymous user parts
|
||||
of the ACLs.
|
||||
|
||||
If a key is acquired, then all AFS operations, including mounts and automounts,
|
||||
made by a possessor of that key will be secured with that key.
|
||||
|
||||
If a file is opened with a particular key and then the file descriptor is
|
||||
passed to a process that doesn't have that key (perhaps over an AF_UNIX
|
||||
socket), then the operations on the file will be made with key that was used to
|
||||
open the file.
|
||||
|
||||
|
||||
========
|
||||
EXAMPLES
|
||||
========
|
||||
|
||||
Here's what I use to test this. Some of the names and IP addresses are local
|
||||
to my internal DNS. My "root.afs" partition has a mount point within it for
|
||||
Here's what I use to test this. Some of the names and IP addresses are local
|
||||
to my internal DNS. My "root.afs" partition has a mount point within it for
|
||||
some public volumes volumes.
|
||||
|
||||
insmod -S /tmp/rxrpc.o
|
||||
insmod -S /tmp/kafs.o rootcell=cambridge.redhat.com:172.16.18.73:172.16.18.91
|
||||
insmod /tmp/rxrpc.o
|
||||
insmod /tmp/rxkad.o
|
||||
insmod /tmp/kafs.o rootcell=cambridge.redhat.com:172.16.18.91
|
||||
|
||||
mount -t afs \%root.afs. /afs
|
||||
mount -t afs \%cambridge.redhat.com:root.cell. /afs/cambridge.redhat.com/
|
||||
|
||||
echo add grand.central.org 18.7.14.88:128.2.191.224 > /proc/fs/afs/cells
|
||||
echo add grand.central.org 18.7.14.88:128.2.191.224 > /proc/fs/afs/cells
|
||||
mount -t afs "#grand.central.org:root.cell." /afs/grand.central.org/
|
||||
mount -t afs "#grand.central.org:root.archive." /afs/grand.central.org/archive
|
||||
mount -t afs "#grand.central.org:root.contrib." /afs/grand.central.org/contrib
|
||||
@ -141,15 +243,7 @@ mount -t afs "#grand.central.org:root.service." /afs/grand.central.org/service
|
||||
mount -t afs "#grand.central.org:root.software." /afs/grand.central.org/software
|
||||
mount -t afs "#grand.central.org:root.user." /afs/grand.central.org/user
|
||||
|
||||
umount /afs/grand.central.org/user
|
||||
umount /afs/grand.central.org/software
|
||||
umount /afs/grand.central.org/service
|
||||
umount /afs/grand.central.org/project
|
||||
umount /afs/grand.central.org/doc
|
||||
umount /afs/grand.central.org/contrib
|
||||
umount /afs/grand.central.org/archive
|
||||
umount /afs/grand.central.org
|
||||
umount /afs/cambridge.redhat.com
|
||||
umount /afs
|
||||
rmmod kafs
|
||||
rmmod rxkad
|
||||
rmmod rxrpc
|
||||
|
@ -1421,6 +1421,15 @@ fewer messages that will be written. Message_burst controls when messages will
|
||||
be dropped. The default settings limit warning messages to one every five
|
||||
seconds.
|
||||
|
||||
warnings
|
||||
--------
|
||||
|
||||
This controls console messages from the networking stack that can occur because
|
||||
of problems on the network like duplicate address or bad checksums. Normally,
|
||||
this should be enabled, but if the problem persists the messages can be
|
||||
disabled.
|
||||
|
||||
|
||||
netdev_max_backlog
|
||||
------------------
|
||||
|
||||
|
@ -27,7 +27,7 @@ The exact capabilities of GPIOs vary between systems. Common options:
|
||||
- Output values are writable (high=1, low=0). Some chips also have
|
||||
options about how that value is driven, so that for example only one
|
||||
value might be driven ... supporting "wire-OR" and similar schemes
|
||||
for the other value.
|
||||
for the other value (notably, "open drain" signaling).
|
||||
|
||||
- Input values are likewise readable (1, 0). Some chips support readback
|
||||
of pins configured as "output", which is very useful in such "wire-OR"
|
||||
@ -247,6 +247,35 @@ with gpio_get_value(), for example to initialize or update driver state
|
||||
when the IRQ is edge-triggered.
|
||||
|
||||
|
||||
Emulating Open Drain Signals
|
||||
----------------------------
|
||||
Sometimes shared signals need to use "open drain" signaling, where only the
|
||||
low signal level is actually driven. (That term applies to CMOS transistors;
|
||||
"open collector" is used for TTL.) A pullup resistor causes the high signal
|
||||
level. This is sometimes called a "wire-AND"; or more practically, from the
|
||||
negative logic (low=true) perspective this is a "wire-OR".
|
||||
|
||||
One common example of an open drain signal is a shared active-low IRQ line.
|
||||
Also, bidirectional data bus signals sometimes use open drain signals.
|
||||
|
||||
Some GPIO controllers directly support open drain outputs; many don't. When
|
||||
you need open drain signaling but your hardware doesn't directly support it,
|
||||
there's a common idiom you can use to emulate it with any GPIO pin that can
|
||||
be used as either an input or an output:
|
||||
|
||||
LOW: gpio_direction_output(gpio, 0) ... this drives the signal
|
||||
and overrides the pullup.
|
||||
|
||||
HIGH: gpio_direction_input(gpio) ... this turns off the output,
|
||||
so the pullup (or some other device) controls the signal.
|
||||
|
||||
If you are "driving" the signal high but gpio_get_value(gpio) reports a low
|
||||
value (after the appropriate rise time passes), you know some other component
|
||||
is driving the shared signal low. That's not necessarily an error. As one
|
||||
common example, that's how I2C clocks are stretched: a slave that needs a
|
||||
slower clock delays the rising edge of SCK, and the I2C master adjusts its
|
||||
signaling rate accordingly.
|
||||
|
||||
|
||||
What do these conventions omit?
|
||||
===============================
|
||||
|
@ -91,6 +91,14 @@ Sending MADs
|
||||
if (ret != sizeof *mad + mad_length)
|
||||
perror("write");
|
||||
|
||||
Transaction IDs
|
||||
|
||||
Users of the umad devices can use the lower 32 bits of the
|
||||
transaction ID field (that is, the least significant half of the
|
||||
field in network byte order) in MADs being sent to match
|
||||
request/response pairs. The upper 32 bits are reserved for use by
|
||||
the kernel and will be overwritten before a MAD is sent.
|
||||
|
||||
Setting IsSM Capability Bit
|
||||
|
||||
To set the IsSM capability bit for a port, simply open the
|
||||
|
@ -142,7 +142,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
Format: <int>
|
||||
2: use 2nd APIC table, if available
|
||||
1,0: use 1st APIC table
|
||||
default: 2
|
||||
default: 0
|
||||
|
||||
acpi_sleep= [HW,ACPI] Sleep options
|
||||
Format: { s3_bios, s3_mode }
|
||||
@ -181,19 +181,41 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
that require a timer override, but don't have
|
||||
HPET
|
||||
|
||||
acpi_dbg_layer= [HW,ACPI]
|
||||
acpi.debug_layer= [HW,ACPI]
|
||||
Format: <int>
|
||||
Each bit of the <int> indicates an ACPI debug layer,
|
||||
1: enable, 0: disable. It is useful for boot time
|
||||
debugging. After system has booted up, it can be set
|
||||
via /proc/acpi/debug_layer.
|
||||
via /sys/module/acpi/parameters/debug_layer.
|
||||
CONFIG_ACPI_DEBUG must be enabled for this to produce any output.
|
||||
Available bits (add the numbers together) to enable debug output
|
||||
for specific parts of the ACPI subsystem:
|
||||
0x01 utilities 0x02 hardware 0x04 events 0x08 tables
|
||||
0x10 namespace 0x20 parser 0x40 dispatcher
|
||||
0x80 executer 0x100 resources 0x200 acpica debugger
|
||||
0x400 os services 0x800 acpica disassembler.
|
||||
The number can be in decimal or prefixed with 0x in hex.
|
||||
Warning: Many of these options can produce a lot of
|
||||
output and make your system unusable. Be very careful.
|
||||
|
||||
acpi_dbg_level= [HW,ACPI]
|
||||
acpi.debug_level= [HW,ACPI]
|
||||
Format: <int>
|
||||
Each bit of the <int> indicates an ACPI debug level,
|
||||
1: enable, 0: disable. It is useful for boot time
|
||||
debugging. After system has booted up, it can be set
|
||||
via /proc/acpi/debug_level.
|
||||
via /sys/module/acpi/parameters/debug_level.
|
||||
CONFIG_ACPI_DEBUG must be enabled for this to produce any output.
|
||||
Available bits (add the numbers together) to enable different
|
||||
debug output levels of the ACPI subsystem:
|
||||
0x01 error 0x02 warn 0x04 init 0x08 debug object
|
||||
0x10 info 0x20 init names 0x40 parse 0x80 load
|
||||
0x100 dispatch 0x200 execute 0x400 names 0x800 operation region
|
||||
0x1000 bfield 0x2000 tables 0x4000 values 0x8000 objects
|
||||
0x10000 resources 0x20000 user requests 0x40000 package.
|
||||
The number can be in decimal or prefixed with 0x in hex.
|
||||
Warning: Many of these options can produce a lot of
|
||||
output and make your system unusable. Be very careful.
|
||||
|
||||
|
||||
acpi_fake_ecdt [HW,ACPI] Workaround failure due to BIOS lacking ECDT
|
||||
|
||||
@ -1792,7 +1814,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
for newly-detected USB devices (default 2). This
|
||||
is the time required before an idle device will be
|
||||
autosuspended. Devices for which the delay is set
|
||||
to 0 won't be autosuspended at all.
|
||||
to a negative value won't be autosuspended at all.
|
||||
|
||||
usbhid.mousepoll=
|
||||
[USBHID] The interval which mice are to be polled at.
|
||||
|
@ -859,6 +859,18 @@ payload contents" for more information.
|
||||
void unregister_key_type(struct key_type *type);
|
||||
|
||||
|
||||
Under some circumstances, it may be desirable to desirable to deal with a
|
||||
bundle of keys. The facility provides access to the keyring type for managing
|
||||
such a bundle:
|
||||
|
||||
struct key_type key_type_keyring;
|
||||
|
||||
This can be used with a function such as request_key() to find a specific
|
||||
keyring in a process's keyrings. A keyring thus found can then be searched
|
||||
with keyring_search(). Note that it is not possible to use request_key() to
|
||||
search a specific keyring, so using keyrings in this way is of limited utility.
|
||||
|
||||
|
||||
===================================
|
||||
NOTES ON ACCESSING PAYLOAD CONTENTS
|
||||
===================================
|
||||
|
@ -1,16 +1,10 @@
|
||||
To use the amateur radio protocols within Linux you will need to get a
|
||||
suitable copy of the AX.25 Utilities. More detailed information about these
|
||||
and associated programs can be found on http://zone.pspt.fi/~jsn/.
|
||||
|
||||
For more information about the AX.25, NET/ROM and ROSE protocol stacks, see
|
||||
the AX25-HOWTO written by Terry Dawson <terry@perf.no.itg.telstra.com.au>
|
||||
who is also the AX.25 Utilities maintainer.
|
||||
suitable copy of the AX.25 Utilities. More detailed information about
|
||||
AX.25, NET/ROM and ROSE, associated programs and and utilities can be
|
||||
found on http://www.linux-ax25.org.
|
||||
|
||||
There is an active mailing list for discussing Linux amateur radio matters
|
||||
called linux-hams. To subscribe to it, send a message to
|
||||
called linux-hams@vger.kernel.org. To subscribe to it, send a message to
|
||||
majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body
|
||||
of the message, the subject field is ignored.
|
||||
|
||||
Jonathan G4KLX
|
||||
|
||||
g4klx@g4klx.demon.co.uk
|
||||
of the message, the subject field is ignored. You don't need to be
|
||||
subscribed to post but of course that means you might miss an answer.
|
||||
|
@ -2,35 +2,88 @@
|
||||
BCM43xx Linux Driver Project
|
||||
============================
|
||||
|
||||
About this software
|
||||
-------------------
|
||||
|
||||
The goal of this project is to develop a linux driver for Broadcom
|
||||
BCM43xx chips, based on the specification at
|
||||
http://bcm-specs.sipsolutions.net/
|
||||
|
||||
The project page is http://bcm43xx.berlios.de/
|
||||
|
||||
|
||||
Requirements
|
||||
Introduction
|
||||
------------
|
||||
|
||||
1) Linux Kernel 2.6.16 or later
|
||||
http://www.kernel.org/
|
||||
Many of the wireless devices found in modern notebook computers are
|
||||
based on the wireless chips produced by Broadcom. These devices have
|
||||
been a problem for Linux users as there is no open-source driver
|
||||
available. In addition, Broadcom has not released specifications
|
||||
for the device, and driver availability has been limited to the
|
||||
binary-only form used in the GPL versions of AP hardware such as the
|
||||
Linksys WRT54G, and the Windows and OS X drivers. Before this project
|
||||
began, the only way to use these devices were to use the Windows or
|
||||
OS X drivers with either the Linuxant or ndiswrapper modules. There
|
||||
is a strong penalty if this method is used as loading the binary-only
|
||||
module "taints" the kernel, and no kernel developer will help diagnose
|
||||
any kernel problems.
|
||||
|
||||
You may want to configure your kernel with:
|
||||
Development
|
||||
-----------
|
||||
|
||||
CONFIG_DEBUG_FS (optional):
|
||||
-> Kernel hacking
|
||||
-> Debug Filesystem
|
||||
This driver has been developed using
|
||||
a clean-room technique that is described at
|
||||
http://bcm-specs.sipsolutions.net/ReverseEngineeringProcess. For legal
|
||||
reasons, none of the clean-room crew works on the on the Linux driver,
|
||||
and none of the Linux developers sees anything but the specifications,
|
||||
which are the ultimate product of the reverse-engineering group.
|
||||
|
||||
2) SoftMAC IEEE 802.11 Networking Stack extension and patched ieee80211
|
||||
modules:
|
||||
http://softmac.sipsolutions.net/
|
||||
Software
|
||||
--------
|
||||
|
||||
3) Firmware Files
|
||||
Since the release of the 2.6.17 kernel, the bcm43xx driver has been
|
||||
distributed with the kernel source, and is prebuilt in most, if not
|
||||
all, distributions. There is, however, additional software that is
|
||||
required. The firmware used by the chip is the intellectual property
|
||||
of Broadcom and they have not given the bcm43xx team redistribution
|
||||
rights to this firmware. Since we cannot legally redistribute
|
||||
the firwmare we cannot include it with the driver. Furthermore, it
|
||||
cannot be placed in the downloadable archives of any distributing
|
||||
organization; therefore, the user is responsible for obtaining the
|
||||
firmware and placing it in the appropriate location so that the driver
|
||||
can find it when initializing.
|
||||
|
||||
Please try fwcutter. Fwcutter can extract the firmware from various
|
||||
binary driver files. It supports driver files from Windows, MacOS and
|
||||
Linux. You can get fwcutter from http://bcm43xx.berlios.de/.
|
||||
Also, fwcutter comes with a README file for further instructions.
|
||||
To help with this process, the bcm43xx developers provide a separate
|
||||
program named bcm43xx-fwcutter to "cut" the firmware out of a
|
||||
Windows or OS X driver and write the extracted files to the proper
|
||||
location. This program is usually provided with the distribution;
|
||||
however, it may be downloaded from
|
||||
|
||||
http://developer.berlios.de/project/showfiles.php?group_id=4547
|
||||
|
||||
The firmware is available in two versions. V3 firmware is used with
|
||||
the in-kernel bcm43xx driver that uses a software MAC layer called
|
||||
SoftMAC, and will have a microcode revision of 0x127 or smaller. The
|
||||
V4 firmware is used by an out-of-kernel driver employing a variation of
|
||||
the Devicescape MAC layer known as d80211. Once bcm43xx-d80211 reaches
|
||||
a satisfactory level of development, it will replace bcm43xx-softmac
|
||||
in the kernel as it is much more flexible and powerful.
|
||||
|
||||
A source for the latest V3 firmware is
|
||||
|
||||
http://downloads.openwrt.org/sources/wl_apsta-3.130.20.0.o
|
||||
|
||||
Once this file is downloaded, the command
|
||||
'bcm43xx-fwcutter -w <dir> <filename>'
|
||||
will extract the microcode and write it to directory
|
||||
<dir>. The correct directory will depend on your distribution;
|
||||
however, most use '/lib/firmware'. Once this step is completed,
|
||||
the bcm3xx driver should load when the system is booted. To see
|
||||
any messages relating to the driver, issue the command 'dmesg |
|
||||
grep bcm43xx' from a terminal window. If there are any problems,
|
||||
please send that output to Bcm43xx-dev@lists.berlios.de.
|
||||
|
||||
Although the driver has been in-kernel since 2.6.17, the earliest
|
||||
version is quite limited in its capability. Patches that include
|
||||
all features of later versions are available for the stable kernel
|
||||
versions from 2.6.18. These will be needed if you use a BCM4318,
|
||||
or a PCI Express version (BCM4311 and BCM4312). In addition, if you
|
||||
have an early BCM4306 and more than 1 GB RAM, your kernel will need
|
||||
to be patched. These patches, which are being updated regularly,
|
||||
are available at ftp://lwfinger.dynalias.org/patches. Look for
|
||||
combined_2.6.YY.patch. Of course you will need kernel source downloaded
|
||||
from kernel.org, or the source from your distribution.
|
||||
|
||||
If you build your own kernel, please enable CONFIG_BCM43XX_DEBUG
|
||||
and CONFIG_IEEE80211_SOFTMAC_DEBUG. The log information provided is
|
||||
essential for solving any problems.
|
||||
|
@ -920,40 +920,9 @@ options, you may wish to use the "max_bonds" module parameter,
|
||||
documented above.
|
||||
|
||||
To create multiple bonding devices with differing options, it
|
||||
is necessary to load the bonding driver multiple times. Note that
|
||||
current versions of the sysconfig network initialization scripts
|
||||
handle this automatically; if your distro uses these scripts, no
|
||||
special action is needed. See the section Configuring Bonding
|
||||
Devices, above, if you're not sure about your network initialization
|
||||
scripts.
|
||||
is necessary to use bonding parameters exported by sysfs, documented
|
||||
in the section below.
|
||||
|
||||
To load multiple instances of the module, it is necessary to
|
||||
specify a different name for each instance (the module loading system
|
||||
requires that every loaded module, even multiple instances of the same
|
||||
module, have a unique name). This is accomplished by supplying
|
||||
multiple sets of bonding options in /etc/modprobe.conf, for example:
|
||||
|
||||
alias bond0 bonding
|
||||
options bond0 -o bond0 mode=balance-rr miimon=100
|
||||
|
||||
alias bond1 bonding
|
||||
options bond1 -o bond1 mode=balance-alb miimon=50
|
||||
|
||||
will load the bonding module two times. The first instance is
|
||||
named "bond0" and creates the bond0 device in balance-rr mode with an
|
||||
miimon of 100. The second instance is named "bond1" and creates the
|
||||
bond1 device in balance-alb mode with an miimon of 50.
|
||||
|
||||
In some circumstances (typically with older distributions),
|
||||
the above does not work, and the second bonding instance never sees
|
||||
its options. In that case, the second options line can be substituted
|
||||
as follows:
|
||||
|
||||
install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \
|
||||
mode=balance-alb miimon=50
|
||||
|
||||
This may be repeated any number of times, specifying a new and
|
||||
unique name in place of bond1 for each subsequent instance.
|
||||
|
||||
3.4 Configuring Bonding Manually via Sysfs
|
||||
------------------------------------------
|
||||
|
@ -57,6 +57,16 @@ DCCP_SOCKOPT_SEND_CSCOV is for the receiver and has a different meaning: it
|
||||
coverage value are also acceptable. The higher the number, the more
|
||||
restrictive this setting (see [RFC 4340, sec. 9.2.1]).
|
||||
|
||||
The following two options apply to CCID 3 exclusively and are getsockopt()-only.
|
||||
In either case, a TFRC info struct (defined in <linux/tfrc.h>) is returned.
|
||||
DCCP_SOCKOPT_CCID_RX_INFO
|
||||
Returns a `struct tfrc_rx_info' in optval; the buffer for optval and
|
||||
optlen must be set to at least sizeof(struct tfrc_rx_info).
|
||||
DCCP_SOCKOPT_CCID_TX_INFO
|
||||
Returns a `struct tfrc_tx_info' in optval; the buffer for optval and
|
||||
optlen must be set to at least sizeof(struct tfrc_tx_info).
|
||||
|
||||
|
||||
Sysctl variables
|
||||
================
|
||||
Several DCCP default parameters can be managed by the following sysctls
|
||||
|
@ -179,11 +179,31 @@ tcp_fin_timeout - INTEGER
|
||||
because they eat maximum 1.5K of memory, but they tend
|
||||
to live longer. Cf. tcp_max_orphans.
|
||||
|
||||
tcp_frto - BOOLEAN
|
||||
tcp_frto - INTEGER
|
||||
Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
|
||||
timeouts. It is particularly beneficial in wireless environments
|
||||
where packet loss is typically due to random radio interference
|
||||
rather than intermediate router congestion.
|
||||
rather than intermediate router congestion. If set to 1, basic
|
||||
version is enabled. 2 enables SACK enhanced F-RTO, which is
|
||||
EXPERIMENTAL. The basic version can be used also when SACK is
|
||||
enabled for a flow through tcp_sack sysctl.
|
||||
|
||||
tcp_frto_response - INTEGER
|
||||
When F-RTO has detected that a TCP retransmission timeout was
|
||||
spurious (i.e, the timeout would have been avoided had TCP set a
|
||||
longer retransmission timeout), TCP has several options what to do
|
||||
next. Possible values are:
|
||||
0 Rate halving based; a smooth and conservative response,
|
||||
results in halved cwnd and ssthresh after one RTT
|
||||
1 Very conservative response; not recommended because even
|
||||
though being valid, it interacts poorly with the rest of
|
||||
Linux TCP, halves cwnd and ssthresh immediately
|
||||
2 Aggressive response; undoes congestion control measures
|
||||
that are now known to be unnecessary (ignoring the
|
||||
possibility of a lost retransmission that would require
|
||||
TCP to be more cautious), cwnd and ssthresh are restored
|
||||
to the values prior timeout
|
||||
Default: 0 (rate halving based)
|
||||
|
||||
tcp_keepalive_time - INTEGER
|
||||
How often TCP sends out keepalive messages when keepalive is enabled.
|
||||
@ -851,6 +871,15 @@ accept_redirects - BOOLEAN
|
||||
Functional default: enabled if local forwarding is disabled.
|
||||
disabled if local forwarding is enabled.
|
||||
|
||||
accept_source_route - INTEGER
|
||||
Accept source routing (routing extension header).
|
||||
|
||||
> 0: Accept routing header.
|
||||
= 0: Accept only routing header type 2.
|
||||
< 0: Do not accept routing header.
|
||||
|
||||
Default: 0
|
||||
|
||||
autoconf - BOOLEAN
|
||||
Autoconfigure addresses using Prefix Information in Router
|
||||
Advertisements.
|
||||
@ -986,7 +1015,12 @@ bridge-nf-call-ip6tables - BOOLEAN
|
||||
Default: 1
|
||||
|
||||
bridge-nf-filter-vlan-tagged - BOOLEAN
|
||||
1 : pass bridged vlan-tagged ARP/IP traffic to arptables/iptables.
|
||||
1 : pass bridged vlan-tagged ARP/IP/IPv6 traffic to {arp,ip,ip6}tables.
|
||||
0 : disable this.
|
||||
Default: 1
|
||||
|
||||
bridge-nf-filter-pppoe-tagged - BOOLEAN
|
||||
1 : pass bridged pppoe-tagged IP/IPv6 traffic to {ip,ip6}tables.
|
||||
0 : disable this.
|
||||
Default: 1
|
||||
|
||||
|
859
Documentation/networking/rxrpc.txt
Normal file
859
Documentation/networking/rxrpc.txt
Normal file
@ -0,0 +1,859 @@
|
||||
======================
|
||||
RxRPC NETWORK PROTOCOL
|
||||
======================
|
||||
|
||||
The RxRPC protocol driver provides a reliable two-phase transport on top of UDP
|
||||
that can be used to perform RxRPC remote operations. This is done over sockets
|
||||
of AF_RXRPC family, using sendmsg() and recvmsg() with control data to send and
|
||||
receive data, aborts and errors.
|
||||
|
||||
Contents of this document:
|
||||
|
||||
(*) Overview.
|
||||
|
||||
(*) RxRPC protocol summary.
|
||||
|
||||
(*) AF_RXRPC driver model.
|
||||
|
||||
(*) Control messages.
|
||||
|
||||
(*) Socket options.
|
||||
|
||||
(*) Security.
|
||||
|
||||
(*) Example client usage.
|
||||
|
||||
(*) Example server usage.
|
||||
|
||||
(*) AF_RXRPC kernel interface.
|
||||
|
||||
|
||||
========
|
||||
OVERVIEW
|
||||
========
|
||||
|
||||
RxRPC is a two-layer protocol. There is a session layer which provides
|
||||
reliable virtual connections using UDP over IPv4 (or IPv6) as the transport
|
||||
layer, but implements a real network protocol; and there's the presentation
|
||||
layer which renders structured data to binary blobs and back again using XDR
|
||||
(as does SunRPC):
|
||||
|
||||
+-------------+
|
||||
| Application |
|
||||
+-------------+
|
||||
| XDR | Presentation
|
||||
+-------------+
|
||||
| RxRPC | Session
|
||||
+-------------+
|
||||
| UDP | Transport
|
||||
+-------------+
|
||||
|
||||
|
||||
AF_RXRPC provides:
|
||||
|
||||
(1) Part of an RxRPC facility for both kernel and userspace applications by
|
||||
making the session part of it a Linux network protocol (AF_RXRPC).
|
||||
|
||||
(2) A two-phase protocol. The client transmits a blob (the request) and then
|
||||
receives a blob (the reply), and the server receives the request and then
|
||||
transmits the reply.
|
||||
|
||||
(3) Retention of the reusable bits of the transport system set up for one call
|
||||
to speed up subsequent calls.
|
||||
|
||||
(4) A secure protocol, using the Linux kernel's key retention facility to
|
||||
manage security on the client end. The server end must of necessity be
|
||||
more active in security negotiations.
|
||||
|
||||
AF_RXRPC does not provide XDR marshalling/presentation facilities. That is
|
||||
left to the application. AF_RXRPC only deals in blobs. Even the operation ID
|
||||
is just the first four bytes of the request blob, and as such is beyond the
|
||||
kernel's interest.
|
||||
|
||||
|
||||
Sockets of AF_RXRPC family are:
|
||||
|
||||
(1) created as type SOCK_DGRAM;
|
||||
|
||||
(2) provided with a protocol of the type of underlying transport they're going
|
||||
to use - currently only PF_INET is supported.
|
||||
|
||||
|
||||
The Andrew File System (AFS) is an example of an application that uses this and
|
||||
that has both kernel (filesystem) and userspace (utility) components.
|
||||
|
||||
|
||||
======================
|
||||
RXRPC PROTOCOL SUMMARY
|
||||
======================
|
||||
|
||||
An overview of the RxRPC protocol:
|
||||
|
||||
(*) RxRPC sits on top of another networking protocol (UDP is the only option
|
||||
currently), and uses this to provide network transport. UDP ports, for
|
||||
example, provide transport endpoints.
|
||||
|
||||
(*) RxRPC supports multiple virtual "connections" from any given transport
|
||||
endpoint, thus allowing the endpoints to be shared, even to the same
|
||||
remote endpoint.
|
||||
|
||||
(*) Each connection goes to a particular "service". A connection may not go
|
||||
to multiple services. A service may be considered the RxRPC equivalent of
|
||||
a port number. AF_RXRPC permits multiple services to share an endpoint.
|
||||
|
||||
(*) Client-originating packets are marked, thus a transport endpoint can be
|
||||
shared between client and server connections (connections have a
|
||||
direction).
|
||||
|
||||
(*) Up to a billion connections may be supported concurrently between one
|
||||
local transport endpoint and one service on one remote endpoint. An RxRPC
|
||||
connection is described by seven numbers:
|
||||
|
||||
Local address }
|
||||
Local port } Transport (UDP) address
|
||||
Remote address }
|
||||
Remote port }
|
||||
Direction
|
||||
Connection ID
|
||||
Service ID
|
||||
|
||||
(*) Each RxRPC operation is a "call". A connection may make up to four
|
||||
billion calls, but only up to four calls may be in progress on a
|
||||
connection at any one time.
|
||||
|
||||
(*) Calls are two-phase and asymmetric: the client sends its request data,
|
||||
which the service receives; then the service transmits the reply data
|
||||
which the client receives.
|
||||
|
||||
(*) The data blobs are of indefinite size, the end of a phase is marked with a
|
||||
flag in the packet. The number of packets of data making up one blob may
|
||||
not exceed 4 billion, however, as this would cause the sequence number to
|
||||
wrap.
|
||||
|
||||
(*) The first four bytes of the request data are the service operation ID.
|
||||
|
||||
(*) Security is negotiated on a per-connection basis. The connection is
|
||||
initiated by the first data packet on it arriving. If security is
|
||||
requested, the server then issues a "challenge" and then the client
|
||||
replies with a "response". If the response is successful, the security is
|
||||
set for the lifetime of that connection, and all subsequent calls made
|
||||
upon it use that same security. In the event that the server lets a
|
||||
connection lapse before the client, the security will be renegotiated if
|
||||
the client uses the connection again.
|
||||
|
||||
(*) Calls use ACK packets to handle reliability. Data packets are also
|
||||
explicitly sequenced per call.
|
||||
|
||||
(*) There are two types of positive acknowledgement: hard-ACKs and soft-ACKs.
|
||||
A hard-ACK indicates to the far side that all the data received to a point
|
||||
has been received and processed; a soft-ACK indicates that the data has
|
||||
been received but may yet be discarded and re-requested. The sender may
|
||||
not discard any transmittable packets until they've been hard-ACK'd.
|
||||
|
||||
(*) Reception of a reply data packet implicitly hard-ACK's all the data
|
||||
packets that make up the request.
|
||||
|
||||
(*) An call is complete when the request has been sent, the reply has been
|
||||
received and the final hard-ACK on the last packet of the reply has
|
||||
reached the server.
|
||||
|
||||
(*) An call may be aborted by either end at any time up to its completion.
|
||||
|
||||
|
||||
=====================
|
||||
AF_RXRPC DRIVER MODEL
|
||||
=====================
|
||||
|
||||
About the AF_RXRPC driver:
|
||||
|
||||
(*) The AF_RXRPC protocol transparently uses internal sockets of the transport
|
||||
protocol to represent transport endpoints.
|
||||
|
||||
(*) AF_RXRPC sockets map onto RxRPC connection bundles. Actual RxRPC
|
||||
connections are handled transparently. One client socket may be used to
|
||||
make multiple simultaneous calls to the same service. One server socket
|
||||
may handle calls from many clients.
|
||||
|
||||
(*) Additional parallel client connections will be initiated to support extra
|
||||
concurrent calls, up to a tunable limit.
|
||||
|
||||
(*) Each connection is retained for a certain amount of time [tunable] after
|
||||
the last call currently using it has completed in case a new call is made
|
||||
that could reuse it.
|
||||
|
||||
(*) Each internal UDP socket is retained [tunable] for a certain amount of
|
||||
time [tunable] after the last connection using it discarded, in case a new
|
||||
connection is made that could use it.
|
||||
|
||||
(*) A client-side connection is only shared between calls if they have have
|
||||
the same key struct describing their security (and assuming the calls
|
||||
would otherwise share the connection). Non-secured calls would also be
|
||||
able to share connections with each other.
|
||||
|
||||
(*) A server-side connection is shared if the client says it is.
|
||||
|
||||
(*) ACK'ing is handled by the protocol driver automatically, including ping
|
||||
replying.
|
||||
|
||||
(*) SO_KEEPALIVE automatically pings the other side to keep the connection
|
||||
alive [TODO].
|
||||
|
||||
(*) If an ICMP error is received, all calls affected by that error will be
|
||||
aborted with an appropriate network error passed through recvmsg().
|
||||
|
||||
|
||||
Interaction with the user of the RxRPC socket:
|
||||
|
||||
(*) A socket is made into a server socket by binding an address with a
|
||||
non-zero service ID.
|
||||
|
||||
(*) In the client, sending a request is achieved with one or more sendmsgs,
|
||||
followed by the reply being received with one or more recvmsgs.
|
||||
|
||||
(*) The first sendmsg for a request to be sent from a client contains a tag to
|
||||
be used in all other sendmsgs or recvmsgs associated with that call. The
|
||||
tag is carried in the control data.
|
||||
|
||||
(*) connect() is used to supply a default destination address for a client
|
||||
socket. This may be overridden by supplying an alternate address to the
|
||||
first sendmsg() of a call (struct msghdr::msg_name).
|
||||
|
||||
(*) If connect() is called on an unbound client, a random local port will
|
||||
bound before the operation takes place.
|
||||
|
||||
(*) A server socket may also be used to make client calls. To do this, the
|
||||
first sendmsg() of the call must specify the target address. The server's
|
||||
transport endpoint is used to send the packets.
|
||||
|
||||
(*) Once the application has received the last message associated with a call,
|
||||
the tag is guaranteed not to be seen again, and so it can be used to pin
|
||||
client resources. A new call can then be initiated with the same tag
|
||||
without fear of interference.
|
||||
|
||||
(*) In the server, a request is received with one or more recvmsgs, then the
|
||||
the reply is transmitted with one or more sendmsgs, and then the final ACK
|
||||
is received with a last recvmsg.
|
||||
|
||||
(*) When sending data for a call, sendmsg is given MSG_MORE if there's more
|
||||
data to come on that call.
|
||||
|
||||
(*) When receiving data for a call, recvmsg flags MSG_MORE if there's more
|
||||
data to come for that call.
|
||||
|
||||
(*) When receiving data or messages for a call, MSG_EOR is flagged by recvmsg
|
||||
to indicate the terminal message for that call.
|
||||
|
||||
(*) A call may be aborted by adding an abort control message to the control
|
||||
data. Issuing an abort terminates the kernel's use of that call's tag.
|
||||
Any messages waiting in the receive queue for that call will be discarded.
|
||||
|
||||
(*) Aborts, busy notifications and challenge packets are delivered by recvmsg,
|
||||
and control data messages will be set to indicate the context. Receiving
|
||||
an abort or a busy message terminates the kernel's use of that call's tag.
|
||||
|
||||
(*) The control data part of the msghdr struct is used for a number of things:
|
||||
|
||||
(*) The tag of the intended or affected call.
|
||||
|
||||
(*) Sending or receiving errors, aborts and busy notifications.
|
||||
|
||||
(*) Notifications of incoming calls.
|
||||
|
||||
(*) Sending debug requests and receiving debug replies [TODO].
|
||||
|
||||
(*) When the kernel has received and set up an incoming call, it sends a
|
||||
message to server application to let it know there's a new call awaiting
|
||||
its acceptance [recvmsg reports a special control message]. The server
|
||||
application then uses sendmsg to assign a tag to the new call. Once that
|
||||
is done, the first part of the request data will be delivered by recvmsg.
|
||||
|
||||
(*) The server application has to provide the server socket with a keyring of
|
||||
secret keys corresponding to the security types it permits. When a secure
|
||||
connection is being set up, the kernel looks up the appropriate secret key
|
||||
in the keyring and then sends a challenge packet to the client and
|
||||
receives a response packet. The kernel then checks the authorisation of
|
||||
the packet and either aborts the connection or sets up the security.
|
||||
|
||||
(*) The name of the key a client will use to secure its communications is
|
||||
nominated by a socket option.
|
||||
|
||||
|
||||
Notes on recvmsg:
|
||||
|
||||
(*) If there's a sequence of data messages belonging to a particular call on
|
||||
the receive queue, then recvmsg will keep working through them until:
|
||||
|
||||
(a) it meets the end of that call's received data,
|
||||
|
||||
(b) it meets a non-data message,
|
||||
|
||||
(c) it meets a message belonging to a different call, or
|
||||
|
||||
(d) it fills the user buffer.
|
||||
|
||||
If recvmsg is called in blocking mode, it will keep sleeping, awaiting the
|
||||
reception of further data, until one of the above four conditions is met.
|
||||
|
||||
(2) MSG_PEEK operates similarly, but will return immediately if it has put any
|
||||
data in the buffer rather than sleeping until it can fill the buffer.
|
||||
|
||||
(3) If a data message is only partially consumed in filling a user buffer,
|
||||
then the remainder of that message will be left on the front of the queue
|
||||
for the next taker. MSG_TRUNC will never be flagged.
|
||||
|
||||
(4) If there is more data to be had on a call (it hasn't copied the last byte
|
||||
of the last data message in that phase yet), then MSG_MORE will be
|
||||
flagged.
|
||||
|
||||
|
||||
================
|
||||
CONTROL MESSAGES
|
||||
================
|
||||
|
||||
AF_RXRPC makes use of control messages in sendmsg() and recvmsg() to multiplex
|
||||
calls, to invoke certain actions and to report certain conditions. These are:
|
||||
|
||||
MESSAGE ID SRT DATA MEANING
|
||||
======================= === =========== ===============================
|
||||
RXRPC_USER_CALL_ID sr- User ID App's call specifier
|
||||
RXRPC_ABORT srt Abort code Abort code to issue/received
|
||||
RXRPC_ACK -rt n/a Final ACK received
|
||||
RXRPC_NET_ERROR -rt error num Network error on call
|
||||
RXRPC_BUSY -rt n/a Call rejected (server busy)
|
||||
RXRPC_LOCAL_ERROR -rt error num Local error encountered
|
||||
RXRPC_NEW_CALL -r- n/a New call received
|
||||
RXRPC_ACCEPT s-- n/a Accept new call
|
||||
|
||||
(SRT = usable in Sendmsg / delivered by Recvmsg / Terminal message)
|
||||
|
||||
(*) RXRPC_USER_CALL_ID
|
||||
|
||||
This is used to indicate the application's call ID. It's an unsigned long
|
||||
that the app specifies in the client by attaching it to the first data
|
||||
message or in the server by passing it in association with an RXRPC_ACCEPT
|
||||
message. recvmsg() passes it in conjunction with all messages except
|
||||
those of the RXRPC_NEW_CALL message.
|
||||
|
||||
(*) RXRPC_ABORT
|
||||
|
||||
This is can be used by an application to abort a call by passing it to
|
||||
sendmsg, or it can be delivered by recvmsg to indicate a remote abort was
|
||||
received. Either way, it must be associated with an RXRPC_USER_CALL_ID to
|
||||
specify the call affected. If an abort is being sent, then error EBADSLT
|
||||
will be returned if there is no call with that user ID.
|
||||
|
||||
(*) RXRPC_ACK
|
||||
|
||||
This is delivered to a server application to indicate that the final ACK
|
||||
of a call was received from the client. It will be associated with an
|
||||
RXRPC_USER_CALL_ID to indicate the call that's now complete.
|
||||
|
||||
(*) RXRPC_NET_ERROR
|
||||
|
||||
This is delivered to an application to indicate that an ICMP error message
|
||||
was encountered in the process of trying to talk to the peer. An
|
||||
errno-class integer value will be included in the control message data
|
||||
indicating the problem, and an RXRPC_USER_CALL_ID will indicate the call
|
||||
affected.
|
||||
|
||||
(*) RXRPC_BUSY
|
||||
|
||||
This is delivered to a client application to indicate that a call was
|
||||
rejected by the server due to the server being busy. It will be
|
||||
associated with an RXRPC_USER_CALL_ID to indicate the rejected call.
|
||||
|
||||
(*) RXRPC_LOCAL_ERROR
|
||||
|
||||
This is delivered to an application to indicate that a local error was
|
||||
encountered and that a call has been aborted because of it. An
|
||||
errno-class integer value will be included in the control message data
|
||||
indicating the problem, and an RXRPC_USER_CALL_ID will indicate the call
|
||||
affected.
|
||||
|
||||
(*) RXRPC_NEW_CALL
|
||||
|
||||
This is delivered to indicate to a server application that a new call has
|
||||
arrived and is awaiting acceptance. No user ID is associated with this,
|
||||
as a user ID must subsequently be assigned by doing an RXRPC_ACCEPT.
|
||||
|
||||
(*) RXRPC_ACCEPT
|
||||
|
||||
This is used by a server application to attempt to accept a call and
|
||||
assign it a user ID. It should be associated with an RXRPC_USER_CALL_ID
|
||||
to indicate the user ID to be assigned. If there is no call to be
|
||||
accepted (it may have timed out, been aborted, etc.), then sendmsg will
|
||||
return error ENODATA. If the user ID is already in use by another call,
|
||||
then error EBADSLT will be returned.
|
||||
|
||||
|
||||
==============
|
||||
SOCKET OPTIONS
|
||||
==============
|
||||
|
||||
AF_RXRPC sockets support a few socket options at the SOL_RXRPC level:
|
||||
|
||||
(*) RXRPC_SECURITY_KEY
|
||||
|
||||
This is used to specify the description of the key to be used. The key is
|
||||
extracted from the calling process's keyrings with request_key() and
|
||||
should be of "rxrpc" type.
|
||||
|
||||
The optval pointer points to the description string, and optlen indicates
|
||||
how long the string is, without the NUL terminator.
|
||||
|
||||
(*) RXRPC_SECURITY_KEYRING
|
||||
|
||||
Similar to above but specifies a keyring of server secret keys to use (key
|
||||
type "keyring"). See the "Security" section.
|
||||
|
||||
(*) RXRPC_EXCLUSIVE_CONNECTION
|
||||
|
||||
This is used to request that new connections should be used for each call
|
||||
made subsequently on this socket. optval should be NULL and optlen 0.
|
||||
|
||||
(*) RXRPC_MIN_SECURITY_LEVEL
|
||||
|
||||
This is used to specify the minimum security level required for calls on
|
||||
this socket. optval must point to an int containing one of the following
|
||||
values:
|
||||
|
||||
(a) RXRPC_SECURITY_PLAIN
|
||||
|
||||
Encrypted checksum only.
|
||||
|
||||
(b) RXRPC_SECURITY_AUTH
|
||||
|
||||
Encrypted checksum plus packet padded and first eight bytes of packet
|
||||
encrypted - which includes the actual packet length.
|
||||
|
||||
(c) RXRPC_SECURITY_ENCRYPTED
|
||||
|
||||
Encrypted checksum plus entire packet padded and encrypted, including
|
||||
actual packet length.
|
||||
|
||||
|
||||
========
|
||||
SECURITY
|
||||
========
|
||||
|
||||
Currently, only the kerberos 4 equivalent protocol has been implemented
|
||||
(security index 2 - rxkad). This requires the rxkad module to be loaded and,
|
||||
on the client, tickets of the appropriate type to be obtained from the AFS
|
||||
kaserver or the kerberos server and installed as "rxrpc" type keys. This is
|
||||
normally done using the klog program. An example simple klog program can be
|
||||
found at:
|
||||
|
||||
http://people.redhat.com/~dhowells/rxrpc/klog.c
|
||||
|
||||
The payload provided to add_key() on the client should be of the following
|
||||
form:
|
||||
|
||||
struct rxrpc_key_sec2_v1 {
|
||||
uint16_t security_index; /* 2 */
|
||||
uint16_t ticket_length; /* length of ticket[] */
|
||||
uint32_t expiry; /* time at which expires */
|
||||
uint8_t kvno; /* key version number */
|
||||
uint8_t __pad[3];
|
||||
uint8_t session_key[8]; /* DES session key */
|
||||
uint8_t ticket[0]; /* the encrypted ticket */
|
||||
};
|
||||
|
||||
Where the ticket blob is just appended to the above structure.
|
||||
|
||||
|
||||
For the server, keys of type "rxrpc_s" must be made available to the server.
|
||||
They have a description of "<serviceID>:<securityIndex>" (eg: "52:2" for an
|
||||
rxkad key for the AFS VL service). When such a key is created, it should be
|
||||
given the server's secret key as the instantiation data (see the example
|
||||
below).
|
||||
|
||||
add_key("rxrpc_s", "52:2", secret_key, 8, keyring);
|
||||
|
||||
A keyring is passed to the server socket by naming it in a sockopt. The server
|
||||
socket then looks the server secret keys up in this keyring when secure
|
||||
incoming connections are made. This can be seen in an example program that can
|
||||
be found at:
|
||||
|
||||
http://people.redhat.com/~dhowells/rxrpc/listen.c
|
||||
|
||||
|
||||
====================
|
||||
EXAMPLE CLIENT USAGE
|
||||
====================
|
||||
|
||||
A client would issue an operation by:
|
||||
|
||||
(1) An RxRPC socket is set up by:
|
||||
|
||||
client = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);
|
||||
|
||||
Where the third parameter indicates the protocol family of the transport
|
||||
socket used - usually IPv4 but it can also be IPv6 [TODO].
|
||||
|
||||
(2) A local address can optionally be bound:
|
||||
|
||||
struct sockaddr_rxrpc srx = {
|
||||
.srx_family = AF_RXRPC,
|
||||
.srx_service = 0, /* we're a client */
|
||||
.transport_type = SOCK_DGRAM, /* type of transport socket */
|
||||
.transport.sin_family = AF_INET,
|
||||
.transport.sin_port = htons(7000), /* AFS callback */
|
||||
.transport.sin_address = 0, /* all local interfaces */
|
||||
};
|
||||
bind(client, &srx, sizeof(srx));
|
||||
|
||||
This specifies the local UDP port to be used. If not given, a random
|
||||
non-privileged port will be used. A UDP port may be shared between
|
||||
several unrelated RxRPC sockets. Security is handled on a basis of
|
||||
per-RxRPC virtual connection.
|
||||
|
||||
(3) The security is set:
|
||||
|
||||
const char *key = "AFS:cambridge.redhat.com";
|
||||
setsockopt(client, SOL_RXRPC, RXRPC_SECURITY_KEY, key, strlen(key));
|
||||
|
||||
This issues a request_key() to get the key representing the security
|
||||
context. The minimum security level can be set:
|
||||
|
||||
unsigned int sec = RXRPC_SECURITY_ENCRYPTED;
|
||||
setsockopt(client, SOL_RXRPC, RXRPC_MIN_SECURITY_LEVEL,
|
||||
&sec, sizeof(sec));
|
||||
|
||||
(4) The server to be contacted can then be specified (alternatively this can
|
||||
be done through sendmsg):
|
||||
|
||||
struct sockaddr_rxrpc srx = {
|
||||
.srx_family = AF_RXRPC,
|
||||
.srx_service = VL_SERVICE_ID,
|
||||
.transport_type = SOCK_DGRAM, /* type of transport socket */
|
||||
.transport.sin_family = AF_INET,
|
||||
.transport.sin_port = htons(7005), /* AFS volume manager */
|
||||
.transport.sin_address = ...,
|
||||
};
|
||||
connect(client, &srx, sizeof(srx));
|
||||
|
||||
(5) The request data should then be posted to the server socket using a series
|
||||
of sendmsg() calls, each with the following control message attached:
|
||||
|
||||
RXRPC_USER_CALL_ID - specifies the user ID for this call
|
||||
|
||||
MSG_MORE should be set in msghdr::msg_flags on all but the last part of
|
||||
the request. Multiple requests may be made simultaneously.
|
||||
|
||||
If a call is intended to go to a destination other then the default
|
||||
specified through connect(), then msghdr::msg_name should be set on the
|
||||
first request message of that call.
|
||||
|
||||
(6) The reply data will then be posted to the server socket for recvmsg() to
|
||||
pick up. MSG_MORE will be flagged by recvmsg() if there's more reply data
|
||||
for a particular call to be read. MSG_EOR will be set on the terminal
|
||||
read for a call.
|
||||
|
||||
All data will be delivered with the following control message attached:
|
||||
|
||||
RXRPC_USER_CALL_ID - specifies the user ID for this call
|
||||
|
||||
If an abort or error occurred, this will be returned in the control data
|
||||
buffer instead, and MSG_EOR will be flagged to indicate the end of that
|
||||
call.
|
||||
|
||||
|
||||
====================
|
||||
EXAMPLE SERVER USAGE
|
||||
====================
|
||||
|
||||
A server would be set up to accept operations in the following manner:
|
||||
|
||||
(1) An RxRPC socket is created by:
|
||||
|
||||
server = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);
|
||||
|
||||
Where the third parameter indicates the address type of the transport
|
||||
socket used - usually IPv4.
|
||||
|
||||
(2) Security is set up if desired by giving the socket a keyring with server
|
||||
secret keys in it:
|
||||
|
||||
keyring = add_key("keyring", "AFSkeys", NULL, 0,
|
||||
KEY_SPEC_PROCESS_KEYRING);
|
||||
|
||||
const char secret_key[8] = {
|
||||
0xa7, 0x83, 0x8a, 0xcb, 0xc7, 0x83, 0xec, 0x94 };
|
||||
add_key("rxrpc_s", "52:2", secret_key, 8, keyring);
|
||||
|
||||
setsockopt(server, SOL_RXRPC, RXRPC_SECURITY_KEYRING, "AFSkeys", 7);
|
||||
|
||||
The keyring can be manipulated after it has been given to the socket. This
|
||||
permits the server to add more keys, replace keys, etc. whilst it is live.
|
||||
|
||||
(2) A local address must then be bound:
|
||||
|
||||
struct sockaddr_rxrpc srx = {
|
||||
.srx_family = AF_RXRPC,
|
||||
.srx_service = VL_SERVICE_ID, /* RxRPC service ID */
|
||||
.transport_type = SOCK_DGRAM, /* type of transport socket */
|
||||
.transport.sin_family = AF_INET,
|
||||
.transport.sin_port = htons(7000), /* AFS callback */
|
||||
.transport.sin_address = 0, /* all local interfaces */
|
||||
};
|
||||
bind(server, &srx, sizeof(srx));
|
||||
|
||||
(3) The server is then set to listen out for incoming calls:
|
||||
|
||||
listen(server, 100);
|
||||
|
||||
(4) The kernel notifies the server of pending incoming connections by sending
|
||||
it a message for each. This is received with recvmsg() on the server
|
||||
socket. It has no data, and has a single dataless control message
|
||||
attached:
|
||||
|
||||
RXRPC_NEW_CALL
|
||||
|
||||
The address that can be passed back by recvmsg() at this point should be
|
||||
ignored since the call for which the message was posted may have gone by
|
||||
the time it is accepted - in which case the first call still on the queue
|
||||
will be accepted.
|
||||
|
||||
(5) The server then accepts the new call by issuing a sendmsg() with two
|
||||
pieces of control data and no actual data:
|
||||
|
||||
RXRPC_ACCEPT - indicate connection acceptance
|
||||
RXRPC_USER_CALL_ID - specify user ID for this call
|
||||
|
||||
(6) The first request data packet will then be posted to the server socket for
|
||||
recvmsg() to pick up. At that point, the RxRPC address for the call can
|
||||
be read from the address fields in the msghdr struct.
|
||||
|
||||
Subsequent request data will be posted to the server socket for recvmsg()
|
||||
to collect as it arrives. All but the last piece of the request data will
|
||||
be delivered with MSG_MORE flagged.
|
||||
|
||||
All data will be delivered with the following control message attached:
|
||||
|
||||
RXRPC_USER_CALL_ID - specifies the user ID for this call
|
||||
|
||||
(8) The reply data should then be posted to the server socket using a series
|
||||
of sendmsg() calls, each with the following control messages attached:
|
||||
|
||||
RXRPC_USER_CALL_ID - specifies the user ID for this call
|
||||
|
||||
MSG_MORE should be set in msghdr::msg_flags on all but the last message
|
||||
for a particular call.
|
||||
|
||||
(9) The final ACK from the client will be posted for retrieval by recvmsg()
|
||||
when it is received. It will take the form of a dataless message with two
|
||||
control messages attached:
|
||||
|
||||
RXRPC_USER_CALL_ID - specifies the user ID for this call
|
||||
RXRPC_ACK - indicates final ACK (no data)
|
||||
|
||||
MSG_EOR will be flagged to indicate that this is the final message for
|
||||
this call.
|
||||
|
||||
(10) Up to the point the final packet of reply data is sent, the call can be
|
||||
aborted by calling sendmsg() with a dataless message with the following
|
||||
control messages attached:
|
||||
|
||||
RXRPC_USER_CALL_ID - specifies the user ID for this call
|
||||
RXRPC_ABORT - indicates abort code (4 byte data)
|
||||
|
||||
Any packets waiting in the socket's receive queue will be discarded if
|
||||
this is issued.
|
||||
|
||||
Note that all the communications for a particular service take place through
|
||||
the one server socket, using control messages on sendmsg() and recvmsg() to
|
||||
determine the call affected.
|
||||
|
||||
|
||||
=========================
|
||||
AF_RXRPC KERNEL INTERFACE
|
||||
=========================
|
||||
|
||||
The AF_RXRPC module also provides an interface for use by in-kernel utilities
|
||||
such as the AFS filesystem. This permits such a utility to:
|
||||
|
||||
(1) Use different keys directly on individual client calls on one socket
|
||||
rather than having to open a whole slew of sockets, one for each key it
|
||||
might want to use.
|
||||
|
||||
(2) Avoid having RxRPC call request_key() at the point of issue of a call or
|
||||
opening of a socket. Instead the utility is responsible for requesting a
|
||||
key at the appropriate point. AFS, for instance, would do this during VFS
|
||||
operations such as open() or unlink(). The key is then handed through
|
||||
when the call is initiated.
|
||||
|
||||
(3) Request the use of something other than GFP_KERNEL to allocate memory.
|
||||
|
||||
(4) Avoid the overhead of using the recvmsg() call. RxRPC messages can be
|
||||
intercepted before they get put into the socket Rx queue and the socket
|
||||
buffers manipulated directly.
|
||||
|
||||
To use the RxRPC facility, a kernel utility must still open an AF_RXRPC socket,
|
||||
bind an addess as appropriate and listen if it's to be a server socket, but
|
||||
then it passes this to the kernel interface functions.
|
||||
|
||||
The kernel interface functions are as follows:
|
||||
|
||||
(*) Begin a new client call.
|
||||
|
||||
struct rxrpc_call *
|
||||
rxrpc_kernel_begin_call(struct socket *sock,
|
||||
struct sockaddr_rxrpc *srx,
|
||||
struct key *key,
|
||||
unsigned long user_call_ID,
|
||||
gfp_t gfp);
|
||||
|
||||
This allocates the infrastructure to make a new RxRPC call and assigns
|
||||
call and connection numbers. The call will be made on the UDP port that
|
||||
the socket is bound to. The call will go to the destination address of a
|
||||
connected client socket unless an alternative is supplied (srx is
|
||||
non-NULL).
|
||||
|
||||
If a key is supplied then this will be used to secure the call instead of
|
||||
the key bound to the socket with the RXRPC_SECURITY_KEY sockopt. Calls
|
||||
secured in this way will still share connections if at all possible.
|
||||
|
||||
The user_call_ID is equivalent to that supplied to sendmsg() in the
|
||||
control data buffer. It is entirely feasible to use this to point to a
|
||||
kernel data structure.
|
||||
|
||||
If this function is successful, an opaque reference to the RxRPC call is
|
||||
returned. The caller now holds a reference on this and it must be
|
||||
properly ended.
|
||||
|
||||
(*) End a client call.
|
||||
|
||||
void rxrpc_kernel_end_call(struct rxrpc_call *call);
|
||||
|
||||
This is used to end a previously begun call. The user_call_ID is expunged
|
||||
from AF_RXRPC's knowledge and will not be seen again in association with
|
||||
the specified call.
|
||||
|
||||
(*) Send data through a call.
|
||||
|
||||
int rxrpc_kernel_send_data(struct rxrpc_call *call, struct msghdr *msg,
|
||||
size_t len);
|
||||
|
||||
This is used to supply either the request part of a client call or the
|
||||
reply part of a server call. msg.msg_iovlen and msg.msg_iov specify the
|
||||
data buffers to be used. msg_iov may not be NULL and must point
|
||||
exclusively to in-kernel virtual addresses. msg.msg_flags may be given
|
||||
MSG_MORE if there will be subsequent data sends for this call.
|
||||
|
||||
The msg must not specify a destination address, control data or any flags
|
||||
other than MSG_MORE. len is the total amount of data to transmit.
|
||||
|
||||
(*) Abort a call.
|
||||
|
||||
void rxrpc_kernel_abort_call(struct rxrpc_call *call, u32 abort_code);
|
||||
|
||||
This is used to abort a call if it's still in an abortable state. The
|
||||
abort code specified will be placed in the ABORT message sent.
|
||||
|
||||
(*) Intercept received RxRPC messages.
|
||||
|
||||
typedef void (*rxrpc_interceptor_t)(struct sock *sk,
|
||||
unsigned long user_call_ID,
|
||||
struct sk_buff *skb);
|
||||
|
||||
void
|
||||
rxrpc_kernel_intercept_rx_messages(struct socket *sock,
|
||||
rxrpc_interceptor_t interceptor);
|
||||
|
||||
This installs an interceptor function on the specified AF_RXRPC socket.
|
||||
All messages that would otherwise wind up in the socket's Rx queue are
|
||||
then diverted to this function. Note that care must be taken to process
|
||||
the messages in the right order to maintain DATA message sequentiality.
|
||||
|
||||
The interceptor function itself is provided with the address of the socket
|
||||
and handling the incoming message, the ID assigned by the kernel utility
|
||||
to the call and the socket buffer containing the message.
|
||||
|
||||
The skb->mark field indicates the type of message:
|
||||
|
||||
MARK MEANING
|
||||
=============================== =======================================
|
||||
RXRPC_SKB_MARK_DATA Data message
|
||||
RXRPC_SKB_MARK_FINAL_ACK Final ACK received for an incoming call
|
||||
RXRPC_SKB_MARK_BUSY Client call rejected as server busy
|
||||
RXRPC_SKB_MARK_REMOTE_ABORT Call aborted by peer
|
||||
RXRPC_SKB_MARK_NET_ERROR Network error detected
|
||||
RXRPC_SKB_MARK_LOCAL_ERROR Local error encountered
|
||||
RXRPC_SKB_MARK_NEW_CALL New incoming call awaiting acceptance
|
||||
|
||||
The remote abort message can be probed with rxrpc_kernel_get_abort_code().
|
||||
The two error messages can be probed with rxrpc_kernel_get_error_number().
|
||||
A new call can be accepted with rxrpc_kernel_accept_call().
|
||||
|
||||
Data messages can have their contents extracted with the usual bunch of
|
||||
socket buffer manipulation functions. A data message can be determined to
|
||||
be the last one in a sequence with rxrpc_kernel_is_data_last(). When a
|
||||
data message has been used up, rxrpc_kernel_data_delivered() should be
|
||||
called on it..
|
||||
|
||||
Non-data messages should be handled to rxrpc_kernel_free_skb() to dispose
|
||||
of. It is possible to get extra refs on all types of message for later
|
||||
freeing, but this may pin the state of a call until the message is finally
|
||||
freed.
|
||||
|
||||
(*) Accept an incoming call.
|
||||
|
||||
struct rxrpc_call *
|
||||
rxrpc_kernel_accept_call(struct socket *sock,
|
||||
unsigned long user_call_ID);
|
||||
|
||||
This is used to accept an incoming call and to assign it a call ID. This
|
||||
function is similar to rxrpc_kernel_begin_call() and calls accepted must
|
||||
be ended in the same way.
|
||||
|
||||
If this function is successful, an opaque reference to the RxRPC call is
|
||||
returned. The caller now holds a reference on this and it must be
|
||||
properly ended.
|
||||
|
||||
(*) Reject an incoming call.
|
||||
|
||||
int rxrpc_kernel_reject_call(struct socket *sock);
|
||||
|
||||
This is used to reject the first incoming call on the socket's queue with
|
||||
a BUSY message. -ENODATA is returned if there were no incoming calls.
|
||||
Other errors may be returned if the call had been aborted (-ECONNABORTED)
|
||||
or had timed out (-ETIME).
|
||||
|
||||
(*) Record the delivery of a data message and free it.
|
||||
|
||||
void rxrpc_kernel_data_delivered(struct sk_buff *skb);
|
||||
|
||||
This is used to record a data message as having been delivered and to
|
||||
update the ACK state for the call. The socket buffer will be freed.
|
||||
|
||||
(*) Free a message.
|
||||
|
||||
void rxrpc_kernel_free_skb(struct sk_buff *skb);
|
||||
|
||||
This is used to free a non-DATA socket buffer intercepted from an AF_RXRPC
|
||||
socket.
|
||||
|
||||
(*) Determine if a data message is the last one on a call.
|
||||
|
||||
bool rxrpc_kernel_is_data_last(struct sk_buff *skb);
|
||||
|
||||
This is used to determine if a socket buffer holds the last data message
|
||||
to be received for a call (true will be returned if it does, false
|
||||
if not).
|
||||
|
||||
The data message will be part of the reply on a client call and the
|
||||
request on an incoming call. In the latter case there will be more
|
||||
messages, but in the former case there will not.
|
||||
|
||||
(*) Get the abort code from an abort message.
|
||||
|
||||
u32 rxrpc_kernel_get_abort_code(struct sk_buff *skb);
|
||||
|
||||
This is used to extract the abort code from a remote abort message.
|
||||
|
||||
(*) Get the error number from a local or network error message.
|
||||
|
||||
int rxrpc_kernel_get_error_number(struct sk_buff *skb);
|
||||
|
||||
This is used to extract the error number from a message indicating either
|
||||
a local error occurred or a network error occurred.
|
@ -250,7 +250,6 @@ PRODUCT COMPONENTS AND RELATED FILES
|
||||
sdladrv.h SDLA support module API definitions
|
||||
sdlasfm.h SDLA firmware module definitions
|
||||
if_wanpipe.h WANPIPE Socket definitions
|
||||
if_wanpipe_common.h WANPIPE Socket/Driver common definitions.
|
||||
sdlapci.h WANPIPE PCI definitions
|
||||
|
||||
|
||||
|
@ -18,17 +18,10 @@ states.
|
||||
|
||||
|
||||
/sys/power/disk controls the operating mode of the suspend-to-disk
|
||||
mechanism. Suspend-to-disk can be handled in several ways. The
|
||||
greatest distinction is who writes memory to disk - the firmware or
|
||||
the kernel. If the firmware does it, we assume that it also handles
|
||||
suspending the system.
|
||||
|
||||
If the kernel does it, then we have three options for putting the system
|
||||
to sleep - using the platform driver (e.g. ACPI or other PM
|
||||
registers), powering off the system or rebooting the system (for
|
||||
testing). The system will support either 'firmware' or 'platform', and
|
||||
that is known a priori. But, the user may choose 'shutdown' or
|
||||
'reboot' as alternatives.
|
||||
mechanism. Suspend-to-disk can be handled in several ways. We have a
|
||||
few options for putting the system to sleep - using the platform driver
|
||||
(e.g. ACPI or other pm_ops), powering off the system or rebooting the
|
||||
system (for testing).
|
||||
|
||||
Additionally, /sys/power/disk can be used to turn on one of the two testing
|
||||
modes of the suspend-to-disk mechanism: 'testproc' or 'test'. If the
|
||||
@ -44,16 +37,12 @@ is being slow and which device drivers are misbehaving.
|
||||
Reading from this file will display what the mode is currently set
|
||||
to. Writing to this file will accept one of
|
||||
|
||||
'firmware'
|
||||
'platform'
|
||||
'platform' (only if the platform supports it)
|
||||
'shutdown'
|
||||
'reboot'
|
||||
'testproc'
|
||||
'test'
|
||||
|
||||
It will only change to 'firmware' or 'platform' if the system supports
|
||||
it.
|
||||
|
||||
/sys/power/image_size controls the size of the image created by
|
||||
the suspend-to-disk mechanism. It can be written a string
|
||||
representing a non-negative integer that will be used as an upper
|
||||
|
@ -102,31 +102,28 @@ pci_save_state
|
||||
--------------
|
||||
|
||||
Usage:
|
||||
pci_save_state(dev, buffer);
|
||||
pci_save_state(struct pci_dev *dev);
|
||||
|
||||
Description:
|
||||
Save first 64 bytes of PCI config space. Buffer must be allocated by
|
||||
caller.
|
||||
Save first 64 bytes of PCI config space, along with any additional
|
||||
PCI-Express or PCI-X information.
|
||||
|
||||
|
||||
pci_restore_state
|
||||
-----------------
|
||||
|
||||
Usage:
|
||||
pci_restore_state(dev, buffer);
|
||||
pci_restore_state(struct pci_dev *dev);
|
||||
|
||||
Description:
|
||||
Restore previously saved config space. (First 64 bytes only);
|
||||
|
||||
If buffer is NULL, then restore what information we know about the
|
||||
device from bootup: BARs and interrupt line.
|
||||
Restore previously saved config space.
|
||||
|
||||
|
||||
pci_set_power_state
|
||||
-------------------
|
||||
|
||||
Usage:
|
||||
pci_set_power_state(dev, state);
|
||||
pci_set_power_state(struct pci_dev *dev, pci_power_t state);
|
||||
|
||||
Description:
|
||||
Transition device to low power state using PCI PM Capabilities
|
||||
@ -142,7 +139,7 @@ pci_enable_wake
|
||||
---------------
|
||||
|
||||
Usage:
|
||||
pci_enable_wake(dev, state, enable);
|
||||
pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
|
||||
|
||||
Description:
|
||||
Enable device to generate PME# during low power state using PCI PM
|
||||
|
@ -62,17 +62,18 @@ setup via another operating system for it to use. Despite the
|
||||
inconvenience, this method requires minimal work by the kernel, since
|
||||
the firmware will also handle restoring memory contents on resume.
|
||||
|
||||
If the kernel is responsible for persistently saving state, a mechanism
|
||||
called 'swsusp' (Swap Suspend) is used to write memory contents to
|
||||
free swap space. swsusp has some restrictive requirements, but should
|
||||
work in most cases. Some, albeit outdated, documentation can be found
|
||||
in Documentation/power/swsusp.txt.
|
||||
For suspend-to-disk, a mechanism called swsusp called 'swsusp' (Swap
|
||||
Suspend) is used to write memory contents to free swap space.
|
||||
swsusp has some restrictive requirements, but should work in most
|
||||
cases. Some, albeit outdated, documentation can be found in
|
||||
Documentation/power/swsusp.txt. Alternatively, userspace can do most
|
||||
of the actual suspend to disk work, see userland-swsusp.txt.
|
||||
|
||||
Once memory state is written to disk, the system may either enter a
|
||||
low-power state (like ACPI S4), or it may simply power down. Powering
|
||||
down offers greater savings, and allows this mechanism to work on any
|
||||
system. However, entering a real low-power state allows the user to
|
||||
trigger wake up events (e.g. pressing a key or opening a laptop lid).
|
||||
trigger wake up events (e.g. pressing a key or opening a laptop lid).
|
||||
|
||||
A transition from Suspend-to-Disk to the On state should take about 30
|
||||
seconds, though it's typically a bit more with the current
|
||||
|
@ -156,8 +156,7 @@ instead set the PF_NOFREEZE process flag when creating the thread (and
|
||||
be very careful).
|
||||
|
||||
|
||||
Q: What is the difference between "platform", "shutdown" and
|
||||
"firmware" in /sys/power/disk?
|
||||
Q: What is the difference between "platform" and "shutdown"?
|
||||
|
||||
A:
|
||||
|
||||
@ -166,11 +165,8 @@ shutdown: save state in linux, then tell bios to powerdown
|
||||
platform: save state in linux, then tell bios to powerdown and blink
|
||||
"suspended led"
|
||||
|
||||
firmware: tell bios to save state itself [needs BIOS-specific suspend
|
||||
partition, and has very little to do with swsusp]
|
||||
|
||||
"platform" is actually right thing to do, but "shutdown" is most
|
||||
reliable.
|
||||
"platform" is actually right thing to do where supported, but
|
||||
"shutdown" is most reliable (except on ACPI systems).
|
||||
|
||||
Q: I do not understand why you have such strong objections to idea of
|
||||
selective suspend.
|
||||
@ -388,8 +384,8 @@ while the system is asleep, maintaining the connection, using true sleep
|
||||
modes like "suspend-to-RAM" or "standby". (Don't write "disk" to the
|
||||
/sys/power/state file; write "standby" or "mem".) We've not seen any
|
||||
hardware that can use these modes through software suspend, although in
|
||||
theory some systems might support "platform" or "firmware" modes that
|
||||
won't break the USB connections.
|
||||
theory some systems might support "platform" modes that won't break the
|
||||
USB connections.
|
||||
|
||||
Remember that it's always a bad idea to unplug a disk drive containing a
|
||||
mounted filesystem. That's true even when your system is asleep! The
|
||||
|
@ -39,7 +39,7 @@
|
||||
and property data. The old style variable
|
||||
alignment would make it impossible to do
|
||||
"simple" insertion of properties using
|
||||
memove (thanks Milton for
|
||||
memmove (thanks Milton for
|
||||
noticing). Updated kernel patch as well
|
||||
- Correct a few more alignment constraints
|
||||
- Add a chapter about the device-tree
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
ToDo:
|
||||
- Add some definitions of interrupt tree (simple/complex)
|
||||
- Add some definitions for pci host bridges
|
||||
- Add some definitions for PCI host bridges
|
||||
- Add some common address format examples
|
||||
- Add definitions for standard properties and "compatible"
|
||||
names for cells that are not already defined by the existing
|
||||
@ -114,7 +114,7 @@ it with special cases.
|
||||
forth words isn't required), you can enter the kernel with:
|
||||
|
||||
r5 : OF callback pointer as defined by IEEE 1275
|
||||
bindings to powerpc. Only the 32 bit client interface
|
||||
bindings to powerpc. Only the 32-bit client interface
|
||||
is currently supported
|
||||
|
||||
r3, r4 : address & length of an initrd if any or 0
|
||||
@ -194,7 +194,7 @@ it with special cases.
|
||||
for this is to keep kernels on embedded systems small and efficient;
|
||||
part of this is due to the fact the code is already that way. In the
|
||||
future, a kernel may support multiple platforms, but only if the
|
||||
platforms feature the same core architectire. A single kernel build
|
||||
platforms feature the same core architecture. A single kernel build
|
||||
cannot support both configurations with Book E and configurations
|
||||
with classic Powerpc architectures.
|
||||
|
||||
@ -215,7 +215,7 @@ of the boot sequences.... someone speak up if this is wrong!
|
||||
enable another config option to select the specific board
|
||||
supported.
|
||||
|
||||
NOTE: If ben doesn't merge the setup files, may need to change this to
|
||||
NOTE: If Ben doesn't merge the setup files, may need to change this to
|
||||
point to setup_32.c
|
||||
|
||||
|
||||
@ -256,7 +256,7 @@ struct boot_param_header {
|
||||
u32 off_dt_struct; /* offset to structure */
|
||||
u32 off_dt_strings; /* offset to strings */
|
||||
u32 off_mem_rsvmap; /* offset to memory reserve map
|
||||
*/
|
||||
*/
|
||||
u32 version; /* format version */
|
||||
u32 last_comp_version; /* last compatible version */
|
||||
|
||||
@ -265,6 +265,9 @@ struct boot_param_header {
|
||||
booting on */
|
||||
/* version 3 fields below */
|
||||
u32 size_dt_strings; /* size of the strings block */
|
||||
|
||||
/* version 17 fields below */
|
||||
u32 size_dt_struct; /* size of the DT structure block */
|
||||
};
|
||||
|
||||
Along with the constants:
|
||||
@ -273,7 +276,7 @@ struct boot_param_header {
|
||||
#define OF_DT_HEADER 0xd00dfeed /* 4: version,
|
||||
4: total size */
|
||||
#define OF_DT_BEGIN_NODE 0x1 /* Start node: full name
|
||||
*/
|
||||
*/
|
||||
#define OF_DT_END_NODE 0x2 /* End node */
|
||||
#define OF_DT_PROP 0x3 /* Property: name off,
|
||||
size, content */
|
||||
@ -310,9 +313,8 @@ struct boot_param_header {
|
||||
- off_mem_rsvmap
|
||||
|
||||
This is an offset from the beginning of the header to the start
|
||||
of the reserved memory map. This map is a list of pairs of 64
|
||||
of the reserved memory map. This map is a list of pairs of 64-
|
||||
bit integers. Each pair is a physical address and a size. The
|
||||
|
||||
list is terminated by an entry of size 0. This map provides the
|
||||
kernel with a list of physical memory areas that are "reserved"
|
||||
and thus not to be used for memory allocations, especially during
|
||||
@ -325,7 +327,7 @@ struct boot_param_header {
|
||||
contain _at least_ this DT block itself (header,total_size). If
|
||||
you are passing an initrd to the kernel, you should reserve it as
|
||||
well. You do not need to reserve the kernel image itself. The map
|
||||
should be 64 bit aligned.
|
||||
should be 64-bit aligned.
|
||||
|
||||
- version
|
||||
|
||||
@ -335,10 +337,13 @@ struct boot_param_header {
|
||||
to reallocate it easily at boot and free up the unused flattened
|
||||
structure after expansion. Version 16 introduces a new more
|
||||
"compact" format for the tree itself that is however not backward
|
||||
compatible. You should always generate a structure of the highest
|
||||
version defined at the time of your implementation. Currently
|
||||
that is version 16, unless you explicitly aim at being backward
|
||||
compatible.
|
||||
compatible. Version 17 adds an additional field, size_dt_struct,
|
||||
allowing it to be reallocated or moved more easily (this is
|
||||
particularly useful for bootloaders which need to make
|
||||
adjustments to a device tree based on probed information). You
|
||||
should always generate a structure of the highest version defined
|
||||
at the time of your implementation. Currently that is version 17,
|
||||
unless you explicitly aim at being backward compatible.
|
||||
|
||||
- last_comp_version
|
||||
|
||||
@ -347,7 +352,7 @@ struct boot_param_header {
|
||||
is backward compatible with version 1 (that is, a kernel build
|
||||
for version 1 will be able to boot with a version 2 format). You
|
||||
should put a 1 in this field if you generate a device tree of
|
||||
version 1 to 3, or 0x10 if you generate a tree of version 0x10
|
||||
version 1 to 3, or 16 if you generate a tree of version 16 or 17
|
||||
using the new unit name format.
|
||||
|
||||
- boot_cpuid_phys
|
||||
@ -360,6 +365,17 @@ struct boot_param_header {
|
||||
point (see further chapters for more informations on the required
|
||||
device-tree contents)
|
||||
|
||||
- size_dt_strings
|
||||
|
||||
This field only exists on version 3 and later headers. It
|
||||
gives the size of the "strings" section of the device tree (which
|
||||
starts at the offset given by off_dt_strings).
|
||||
|
||||
- size_dt_struct
|
||||
|
||||
This field only exists on version 17 and later headers. It gives
|
||||
the size of the "structure" section of the device tree (which
|
||||
starts at the offset given by off_dt_struct).
|
||||
|
||||
So the typical layout of a DT block (though the various parts don't
|
||||
need to be in that order) looks like this (addresses go from top to
|
||||
@ -417,7 +433,7 @@ root node who has no parent.
|
||||
A node has 2 names. The actual node name is generally contained in a
|
||||
property of type "name" in the node property list whose value is a
|
||||
zero terminated string and is mandatory for version 1 to 3 of the
|
||||
format definition (as it is in Open Firmware). Version 0x10 makes it
|
||||
format definition (as it is in Open Firmware). Version 16 makes it
|
||||
optional as it can generate it from the unit name defined below.
|
||||
|
||||
There is also a "unit name" that is used to differentiate nodes with
|
||||
@ -461,7 +477,7 @@ referencing another node via "phandle" is when laying out the
|
||||
interrupt tree which will be described in a further version of this
|
||||
document.
|
||||
|
||||
This "linux, phandle" property is a 32 bit value that uniquely
|
||||
This "linux, phandle" property is a 32-bit value that uniquely
|
||||
identifies a node. You are free to use whatever values or system of
|
||||
values, internal pointers, or whatever to generate these, the only
|
||||
requirement is that every node for which you provide that property has
|
||||
@ -471,7 +487,7 @@ Here is an example of a simple device-tree. In this example, an "o"
|
||||
designates a node followed by the node unit name. Properties are
|
||||
presented with their name followed by their content. "content"
|
||||
represents an ASCII string (zero terminated) value, while <content>
|
||||
represents a 32 bit hexadecimal value. The various nodes in this
|
||||
represents a 32-bit hexadecimal value. The various nodes in this
|
||||
example will be discussed in a later chapter. At this point, it is
|
||||
only meant to give you a idea of what a device-tree looks like. I have
|
||||
purposefully kept the "name" and "linux,phandle" properties which
|
||||
@ -543,15 +559,15 @@ Here's the basic structure of a single node:
|
||||
* [align gap to next 4 bytes boundary]
|
||||
* for each property:
|
||||
* token OF_DT_PROP (that is 0x00000003)
|
||||
* 32 bit value of property value size in bytes (or 0 of no
|
||||
* value)
|
||||
* 32 bit value of offset in string block of property name
|
||||
* 32-bit value of property value size in bytes (or 0 if no
|
||||
value)
|
||||
* 32-bit value of offset in string block of property name
|
||||
* property value data if any
|
||||
* [align gap to next 4 bytes boundary]
|
||||
* [child nodes if any]
|
||||
* token OF_DT_END_NODE (that is 0x00000002)
|
||||
|
||||
So the node content can be summarised as a start token, a full path,
|
||||
So the node content can be summarized as a start token, a full path,
|
||||
a list of properties, a list of child nodes, and an end token. Every
|
||||
child node is a full node structure itself as defined above.
|
||||
|
||||
@ -583,7 +599,7 @@ provide those properties yourself.
|
||||
----------------------------------------------
|
||||
|
||||
The general rule is documented in the various Open Firmware
|
||||
documentations. If you chose to describe a bus with the device-tree
|
||||
documentations. If you choose to describe a bus with the device-tree
|
||||
and there exist an OF bus binding, then you should follow the
|
||||
specification. However, the kernel does not require every single
|
||||
device or bus to be described by the device tree.
|
||||
@ -596,9 +612,9 @@ those properties defining addresses format for devices directly mapped
|
||||
on the processor bus.
|
||||
|
||||
Those 2 properties define 'cells' for representing an address and a
|
||||
size. A "cell" is a 32 bit number. For example, if both contain 2
|
||||
size. A "cell" is a 32-bit number. For example, if both contain 2
|
||||
like the example tree given above, then an address and a size are both
|
||||
composed of 2 cells, and each is a 64 bit number (cells are
|
||||
composed of 2 cells, and each is a 64-bit number (cells are
|
||||
concatenated and expected to be in big endian format). Another example
|
||||
is the way Apple firmware defines them, with 2 cells for an address
|
||||
and one cell for a size. Most 32-bit implementations should define
|
||||
@ -632,7 +648,7 @@ prom_parse.c file of the recent kernels for your bus type.
|
||||
|
||||
The "reg" property only defines addresses and sizes (if #size-cells
|
||||
is non-0) within a given bus. In order to translate addresses upward
|
||||
(that is into parent bus addresses, and possibly into cpu physical
|
||||
(that is into parent bus addresses, and possibly into CPU physical
|
||||
addresses), all busses must contain a "ranges" property. If the
|
||||
"ranges" property is missing at a given level, it's assumed that
|
||||
translation isn't possible. The format of the "ranges" property for a
|
||||
@ -648,9 +664,9 @@ example, for a PCI host controller, that would be a CPU address. For a
|
||||
PCI<->ISA bridge, that would be a PCI address. It defines the base
|
||||
address in the parent bus where the beginning of that range is mapped.
|
||||
|
||||
For a new 64 bit powerpc board, I recommend either the 2/2 format or
|
||||
For a new 64-bit powerpc board, I recommend either the 2/2 format or
|
||||
Apple's 2/1 format which is slightly more compact since sizes usually
|
||||
fit in a single 32 bit word. New 32 bit powerpc boards should use a
|
||||
fit in a single 32-bit word. New 32-bit powerpc boards should use a
|
||||
1/1 format, unless the processor supports physical addresses greater
|
||||
than 32-bits, in which case a 2/1 format is recommended.
|
||||
|
||||
@ -764,7 +780,7 @@ address which can extend beyond that limit.
|
||||
Required properties:
|
||||
|
||||
- device_type : has to be "cpu"
|
||||
- reg : This is the physical cpu number, it's a single 32 bit cell
|
||||
- reg : This is the physical CPU number, it's a single 32-bit cell
|
||||
and is also used as-is as the unit number for constructing the
|
||||
unit name in the full path. For example, with 2 CPUs, you would
|
||||
have the full path:
|
||||
@ -785,7 +801,7 @@ address which can extend beyond that limit.
|
||||
the kernel timebase/decrementer calibration based on this
|
||||
value.
|
||||
- clock-frequency : a cell indicating the CPU core clock frequency
|
||||
in Hz. A new property will be defined for 64 bit values, but if
|
||||
in Hz. A new property will be defined for 64-bit values, but if
|
||||
your frequency is < 4Ghz, one cell is enough. Here as well as
|
||||
for the above, the common code doesn't use that property, but
|
||||
you are welcome to re-use the pSeries or Maple one. A future
|
||||
@ -832,8 +848,7 @@ address which can extend beyond that limit.
|
||||
|
||||
This node is a bit "special". Normally, that's where open firmware
|
||||
puts some variable environment information, like the arguments, or
|
||||
phandle pointers to nodes like the main interrupt controller, or the
|
||||
default input/output devices.
|
||||
the default input/output devices.
|
||||
|
||||
This specification makes a few of these mandatory, but also defines
|
||||
some linux-specific properties that would be normally constructed by
|
||||
@ -853,14 +868,14 @@ address which can extend beyond that limit.
|
||||
that the kernel tries to find out the default console and has
|
||||
knowledge of various types like 8250 serial ports. You may want
|
||||
to extend this function to add your own.
|
||||
- interrupt-controller : This is one cell containing a phandle
|
||||
value that matches the "linux,phandle" property of your main
|
||||
interrupt controller node. May be used for interrupt routing.
|
||||
|
||||
|
||||
Note that u-boot creates and fills in the chosen node for platforms
|
||||
that use it.
|
||||
|
||||
(Note: a practice that is now obsolete was to include a property
|
||||
under /chosen called interrupt-controller which had a phandle value
|
||||
that pointed to the main interrupt controller)
|
||||
|
||||
f) the /soc<SOCname> node
|
||||
|
||||
This node is used to represent a system-on-a-chip (SOC) and must be
|
||||
@ -908,8 +923,7 @@ address which can extend beyond that limit.
|
||||
The SOC node may contain child nodes for each SOC device that the
|
||||
platform uses. Nodes should not be created for devices which exist
|
||||
on the SOC but are not used by a particular platform. See chapter VI
|
||||
for more information on how to specify devices that are part of an
|
||||
SOC.
|
||||
for more information on how to specify devices that are part of a SOC.
|
||||
|
||||
Example SOC node for the MPC8540:
|
||||
|
||||
@ -972,7 +986,7 @@ The syntax of the dtc tool is
|
||||
[-o output-filename] [-V output_version] input_filename
|
||||
|
||||
|
||||
The "output_version" defines what versio of the "blob" format will be
|
||||
The "output_version" defines what version of the "blob" format will be
|
||||
generated. Supported versions are 1,2,3 and 16. The default is
|
||||
currently version 3 but that may change in the future to version 16.
|
||||
|
||||
@ -994,12 +1008,12 @@ supported currently at the toplevel.
|
||||
*/
|
||||
|
||||
property2 = <1234abcd>; /* define a property containing a
|
||||
* numerical 32 bits value (hexadecimal)
|
||||
* numerical 32-bit value (hexadecimal)
|
||||
*/
|
||||
|
||||
property3 = <12345678 12345678 deadbeef>;
|
||||
/* define a property containing 3
|
||||
* numerical 32 bits values (cells) in
|
||||
* numerical 32-bit values (cells) in
|
||||
* hexadecimal
|
||||
*/
|
||||
property4 = [0a 0b 0c 0d de ea ad be ef];
|
||||
@ -1068,7 +1082,7 @@ while all this has been defined and implemented.
|
||||
its usage in early_init_devtree(), and the corresponding various
|
||||
early_init_dt_scan_*() callbacks. That code can be re-used in a
|
||||
GPL bootloader, and as the author of that code, I would be happy
|
||||
to discuss possible free licencing to any vendor who wishes to
|
||||
to discuss possible free licensing to any vendor who wishes to
|
||||
integrate all or part of this code into a non-GPL bootloader.
|
||||
|
||||
|
||||
@ -1077,7 +1091,7 @@ VI - System-on-a-chip devices and nodes
|
||||
=======================================
|
||||
|
||||
Many companies are now starting to develop system-on-a-chip
|
||||
processors, where the processor core (cpu) and many peripheral devices
|
||||
processors, where the processor core (CPU) and many peripheral devices
|
||||
exist on a single piece of silicon. For these SOCs, an SOC node
|
||||
should be used that defines child nodes for the devices that make
|
||||
up the SOC. While platforms are not required to use this model in
|
||||
@ -1109,42 +1123,7 @@ See appendix A for an example partial SOC node definition for the
|
||||
MPC8540.
|
||||
|
||||
|
||||
2) Specifying interrupt information for SOC devices
|
||||
---------------------------------------------------
|
||||
|
||||
Each device that is part of an SOC and which generates interrupts
|
||||
should have the following properties:
|
||||
|
||||
- interrupt-parent : contains the phandle of the interrupt
|
||||
controller which handles interrupts for this device
|
||||
- interrupts : a list of tuples representing the interrupt
|
||||
number and the interrupt sense and level for each interrupt
|
||||
for this device.
|
||||
|
||||
This information is used by the kernel to build the interrupt table
|
||||
for the interrupt controllers in the system.
|
||||
|
||||
Sense and level information should be encoded as follows:
|
||||
|
||||
Devices connected to openPIC-compatible controllers should encode
|
||||
sense and polarity as follows:
|
||||
|
||||
0 = low to high edge sensitive type enabled
|
||||
1 = active low level sensitive type enabled
|
||||
2 = active high level sensitive type enabled
|
||||
3 = high to low edge sensitive type enabled
|
||||
|
||||
ISA PIC interrupt controllers should adhere to the ISA PIC
|
||||
encodings listed below:
|
||||
|
||||
0 = active low level sensitive type enabled
|
||||
1 = active high level sensitive type enabled
|
||||
2 = high to low edge sensitive type enabled
|
||||
3 = low to high edge sensitive type enabled
|
||||
|
||||
|
||||
|
||||
3) Representing devices without a current OF specification
|
||||
2) Representing devices without a current OF specification
|
||||
----------------------------------------------------------
|
||||
|
||||
Currently, there are many devices on SOCs that do not have a standard
|
||||
@ -1201,6 +1180,13 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
- phy-handle : The phandle for the PHY connected to this ethernet
|
||||
controller.
|
||||
|
||||
Recommended properties:
|
||||
|
||||
- linux,network-index : This is the intended "index" of this
|
||||
network device. This is used by the bootwrapper to interpret
|
||||
MAC addresses passed by the firmware when no information other
|
||||
than indices is available to associate an address with a device.
|
||||
|
||||
Example:
|
||||
|
||||
ethernet@24000 {
|
||||
@ -1312,10 +1298,10 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
and additions :
|
||||
|
||||
Required properties :
|
||||
- compatible : Should be "fsl-usb2-mph" for multi port host usb
|
||||
controllers, or "fsl-usb2-dr" for dual role usb controllers
|
||||
- phy_type : For multi port host usb controllers, should be one of
|
||||
"ulpi", or "serial". For dual role usb controllers, should be
|
||||
- compatible : Should be "fsl-usb2-mph" for multi port host USB
|
||||
controllers, or "fsl-usb2-dr" for dual role USB controllers
|
||||
- phy_type : For multi port host USB controllers, should be one of
|
||||
"ulpi", or "serial". For dual role USB controllers, should be
|
||||
one of "ulpi", "utmi", "utmi_wide", or "serial".
|
||||
- reg : Offset and length of the register set for the device
|
||||
- port0 : boolean; if defined, indicates port0 is connected for
|
||||
@ -1339,7 +1325,7 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
- interrupt-parent : the phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
|
||||
Example multi port host usb controller device node :
|
||||
Example multi port host USB controller device node :
|
||||
usb@22000 {
|
||||
device_type = "usb";
|
||||
compatible = "fsl-usb2-mph";
|
||||
@ -1353,7 +1339,7 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
port1;
|
||||
};
|
||||
|
||||
Example dual role usb controller device node :
|
||||
Example dual role USB controller device node :
|
||||
usb@23000 {
|
||||
device_type = "usb";
|
||||
compatible = "fsl-usb2-dr";
|
||||
@ -1387,7 +1373,7 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
- channel-fifo-len : An integer representing the number of
|
||||
descriptor pointers each channel fetch fifo can hold.
|
||||
- exec-units-mask : The bitmask representing what execution units
|
||||
(EUs) are available. It's a single 32 bit cell. EU information
|
||||
(EUs) are available. It's a single 32-bit cell. EU information
|
||||
should be encoded following the SEC's Descriptor Header Dword
|
||||
EU_SEL0 field documentation, i.e. as follows:
|
||||
|
||||
@ -1403,7 +1389,7 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
bits 8 through 31 are reserved for future SEC EUs.
|
||||
|
||||
- descriptor-types-mask : The bitmask representing what descriptors
|
||||
are available. It's a single 32 bit cell. Descriptor type
|
||||
are available. It's a single 32-bit cell. Descriptor type
|
||||
information should be encoded following the SEC's Descriptor
|
||||
Header Dword DESC_TYPE field documentation, i.e. as follows:
|
||||
|
||||
@ -1492,7 +1478,7 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
Required properties:
|
||||
- device_type : should be "spi".
|
||||
- compatible : should be "fsl_spi".
|
||||
- mode : the spi operation mode, it can be "cpu" or "qe".
|
||||
- mode : the SPI operation mode, it can be "cpu" or "qe".
|
||||
- reg : Offset and length of the register set for the device
|
||||
- interrupts : <a b> where a is the interrupt number and b is a
|
||||
field that represents an encoding of the sense and level
|
||||
@ -1569,6 +1555,12 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
- mac-address : list of bytes representing the ethernet address.
|
||||
- phy-handle : The phandle for the PHY connected to this controller.
|
||||
|
||||
Recommended properties:
|
||||
- linux,network-index : This is the intended "index" of this
|
||||
network device. This is used by the bootwrapper to interpret
|
||||
MAC addresses passed by the firmware when no information other
|
||||
than indices is available to associate an address with a device.
|
||||
|
||||
Example:
|
||||
ucc@2000 {
|
||||
device_type = "network";
|
||||
@ -1712,7 +1704,7 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
- partitions : Several pairs of 32-bit values where the first value is
|
||||
partition's offset from the start of the device and the second one is
|
||||
partition size in bytes with LSB used to signify a read only
|
||||
partition (so, the parition size should always be an even number).
|
||||
partition (so, the partition size should always be an even number).
|
||||
- partition-names : The list of concatenated zero terminated strings
|
||||
representing the partition names.
|
||||
- probe-type : The type of probe which should be done for the chip
|
||||
@ -1733,6 +1725,92 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
|
||||
More devices will be defined as this spec matures.
|
||||
|
||||
VII - Specifying interrupt information for devices
|
||||
===================================================
|
||||
|
||||
The device tree represents the busses and devices of a hardware
|
||||
system in a form similar to the physical bus topology of the
|
||||
hardware.
|
||||
|
||||
In addition, a logical 'interrupt tree' exists which represents the
|
||||
hierarchy and routing of interrupts in the hardware.
|
||||
|
||||
The interrupt tree model is fully described in the
|
||||
document "Open Firmware Recommended Practice: Interrupt
|
||||
Mapping Version 0.9". The document is available at:
|
||||
<http://playground.sun.com/1275/practice>.
|
||||
|
||||
1) interrupts property
|
||||
----------------------
|
||||
|
||||
Devices that generate interrupts to a single interrupt controller
|
||||
should use the conventional OF representation described in the
|
||||
OF interrupt mapping documentation.
|
||||
|
||||
Each device which generates interrupts must have an 'interrupt'
|
||||
property. The interrupt property value is an arbitrary number of
|
||||
of 'interrupt specifier' values which describe the interrupt or
|
||||
interrupts for the device.
|
||||
|
||||
The encoding of an interrupt specifier is determined by the
|
||||
interrupt domain in which the device is located in the
|
||||
interrupt tree. The root of an interrupt domain specifies in
|
||||
its #interrupt-cells property the number of 32-bit cells
|
||||
required to encode an interrupt specifier. See the OF interrupt
|
||||
mapping documentation for a detailed description of domains.
|
||||
|
||||
For example, the binding for the OpenPIC interrupt controller
|
||||
specifies an #interrupt-cells value of 2 to encode the interrupt
|
||||
number and level/sense information. All interrupt children in an
|
||||
OpenPIC interrupt domain use 2 cells per interrupt in their interrupts
|
||||
property.
|
||||
|
||||
The PCI bus binding specifies a #interrupt-cell value of 1 to encode
|
||||
which interrupt pin (INTA,INTB,INTC,INTD) is used.
|
||||
|
||||
2) interrupt-parent property
|
||||
----------------------------
|
||||
|
||||
The interrupt-parent property is specified to define an explicit
|
||||
link between a device node and its interrupt parent in
|
||||
the interrupt tree. The value of interrupt-parent is the
|
||||
phandle of the parent node.
|
||||
|
||||
If the interrupt-parent property is not defined for a node, it's
|
||||
interrupt parent is assumed to be an ancestor in the node's
|
||||
_device tree_ hierarchy.
|
||||
|
||||
3) OpenPIC Interrupt Controllers
|
||||
--------------------------------
|
||||
|
||||
OpenPIC interrupt controllers require 2 cells to encode
|
||||
interrupt information. The first cell defines the interrupt
|
||||
number. The second cell defines the sense and level
|
||||
information.
|
||||
|
||||
Sense and level information should be encoded as follows:
|
||||
|
||||
0 = low to high edge sensitive type enabled
|
||||
1 = active low level sensitive type enabled
|
||||
2 = active high level sensitive type enabled
|
||||
3 = high to low edge sensitive type enabled
|
||||
|
||||
4) ISA Interrupt Controllers
|
||||
----------------------------
|
||||
|
||||
ISA PIC interrupt controllers require 2 cells to encode
|
||||
interrupt information. The first cell defines the interrupt
|
||||
number. The second cell defines the sense and level
|
||||
information.
|
||||
|
||||
ISA PIC interrupt controllers should adhere to the ISA PIC
|
||||
encodings listed below:
|
||||
|
||||
0 = active low level sensitive type enabled
|
||||
1 = active high level sensitive type enabled
|
||||
2 = high to low edge sensitive type enabled
|
||||
3 = low to high edge sensitive type enabled
|
||||
|
||||
|
||||
Appendix A - Sample SOC node for MPC8540
|
||||
========================================
|
||||
|
@ -1,83 +0,0 @@
|
||||
crypto-API support for z990 Message Security Assist (MSA) instructions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
AUTHOR: Thomas Spatzier (tspat@de.ibm.com)
|
||||
|
||||
|
||||
1. Introduction crypto-API
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
See Documentation/crypto/api-intro.txt for an introduction/description of the
|
||||
kernel crypto API.
|
||||
According to api-intro.txt support for z990 crypto instructions has been added
|
||||
in the algorithm api layer of the crypto API. Several files containing z990
|
||||
optimized implementations of crypto algorithms are placed in the
|
||||
arch/s390/crypto directory.
|
||||
|
||||
|
||||
2. Probing for availability of MSA
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
It should be possible to use Kernels with the z990 crypto implementations both
|
||||
on machines with MSA available and on those without MSA (pre z990 or z990
|
||||
without MSA). Therefore a simple probing mechanism has been implemented:
|
||||
In the init function of each crypto module the availability of MSA and of the
|
||||
respective crypto algorithm in particular will be tested. If the algorithm is
|
||||
available the module will load and register its algorithm with the crypto API.
|
||||
|
||||
If the respective crypto algorithm is not available, the init function will
|
||||
return -ENOSYS. In that case a fallback to the standard software implementation
|
||||
of the crypto algorithm must be taken ( -> the standard crypto modules are
|
||||
also built when compiling the kernel).
|
||||
|
||||
|
||||
3. Ensuring z990 crypto module preference
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
If z990 crypto instructions are available the optimized modules should be
|
||||
preferred instead of standard modules.
|
||||
|
||||
3.1. compiled-in modules
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
For compiled-in modules it has to be ensured that the z990 modules are linked
|
||||
before the standard crypto modules. Then, on system startup the init functions
|
||||
of z990 crypto modules will be called first and query for availability of z990
|
||||
crypto instructions. If instruction is available, the z990 module will register
|
||||
its crypto algorithm implementation -> the load of the standard module will fail
|
||||
since the algorithm is already registered.
|
||||
If z990 crypto instruction is not available the load of the z990 module will
|
||||
fail -> the standard module will load and register its algorithm.
|
||||
|
||||
3.2. dynamic modules
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
A system administrator has to take care of giving preference to z990 crypto
|
||||
modules. If MSA is available appropriate lines have to be added to
|
||||
/etc/modprobe.conf.
|
||||
|
||||
Example: z990 crypto instruction for SHA1 algorithm is available
|
||||
|
||||
add the following line to /etc/modprobe.conf (assuming the
|
||||
z990 crypto modules for SHA1 is called sha1_z990):
|
||||
|
||||
alias sha1 sha1_z990
|
||||
|
||||
-> when the sha1 algorithm is requested through the crypto API
|
||||
(which has a module autoloader) the z990 module will be loaded.
|
||||
|
||||
TBD: a userspace module probing mechanism
|
||||
something like 'probe sha1 sha1_z990 sha1' in modprobe.conf
|
||||
-> try module sha1_z990, if it fails to load standard module sha1
|
||||
the 'probe' statement is currently not supported in modprobe.conf
|
||||
|
||||
|
||||
4. Currently implemented z990 crypto algorithms
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The following crypto algorithms with z990 MSA support are currently implemented.
|
||||
The name of each algorithm under which it is registered in crypto API and the
|
||||
name of the respective module is given in square brackets.
|
||||
|
||||
- SHA1 Digest Algorithm [sha1 -> sha1_z990]
|
||||
- DES Encrypt/Decrypt Algorithm (64bit key) [des -> des_z990]
|
||||
- Triple DES Encrypt/Decrypt Algorithm (128bit key) [des3_ede128 -> des_z990]
|
||||
- Triple DES Encrypt/Decrypt Algorithm (192bit key) [des3_ede -> des_z990]
|
||||
|
||||
In order to load, for example, the sha1_z990 module when the sha1 algorithm is
|
||||
requested (see 3.2.) add 'alias sha1 sha1_z990' to /etc/modprobe.conf.
|
||||
|
87
Documentation/s390/zfcpdump.txt
Normal file
87
Documentation/s390/zfcpdump.txt
Normal file
@ -0,0 +1,87 @@
|
||||
s390 SCSI dump tool (zfcpdump)
|
||||
|
||||
System z machines (z900 or higher) provide hardware support for creating system
|
||||
dumps on SCSI disks. The dump process is initiated by booting a dump tool, which
|
||||
has to create a dump of the current (probably crashed) Linux image. In order to
|
||||
not overwrite memory of the crashed Linux with data of the dump tool, the
|
||||
hardware saves some memory plus the register sets of the boot cpu before the
|
||||
dump tool is loaded. There exists an SCLP hardware interface to obtain the saved
|
||||
memory afterwards. Currently 32 MB are saved.
|
||||
|
||||
This zfcpdump implementation consists of a Linux dump kernel together with
|
||||
a userspace dump tool, which are loaded together into the saved memory region
|
||||
below 32 MB. zfcpdump is installed on a SCSI disk using zipl (as contained in
|
||||
the s390-tools package) to make the device bootable. The operator of a Linux
|
||||
system can then trigger a SCSI dump by booting the SCSI disk, where zfcpdump
|
||||
resides on.
|
||||
|
||||
The kernel part of zfcpdump is implemented as a debugfs file under "zcore/mem",
|
||||
which exports memory and registers of the crashed Linux in an s390
|
||||
standalone dump format. It can be used in the same way as e.g. /dev/mem. The
|
||||
dump format defines a 4K header followed by plain uncompressed memory. The
|
||||
register sets are stored in the prefix pages of the respective cpus. To build a
|
||||
dump enabled kernel with the zcore driver, the kernel config option
|
||||
CONFIG_ZFCPDUMP has to be set. When reading from "zcore/mem", the part of
|
||||
memory, which has been saved by hardware is read by the driver via the SCLP
|
||||
hardware interface. The second part is just copied from the non overwritten real
|
||||
memory.
|
||||
|
||||
The userspace application of zfcpdump can reside e.g. in an intitramfs or an
|
||||
initrd. It reads from zcore/mem and writes the system dump to a file on a
|
||||
SCSI disk.
|
||||
|
||||
To build a zfcpdump kernel use the following settings in your kernel
|
||||
configuration:
|
||||
* CONFIG_ZFCPDUMP=y
|
||||
* Enable ZFCP driver
|
||||
* Enable SCSI driver
|
||||
* Enable ext2 and ext3 filesystems
|
||||
* Disable as many features as possible to keep the kernel small.
|
||||
E.g. network support is not needed at all.
|
||||
|
||||
To use the zfcpdump userspace application in an initramfs you have to do the
|
||||
following:
|
||||
|
||||
* Copy the zfcpdump executable somewhere into your Linux tree.
|
||||
E.g. to "arch/s390/boot/zfcpdump. If you do not want to include
|
||||
shared libraries, compile the tool with the "-static" gcc option.
|
||||
* If you want to include e2fsck, add it to your source tree, too. The zfcpdump
|
||||
application attempts to start /sbin/e2fsck from the ramdisk.
|
||||
* Use an initramfs config file like the following:
|
||||
|
||||
dir /dev 755 0 0
|
||||
nod /dev/console 644 0 0 c 5 1
|
||||
nod /dev/null 644 0 0 c 1 3
|
||||
nod /dev/sda1 644 0 0 b 8 1
|
||||
nod /dev/sda2 644 0 0 b 8 2
|
||||
nod /dev/sda3 644 0 0 b 8 3
|
||||
nod /dev/sda4 644 0 0 b 8 4
|
||||
nod /dev/sda5 644 0 0 b 8 5
|
||||
nod /dev/sda6 644 0 0 b 8 6
|
||||
nod /dev/sda7 644 0 0 b 8 7
|
||||
nod /dev/sda8 644 0 0 b 8 8
|
||||
nod /dev/sda9 644 0 0 b 8 9
|
||||
nod /dev/sda10 644 0 0 b 8 10
|
||||
nod /dev/sda11 644 0 0 b 8 11
|
||||
nod /dev/sda12 644 0 0 b 8 12
|
||||
nod /dev/sda13 644 0 0 b 8 13
|
||||
nod /dev/sda14 644 0 0 b 8 14
|
||||
nod /dev/sda15 644 0 0 b 8 15
|
||||
file /init arch/s390/boot/zfcpdump 755 0 0
|
||||
file /sbin/e2fsck arch/s390/boot/e2fsck 755 0 0
|
||||
dir /proc 755 0 0
|
||||
dir /sys 755 0 0
|
||||
dir /mnt 755 0 0
|
||||
dir /sbin 755 0 0
|
||||
|
||||
* Issue "make image" to build the zfcpdump image with initramfs.
|
||||
|
||||
In a Linux distribution the zfcpdump enabled kernel image must be copied to
|
||||
/usr/share/zfcpdump/zfcpdump.image, where the s390 zipl tool is looking for the
|
||||
dump kernel when preparing a SCSI dump disk.
|
||||
|
||||
If you use a ramdisk copy it to "/usr/share/zfcpdump/zfcpdump.rd".
|
||||
|
||||
For more information on how to use zfcpdump refer to the s390 'Using the Dump
|
||||
Tools book', which is available from
|
||||
http://www.ibm.com/developerworks/linux/linux390.
|
@ -3,12 +3,18 @@ Sony Notebook Control Driver (SNC) Readme
|
||||
Copyright (C) 2004- 2005 Stelian Pop <stelian@popies.net>
|
||||
Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
|
||||
|
||||
This mini-driver drives the SNC device present in the ACPI BIOS of
|
||||
the Sony Vaio laptops.
|
||||
This mini-driver drives the SNC and SPIC device present in the ACPI BIOS of the
|
||||
Sony Vaio laptops. This driver mixes both devices functions under the same
|
||||
(hopefully consistent) interface. This also means that the sonypi driver is
|
||||
obsoleted by sony-laptop now.
|
||||
|
||||
It gives access to some extra laptop functionalities. In its current
|
||||
form, this driver let the user set or query the screen brightness
|
||||
through the backlight subsystem and remove/apply power to some devices.
|
||||
Fn keys (hotkeys):
|
||||
------------------
|
||||
Some models report hotkeys through the SNC or SPIC devices, such events are
|
||||
reported both through the ACPI subsystem as acpi events and through the INPUT
|
||||
subsystem. See the logs of acpid or /proc/acpi/event and
|
||||
/proc/bus/input/devices to find out what those events are and which input
|
||||
devices are created by the driver.
|
||||
|
||||
Backlight control:
|
||||
------------------
|
||||
@ -39,6 +45,8 @@ The files are:
|
||||
audiopower power on/off the internal sound card
|
||||
lanpower power on/off the internal ethernet card
|
||||
(only in debug mode)
|
||||
bluetoothpower power on/off the internal bluetooth device
|
||||
fanspeed get/set the fan speed
|
||||
|
||||
Note that some files may be missing if they are not supported
|
||||
by your particular laptop model.
|
||||
@ -76,9 +84,9 @@ The sony-laptop driver creates, for some of those methods (the most
|
||||
current ones found on several Vaio models), an entry under
|
||||
/sys/devices/platform/sony-laptop, just like the 'cdpower' one.
|
||||
You can create other entries corresponding to your own laptop methods by
|
||||
further editing the source (see the 'sony_acpi_values' table, and add a new
|
||||
further editing the source (see the 'sony_nc_values' table, and add a new
|
||||
entry to this table with your get/set method names using the
|
||||
HANDLE_NAMES macro).
|
||||
SNC_HANDLE_NAMES macro).
|
||||
|
||||
Your mission, should you accept it, is to try finding out what
|
||||
those entries are for, by reading/writing random values from/to those
|
||||
@ -87,6 +95,9 @@ files and find out what is the impact on your laptop.
|
||||
Should you find anything interesting, please report it back to me,
|
||||
I will not disavow all knowledge of your actions :)
|
||||
|
||||
See also http://www.linux.it/~malattia/wiki/index.php/Sony_drivers for other
|
||||
useful info.
|
||||
|
||||
Bugs/Limitations:
|
||||
-----------------
|
||||
|
||||
|
@ -1,16 +1,22 @@
|
||||
IBM ThinkPad ACPI Extras Driver
|
||||
ThinkPad ACPI Extras Driver
|
||||
|
||||
Version 0.12
|
||||
17 August 2005
|
||||
Version 0.14
|
||||
April 21st, 2007
|
||||
|
||||
Borislav Deianov <borislav@users.sf.net>
|
||||
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||
http://ibm-acpi.sf.net/
|
||||
|
||||
|
||||
This is a Linux ACPI driver for the IBM ThinkPad laptops. It supports
|
||||
various features of these laptops which are accessible through the
|
||||
ACPI framework but not otherwise supported by the generic Linux ACPI
|
||||
drivers.
|
||||
This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It
|
||||
supports various features of these laptops which are accessible
|
||||
through the ACPI and ACPI EC framework, but not otherwise fully
|
||||
supported by the generic Linux ACPI drivers.
|
||||
|
||||
This driver used to be named ibm-acpi until kernel 2.6.21 and release
|
||||
0.13-20070314. It used to be in the drivers/acpi tree, but it was
|
||||
moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
|
||||
2.6.22, and release 0.14.
|
||||
|
||||
|
||||
Status
|
||||
@ -21,7 +27,7 @@ detailed description):
|
||||
|
||||
- Fn key combinations
|
||||
- Bluetooth enable and disable
|
||||
- video output switching, expansion control
|
||||
- video output switching, expansion control
|
||||
- ThinkLight on and off
|
||||
- limited docking and undocking
|
||||
- UltraBay eject
|
||||
@ -32,7 +38,7 @@ detailed description):
|
||||
- Experimental: embedded controller register dump
|
||||
- LCD brightness control
|
||||
- Volume control
|
||||
- Experimental: fan speed, fan enable/disable
|
||||
- Fan control and monitoring: fan speed, fan enable/disable
|
||||
- Experimental: WAN enable and disable
|
||||
|
||||
A compatibility table by model and feature is maintained on the web
|
||||
@ -42,6 +48,8 @@ Please include the following information in your report:
|
||||
|
||||
- ThinkPad model name
|
||||
- a copy of your DSDT, from /proc/acpi/dsdt
|
||||
- a copy of the output of dmidecode, with serial numbers
|
||||
and UUIDs masked off
|
||||
- which driver features work and which don't
|
||||
- the observed behavior of non-working features
|
||||
|
||||
@ -52,25 +60,85 @@ Installation
|
||||
------------
|
||||
|
||||
If you are compiling this driver as included in the Linux kernel
|
||||
sources, simply enable the CONFIG_ACPI_IBM option (Power Management /
|
||||
ACPI / IBM ThinkPad Laptop Extras).
|
||||
sources, simply enable the CONFIG_THINKPAD_ACPI option, and optionally
|
||||
enable the CONFIG_THINKPAD_ACPI_BAY option if you want the
|
||||
thinkpad-specific bay functionality.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
The driver creates the /proc/acpi/ibm directory. There is a file under
|
||||
that directory for each feature described below. Note that while the
|
||||
driver is still in the alpha stage, the exact proc file format and
|
||||
commands supported by the various features is guaranteed to change
|
||||
frequently.
|
||||
The driver exports two different interfaces to userspace, which can be
|
||||
used to access the features it provides. One is a legacy procfs-based
|
||||
interface, which will be removed at some time in the distant future.
|
||||
The other is a new sysfs-based interface which is not complete yet.
|
||||
|
||||
Driver version -- /proc/acpi/ibm/driver
|
||||
---------------------------------------
|
||||
The procfs interface creates the /proc/acpi/ibm directory. There is a
|
||||
file under that directory for each feature it supports. The procfs
|
||||
interface is mostly frozen, and will change very little if at all: it
|
||||
will not be extended to add any new functionality in the driver, instead
|
||||
all new functionality will be implemented on the sysfs interface.
|
||||
|
||||
The sysfs interface tries to blend in the generic Linux sysfs subsystems
|
||||
and classes as much as possible. Since some of these subsystems are not
|
||||
yet ready or stabilized, it is expected that this interface will change,
|
||||
and any and all userspace programs must deal with it.
|
||||
|
||||
|
||||
Notes about the sysfs interface:
|
||||
|
||||
Unlike what was done with the procfs interface, correctness when talking
|
||||
to the sysfs interfaces will be enforced, as will correctness in the
|
||||
thinkpad-acpi's implementation of sysfs interfaces.
|
||||
|
||||
Also, any bugs in the thinkpad-acpi sysfs driver code or in the
|
||||
thinkpad-acpi's implementation of the sysfs interfaces will be fixed for
|
||||
maximum correctness, even if that means changing an interface in
|
||||
non-compatible ways. As these interfaces mature both in the kernel and
|
||||
in thinkpad-acpi, such changes should become quite rare.
|
||||
|
||||
Applications interfacing to the thinkpad-acpi sysfs interfaces must
|
||||
follow all sysfs guidelines and correctly process all errors (the sysfs
|
||||
interface makes extensive use of errors). File descriptors and open /
|
||||
close operations to the sysfs inodes must also be properly implemented.
|
||||
|
||||
The version of thinkpad-acpi's sysfs interface is exported by the driver
|
||||
as a driver attribute (see below).
|
||||
|
||||
Sysfs driver attributes are on the driver's sysfs attribute space,
|
||||
for 2.6.20 this is /sys/bus/platform/drivers/thinkpad-acpi/.
|
||||
|
||||
Sysfs device attributes are on the driver's sysfs attribute space,
|
||||
for 2.6.20 this is /sys/devices/platform/thinkpad-acpi/.
|
||||
|
||||
Driver version
|
||||
--------------
|
||||
|
||||
procfs: /proc/acpi/ibm/driver
|
||||
sysfs driver attribute: version
|
||||
|
||||
The driver name and version. No commands can be written to this file.
|
||||
|
||||
Hot keys -- /proc/acpi/ibm/hotkey
|
||||
---------------------------------
|
||||
Sysfs interface version
|
||||
-----------------------
|
||||
|
||||
sysfs driver attribute: interface_version
|
||||
|
||||
Version of the thinkpad-acpi sysfs interface, as an unsigned long
|
||||
(output in hex format: 0xAAAABBCC), where:
|
||||
AAAA - major revision
|
||||
BB - minor revision
|
||||
CC - bugfix revision
|
||||
|
||||
The sysfs interface version changelog for the driver can be found at the
|
||||
end of this document. Changes to the sysfs interface done by the kernel
|
||||
subsystems are not documented here, nor are they tracked by this
|
||||
attribute.
|
||||
|
||||
Hot keys
|
||||
--------
|
||||
|
||||
procfs: /proc/acpi/ibm/hotkey
|
||||
sysfs device attribute: hotkey/*
|
||||
|
||||
Without this driver, only the Fn-F4 key (sleep button) generates an
|
||||
ACPI event. With the driver loaded, the hotkey feature enabled and the
|
||||
@ -84,15 +152,6 @@ All labeled Fn-Fx key combinations generate distinct events. In
|
||||
addition, the lid microswitch and some docking station buttons may
|
||||
also generate such events.
|
||||
|
||||
The following commands can be written to this file:
|
||||
|
||||
echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
|
||||
echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
|
||||
echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
|
||||
echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
|
||||
... any other 4-hex-digit mask ...
|
||||
echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
|
||||
|
||||
The bit mask allows some control over which hot keys generate ACPI
|
||||
events. Not all bits in the mask can be modified. Not all bits that
|
||||
can be modified do anything. Not all hot keys can be individually
|
||||
@ -124,15 +183,77 @@ buttons do not generate ACPI events even with this driver. They *can*
|
||||
be used through the "ThinkPad Buttons" utility, see
|
||||
http://www.nongnu.org/tpb/
|
||||
|
||||
Bluetooth -- /proc/acpi/ibm/bluetooth
|
||||
-------------------------------------
|
||||
procfs notes:
|
||||
|
||||
This feature shows the presence and current state of a Bluetooth
|
||||
device. If Bluetooth is installed, the following commands can be used:
|
||||
The following commands can be written to the /proc/acpi/ibm/hotkey file:
|
||||
|
||||
echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
|
||||
echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
|
||||
echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
|
||||
echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
|
||||
... any other 4-hex-digit mask ...
|
||||
echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
|
||||
|
||||
sysfs notes:
|
||||
|
||||
The hot keys attributes are in a hotkey/ subdirectory off the
|
||||
thinkpad device.
|
||||
|
||||
bios_enabled:
|
||||
Returns the status of the hot keys feature when
|
||||
thinkpad-acpi was loaded. Upon module unload, the hot
|
||||
key feature status will be restored to this value.
|
||||
|
||||
0: hot keys were disabled
|
||||
1: hot keys were enabled
|
||||
|
||||
bios_mask:
|
||||
Returns the hot keys mask when thinkpad-acpi was loaded.
|
||||
Upon module unload, the hot keys mask will be restored
|
||||
to this value.
|
||||
|
||||
enable:
|
||||
Enables/disables the hot keys feature, and reports
|
||||
current status of the hot keys feature.
|
||||
|
||||
0: disables the hot keys feature / feature disabled
|
||||
1: enables the hot keys feature / feature enabled
|
||||
|
||||
mask:
|
||||
bit mask to enable ACPI event generation for each hot
|
||||
key (see above). Returns the current status of the hot
|
||||
keys mask, and allows one to modify it.
|
||||
|
||||
|
||||
Bluetooth
|
||||
---------
|
||||
|
||||
procfs: /proc/acpi/ibm/bluetooth
|
||||
sysfs device attribute: bluetooth/enable
|
||||
|
||||
This feature shows the presence and current state of a ThinkPad
|
||||
Bluetooth device in the internal ThinkPad CDC slot.
|
||||
|
||||
Procfs notes:
|
||||
|
||||
If Bluetooth is installed, the following commands can be used:
|
||||
|
||||
echo enable > /proc/acpi/ibm/bluetooth
|
||||
echo disable > /proc/acpi/ibm/bluetooth
|
||||
|
||||
Sysfs notes:
|
||||
|
||||
If the Bluetooth CDC card is installed, it can be enabled /
|
||||
disabled through the "bluetooth/enable" thinkpad-acpi device
|
||||
attribute, and its current status can also be queried.
|
||||
|
||||
enable:
|
||||
0: disables Bluetooth / Bluetooth is disabled
|
||||
1: enables Bluetooth / Bluetooth is enabled.
|
||||
|
||||
Note: this interface will be probably be superseeded by the
|
||||
generic rfkill class.
|
||||
|
||||
Video output control -- /proc/acpi/ibm/video
|
||||
--------------------------------------------
|
||||
|
||||
@ -209,7 +330,7 @@ hot plugging of devices in the Linux ACPI framework. If the laptop was
|
||||
booted while not in the dock, the following message is shown in the
|
||||
logs:
|
||||
|
||||
Mar 17 01:42:34 aero kernel: ibm_acpi: dock device not present
|
||||
Mar 17 01:42:34 aero kernel: thinkpad_acpi: dock device not present
|
||||
|
||||
In this case, no dock-related events are generated but the dock and
|
||||
undock commands described below still work. They can be executed
|
||||
@ -269,7 +390,7 @@ This is due to the current lack of support for hot plugging of devices
|
||||
in the Linux ACPI framework. If the laptop was booted without the
|
||||
UltraBay, the following message is shown in the logs:
|
||||
|
||||
Mar 17 01:42:34 aero kernel: ibm_acpi: bay device not present
|
||||
Mar 17 01:42:34 aero kernel: thinkpad_acpi: bay device not present
|
||||
|
||||
In this case, no bay-related events are generated but the eject
|
||||
command described below still works. It can be executed manually or
|
||||
@ -313,23 +434,19 @@ supported. Use "eject2" instead of "eject" for the second bay.
|
||||
Note: the UltraBay eject support on the 600e/x, A22p and A3x is
|
||||
EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
|
||||
|
||||
CMOS control -- /proc/acpi/ibm/cmos
|
||||
-----------------------------------
|
||||
CMOS control
|
||||
------------
|
||||
|
||||
procfs: /proc/acpi/ibm/cmos
|
||||
sysfs device attribute: cmos_command
|
||||
|
||||
This feature is used internally by the ACPI firmware to control the
|
||||
ThinkLight on most newer ThinkPad models. It may also control LCD
|
||||
brightness, sounds volume and more, but only on some models.
|
||||
|
||||
The commands are non-negative integer numbers:
|
||||
|
||||
echo 0 >/proc/acpi/ibm/cmos
|
||||
echo 1 >/proc/acpi/ibm/cmos
|
||||
echo 2 >/proc/acpi/ibm/cmos
|
||||
...
|
||||
|
||||
The range of valid numbers is 0 to 21, but not all have an effect and
|
||||
the behavior varies from model to model. Here is the behavior on the
|
||||
X40 (tpb is the ThinkPad Buttons utility):
|
||||
The range of valid cmos command numbers is 0 to 21, but not all have an
|
||||
effect and the behavior varies from model to model. Here is the behavior
|
||||
on the X40 (tpb is the ThinkPad Buttons utility):
|
||||
|
||||
0 - no effect but tpb reports "Volume down"
|
||||
1 - no effect but tpb reports "Volume up"
|
||||
@ -342,6 +459,9 @@ X40 (tpb is the ThinkPad Buttons utility):
|
||||
13 - ThinkLight off
|
||||
14 - no effect but tpb reports ThinkLight status change
|
||||
|
||||
The cmos command interface is prone to firmware split-brain problems, as
|
||||
in newer ThinkPads it is just a compatibility layer.
|
||||
|
||||
LED control -- /proc/acpi/ibm/led
|
||||
---------------------------------
|
||||
|
||||
@ -393,17 +513,17 @@ X40:
|
||||
16 - one medium-pitched beep repeating constantly, stop with 17
|
||||
17 - stop 16
|
||||
|
||||
Temperature sensors -- /proc/acpi/ibm/thermal
|
||||
---------------------------------------------
|
||||
Temperature sensors
|
||||
-------------------
|
||||
|
||||
procfs: /proc/acpi/ibm/thermal
|
||||
sysfs device attributes: (hwmon) temp*_input
|
||||
|
||||
Most ThinkPads include six or more separate temperature sensors but
|
||||
only expose the CPU temperature through the standard ACPI methods.
|
||||
This feature shows readings from up to eight different sensors on older
|
||||
ThinkPads, and it has experimental support for up to sixteen different
|
||||
sensors on newer ThinkPads. Readings from sensors that are not available
|
||||
return -128.
|
||||
|
||||
No commands can be written to this file.
|
||||
sensors on newer ThinkPads.
|
||||
|
||||
EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the
|
||||
implementation directly accesses hardware registers and may not work as
|
||||
@ -460,6 +580,20 @@ The A31 has a very atypical layout for the thermal sensors
|
||||
8: Bay Battery: secondary sensor
|
||||
|
||||
|
||||
Procfs notes:
|
||||
Readings from sensors that are not available return -128.
|
||||
No commands can be written to this file.
|
||||
|
||||
Sysfs notes:
|
||||
Sensors that are not available return the ENXIO error. This
|
||||
status may change at runtime, as there are hotplug thermal
|
||||
sensors, like those inside the batteries and docks.
|
||||
|
||||
thinkpad-acpi thermal sensors are reported through the hwmon
|
||||
subsystem, and follow all of the hwmon guidelines at
|
||||
Documentation/hwmon.
|
||||
|
||||
|
||||
EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
|
||||
------------------------------------------------------------------------
|
||||
|
||||
@ -472,7 +606,7 @@ This feature dumps the values of 256 embedded controller
|
||||
registers. Values which have changed since the last time the registers
|
||||
were dumped are marked with a star:
|
||||
|
||||
[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump
|
||||
[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump
|
||||
EC +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f
|
||||
EC 0x00: a7 47 87 01 fe 96 00 08 01 00 cb 00 00 00 40 00
|
||||
EC 0x10: 00 00 ff ff f4 3c 87 09 01 ff 42 01 ff ff 0d 00
|
||||
@ -503,7 +637,7 @@ vary. The second ensures that the fan-related values do vary, since
|
||||
the fan speed fluctuates a bit. The third will (hopefully) mark the
|
||||
fan register with a star:
|
||||
|
||||
[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump
|
||||
[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump
|
||||
EC +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f
|
||||
EC 0x00: a7 47 87 01 fe 96 00 08 01 00 cb 00 00 00 40 00
|
||||
EC 0x10: 00 00 ff ff f4 3c 87 09 01 ff 42 01 ff ff 0d 00
|
||||
@ -533,19 +667,59 @@ registers contain the current battery capacity, etc. If you experiment
|
||||
with this, do send me your results (including some complete dumps with
|
||||
a description of the conditions when they were taken.)
|
||||
|
||||
LCD brightness control -- /proc/acpi/ibm/brightness
|
||||
---------------------------------------------------
|
||||
LCD brightness control
|
||||
----------------------
|
||||
|
||||
procfs: /proc/acpi/ibm/brightness
|
||||
sysfs backlight device "thinkpad_screen"
|
||||
|
||||
This feature allows software control of the LCD brightness on ThinkPad
|
||||
models which don't have a hardware brightness slider. The available
|
||||
commands are:
|
||||
models which don't have a hardware brightness slider.
|
||||
|
||||
It has some limitations: the LCD backlight cannot be actually turned on or off
|
||||
by this interface, and in many ThinkPad models, the "dim while on battery"
|
||||
functionality will be enabled by the BIOS when this interface is used, and
|
||||
cannot be controlled.
|
||||
|
||||
The backlight control has eight levels, ranging from 0 to 7. Some of the
|
||||
levels may not be distinct.
|
||||
|
||||
Procfs notes:
|
||||
|
||||
The available commands are:
|
||||
|
||||
echo up >/proc/acpi/ibm/brightness
|
||||
echo down >/proc/acpi/ibm/brightness
|
||||
echo 'level <level>' >/proc/acpi/ibm/brightness
|
||||
|
||||
The <level> number range is 0 to 7, although not all of them may be
|
||||
distinct. The current brightness level is shown in the file.
|
||||
Sysfs notes:
|
||||
|
||||
The interface is implemented through the backlight sysfs class, which is poorly
|
||||
documented at this time.
|
||||
|
||||
Locate the thinkpad_screen device under /sys/class/backlight, and inside it
|
||||
there will be the following attributes:
|
||||
|
||||
max_brightness:
|
||||
Reads the maximum brightness the hardware can be set to.
|
||||
The minimum is always zero.
|
||||
|
||||
actual_brightness:
|
||||
Reads what brightness the screen is set to at this instant.
|
||||
|
||||
brightness:
|
||||
Writes request the driver to change brightness to the given
|
||||
value. Reads will tell you what brightness the driver is trying
|
||||
to set the display to when "power" is set to zero and the display
|
||||
has not been dimmed by a kernel power management event.
|
||||
|
||||
power:
|
||||
power management mode, where 0 is "display on", and 1 to 3 will
|
||||
dim the display backlight to brightness level 0 because
|
||||
thinkpad-acpi cannot really turn the backlight off. Kernel
|
||||
power management events can temporarily increase the current
|
||||
power management level, i.e. they can dim the display.
|
||||
|
||||
|
||||
Volume control -- /proc/acpi/ibm/volume
|
||||
---------------------------------------
|
||||
@ -563,41 +737,42 @@ distinct. The unmute the volume after the mute command, use either the
|
||||
up or down command (the level command will not unmute the volume).
|
||||
The current volume level and mute state is shown in the file.
|
||||
|
||||
EXPERIMENTAL: fan speed, fan enable/disable -- /proc/acpi/ibm/fan
|
||||
-----------------------------------------------------------------
|
||||
Fan control and monitoring: fan speed, fan enable/disable
|
||||
---------------------------------------------------------
|
||||
|
||||
This feature is marked EXPERIMENTAL because the implementation
|
||||
directly accesses hardware registers and may not work as expected. USE
|
||||
WITH CAUTION! To use this feature, you need to supply the
|
||||
experimental=1 parameter when loading the module.
|
||||
procfs: /proc/acpi/ibm/fan
|
||||
sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
|
||||
|
||||
NOTE NOTE NOTE: fan control operations are disabled by default for
|
||||
safety reasons. To enable them, the module parameter "fan_control=1"
|
||||
must be given to thinkpad-acpi.
|
||||
|
||||
This feature attempts to show the current fan speed, control mode and
|
||||
other fan data that might be available. The speed is read directly
|
||||
from the hardware registers of the embedded controller. This is known
|
||||
to work on later R, T and X series ThinkPads but may show a bogus
|
||||
to work on later R, T, X and Z series ThinkPads but may show a bogus
|
||||
value on other models.
|
||||
|
||||
Most ThinkPad fans work in "levels". Level 0 stops the fan. The higher
|
||||
the level, the higher the fan speed, although adjacent levels often map
|
||||
to the same fan speed. 7 is the highest level, where the fan reaches
|
||||
the maximum recommended speed. Level "auto" means the EC changes the
|
||||
fan level according to some internal algorithm, usually based on
|
||||
readings from the thermal sensors. Level "disengaged" means the EC
|
||||
disables the speed-locked closed-loop fan control, and drives the fan as
|
||||
fast as it can go, which might exceed hardware limits, so use this level
|
||||
with caution.
|
||||
Fan levels:
|
||||
|
||||
The fan usually ramps up or down slowly from one speed to another,
|
||||
and it is normal for the EC to take several seconds to react to fan
|
||||
commands.
|
||||
Most ThinkPad fans work in "levels" at the firmware interface. Level 0
|
||||
stops the fan. The higher the level, the higher the fan speed, although
|
||||
adjacent levels often map to the same fan speed. 7 is the highest
|
||||
level, where the fan reaches the maximum recommended speed.
|
||||
|
||||
The fan may be enabled or disabled with the following commands:
|
||||
Level "auto" means the EC changes the fan level according to some
|
||||
internal algorithm, usually based on readings from the thermal sensors.
|
||||
|
||||
echo enable >/proc/acpi/ibm/fan
|
||||
echo disable >/proc/acpi/ibm/fan
|
||||
There is also a "full-speed" level, also known as "disengaged" level.
|
||||
In this level, the EC disables the speed-locked closed-loop fan control,
|
||||
and drives the fan as fast as it can go, which might exceed hardware
|
||||
limits, so use this level with caution.
|
||||
|
||||
Placing a fan on level 0 is the same as disabling it. Enabling a fan
|
||||
will try to place it in a safe level if it is too slow or disabled.
|
||||
The fan usually ramps up or down slowly from one speed to another, and
|
||||
it is normal for the EC to take several seconds to react to fan
|
||||
commands. The full-speed level may take up to two minutes to ramp up to
|
||||
maximum speed, and in some ThinkPads, the tachometer readings go stale
|
||||
while the EC is transitioning to the full-speed level.
|
||||
|
||||
WARNING WARNING WARNING: do not leave the fan disabled unless you are
|
||||
monitoring all of the temperature sensor readings and you are ready to
|
||||
@ -615,46 +790,146 @@ fan is turned off when the CPU temperature drops to 49 degrees and the
|
||||
HDD temperature drops to 41 degrees. These thresholds cannot
|
||||
currently be controlled.
|
||||
|
||||
The fan level can be controlled with the command:
|
||||
|
||||
echo 'level <level>' > /proc/acpi/ibm/thermal
|
||||
|
||||
Where <level> is an integer from 0 to 7, or one of the words "auto"
|
||||
or "disengaged" (without the quotes). Not all ThinkPads support the
|
||||
"auto" and "disengaged" levels.
|
||||
|
||||
On the X31 and X40 (and ONLY on those models), the fan speed can be
|
||||
controlled to a certain degree. Once the fan is running, it can be
|
||||
forced to run faster or slower with the following command:
|
||||
|
||||
echo 'speed <speed>' > /proc/acpi/ibm/thermal
|
||||
|
||||
The sustainable range of fan speeds on the X40 appears to be from
|
||||
about 3700 to about 7350. Values outside this range either do not have
|
||||
any effect or the fan speed eventually settles somewhere in that
|
||||
range. The fan cannot be stopped or started with this command.
|
||||
|
||||
The ThinkPad's ACPI DSDT code will reprogram the fan on its own when
|
||||
certain conditions are met. It will override any fan programming done
|
||||
through ibm-acpi.
|
||||
through thinkpad-acpi.
|
||||
|
||||
EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
|
||||
---------------------------------------
|
||||
The thinkpad-acpi kernel driver can be programmed to revert the fan
|
||||
level to a safe setting if userspace does not issue one of the procfs
|
||||
fan commands: "enable", "disable", "level" or "watchdog", or if there
|
||||
are no writes to pwm1_enable (or to pwm1 *if and only if* pwm1_enable is
|
||||
set to 1, manual mode) within a configurable amount of time of up to
|
||||
120 seconds. This functionality is called fan safety watchdog.
|
||||
|
||||
Note that the watchdog timer stops after it enables the fan. It will be
|
||||
rearmed again automatically (using the same interval) when one of the
|
||||
above mentioned fan commands is received. The fan watchdog is,
|
||||
therefore, not suitable to protect against fan mode changes made through
|
||||
means other than the "enable", "disable", and "level" procfs fan
|
||||
commands, or the hwmon fan control sysfs interface.
|
||||
|
||||
Procfs notes:
|
||||
|
||||
The fan may be enabled or disabled with the following commands:
|
||||
|
||||
echo enable >/proc/acpi/ibm/fan
|
||||
echo disable >/proc/acpi/ibm/fan
|
||||
|
||||
Placing a fan on level 0 is the same as disabling it. Enabling a fan
|
||||
will try to place it in a safe level if it is too slow or disabled.
|
||||
|
||||
The fan level can be controlled with the command:
|
||||
|
||||
echo 'level <level>' > /proc/acpi/ibm/fan
|
||||
|
||||
Where <level> is an integer from 0 to 7, or one of the words "auto" or
|
||||
"full-speed" (without the quotes). Not all ThinkPads support the "auto"
|
||||
and "full-speed" levels. The driver accepts "disengaged" as an alias for
|
||||
"full-speed", and reports it as "disengaged" for backwards
|
||||
compatibility.
|
||||
|
||||
On the X31 and X40 (and ONLY on those models), the fan speed can be
|
||||
controlled to a certain degree. Once the fan is running, it can be
|
||||
forced to run faster or slower with the following command:
|
||||
|
||||
echo 'speed <speed>' > /proc/acpi/ibm/fan
|
||||
|
||||
The sustainable range of fan speeds on the X40 appears to be from about
|
||||
3700 to about 7350. Values outside this range either do not have any
|
||||
effect or the fan speed eventually settles somewhere in that range. The
|
||||
fan cannot be stopped or started with this command. This functionality
|
||||
is incomplete, and not available through the sysfs interface.
|
||||
|
||||
To program the safety watchdog, use the "watchdog" command.
|
||||
|
||||
echo 'watchdog <interval in seconds>' > /proc/acpi/ibm/fan
|
||||
|
||||
If you want to disable the watchdog, use 0 as the interval.
|
||||
|
||||
Sysfs notes:
|
||||
|
||||
The sysfs interface follows the hwmon subsystem guidelines for the most
|
||||
part, and the exception is the fan safety watchdog.
|
||||
|
||||
Writes to any of the sysfs attributes may return the EINVAL error if
|
||||
that operation is not supported in a given ThinkPad or if the parameter
|
||||
is out-of-bounds, and EPERM if it is forbidden. They may also return
|
||||
EINTR (interrupted system call), and EIO (I/O error while trying to talk
|
||||
to the firmware).
|
||||
|
||||
Features not yet implemented by the driver return ENOSYS.
|
||||
|
||||
hwmon device attribute pwm1_enable:
|
||||
0: PWM offline (fan is set to full-speed mode)
|
||||
1: Manual PWM control (use pwm1 to set fan level)
|
||||
2: Hardware PWM control (EC "auto" mode)
|
||||
3: reserved (Software PWM control, not implemented yet)
|
||||
|
||||
Modes 0 and 2 are not supported by all ThinkPads, and the
|
||||
driver is not always able to detect this. If it does know a
|
||||
mode is unsupported, it will return -EINVAL.
|
||||
|
||||
hwmon device attribute pwm1:
|
||||
Fan level, scaled from the firmware values of 0-7 to the hwmon
|
||||
scale of 0-255. 0 means fan stopped, 255 means highest normal
|
||||
speed (level 7).
|
||||
|
||||
This attribute only commands the fan if pmw1_enable is set to 1
|
||||
(manual PWM control).
|
||||
|
||||
hwmon device attribute fan1_input:
|
||||
Fan tachometer reading, in RPM. May go stale on certain
|
||||
ThinkPads while the EC transitions the PWM to offline mode,
|
||||
which can take up to two minutes. May return rubbish on older
|
||||
ThinkPads.
|
||||
|
||||
driver attribute fan_watchdog:
|
||||
Fan safety watchdog timer interval, in seconds. Minimum is
|
||||
1 second, maximum is 120 seconds. 0 disables the watchdog.
|
||||
|
||||
To stop the fan: set pwm1 to zero, and pwm1_enable to 1.
|
||||
|
||||
To start the fan in a safe mode: set pwm1_enable to 2. If that fails
|
||||
with EINVAL, try to set pwm1_enable to 1 and pwm1 to at least 128 (255
|
||||
would be the safest choice, though).
|
||||
|
||||
|
||||
EXPERIMENTAL: WAN
|
||||
-----------------
|
||||
|
||||
procfs: /proc/acpi/ibm/wan
|
||||
sysfs device attribute: wwan/enable
|
||||
|
||||
This feature is marked EXPERIMENTAL because the implementation
|
||||
directly accesses hardware registers and may not work as expected. USE
|
||||
WITH CAUTION! To use this feature, you need to supply the
|
||||
experimental=1 parameter when loading the module.
|
||||
|
||||
This feature shows the presence and current state of a WAN (Sierra
|
||||
Wireless EV-DO) device. If WAN is installed, the following commands can
|
||||
be used:
|
||||
This feature shows the presence and current state of a W-WAN (Sierra
|
||||
Wireless EV-DO) device.
|
||||
|
||||
It was tested on a Lenovo Thinkpad X60. It should probably work on other
|
||||
Thinkpad models which come with this module installed.
|
||||
|
||||
Procfs notes:
|
||||
|
||||
If the W-WAN card is installed, the following commands can be used:
|
||||
|
||||
echo enable > /proc/acpi/ibm/wan
|
||||
echo disable > /proc/acpi/ibm/wan
|
||||
|
||||
It was tested on a Lenovo Thinkpad X60. It should probably work on other
|
||||
Thinkpad models which come with this module installed.
|
||||
Sysfs notes:
|
||||
|
||||
If the W-WAN card is installed, it can be enabled /
|
||||
disabled through the "wwan/enable" thinkpad-acpi device
|
||||
attribute, and its current status can also be queried.
|
||||
|
||||
enable:
|
||||
0: disables WWAN card / WWAN card is disabled
|
||||
1: enables WWAN card / WWAN card is enabled.
|
||||
|
||||
Note: this interface will be probably be superseeded by the
|
||||
generic rfkill class.
|
||||
|
||||
Multiple Commands, Module Parameters
|
||||
------------------------------------
|
||||
@ -665,64 +940,42 @@ separating them with commas, for example:
|
||||
echo enable,0xffff > /proc/acpi/ibm/hotkey
|
||||
echo lcd_disable,crt_enable > /proc/acpi/ibm/video
|
||||
|
||||
Commands can also be specified when loading the ibm_acpi module, for
|
||||
example:
|
||||
Commands can also be specified when loading the thinkpad-acpi module,
|
||||
for example:
|
||||
|
||||
modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable
|
||||
modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable
|
||||
|
||||
The ibm-acpi kernel driver can be programmed to revert the fan level
|
||||
to a safe setting if userspace does not issue one of the fan commands:
|
||||
"enable", "disable", "level" or "watchdog" within a configurable
|
||||
ammount of time. To do this, use the "watchdog" command.
|
||||
Enabling debugging output
|
||||
-------------------------
|
||||
|
||||
echo 'watchdog <interval>' > /proc/acpi/ibm/fan
|
||||
The module takes a debug paramater which can be used to selectively
|
||||
enable various classes of debugging output, for example:
|
||||
|
||||
Interval is the ammount of time in seconds to wait for one of the
|
||||
above mentioned fan commands before reseting the fan level to a safe
|
||||
one. If set to zero, the watchdog is disabled (default). When the
|
||||
watchdog timer runs out, it does the exact equivalent of the "enable"
|
||||
fan command.
|
||||
modprobe ibm_acpi debug=0xffff
|
||||
|
||||
Note that the watchdog timer stops after it enables the fan. It will
|
||||
be rearmed again automatically (using the same interval) when one of
|
||||
the above mentioned fan commands is received. The fan watchdog is,
|
||||
therefore, not suitable to protect against fan mode changes made
|
||||
through means other than the "enable", "disable", and "level" fan
|
||||
commands.
|
||||
will enable all debugging output classes. It takes a bitmask, so
|
||||
to enable more than one output class, just add their values.
|
||||
|
||||
Debug bitmask Description
|
||||
0x0001 Initialization and probing
|
||||
0x0002 Removal
|
||||
|
||||
There is also a kernel build option to enable more debugging
|
||||
information, which may be necessary to debug driver problems.
|
||||
|
||||
The level of debugging information output by the driver can be changed
|
||||
at runtime through sysfs, using the driver attribute debug_level. The
|
||||
attribute takes the same bitmask as the debug module parameter above.
|
||||
|
||||
Force loading of module
|
||||
-----------------------
|
||||
|
||||
If thinkpad-acpi refuses to detect your ThinkPad, you can try to specify
|
||||
the module parameter force_load=1. Regardless of whether this works or
|
||||
not, please contact ibm-acpi-devel@lists.sourceforge.net with a report.
|
||||
|
||||
|
||||
Example Configuration
|
||||
---------------------
|
||||
Sysfs interface changelog:
|
||||
|
||||
The ACPI support in the kernel is intended to be used in conjunction
|
||||
with a user-space daemon, acpid. The configuration files for this
|
||||
daemon control what actions are taken in response to various ACPI
|
||||
events. An example set of configuration files are included in the
|
||||
config/ directory of the tarball package available on the web
|
||||
site. Note that these are provided for illustration purposes only and
|
||||
may need to be adapted to your particular setup.
|
||||
|
||||
The following utility scripts are used by the example action
|
||||
scripts (included with ibm-acpi for completeness):
|
||||
|
||||
/usr/local/sbin/idectl -- from the hdparm source distribution,
|
||||
see http://www.ibiblio.org/pub/Linux/system/hardware
|
||||
/usr/local/sbin/laptop_mode -- from the Linux kernel source
|
||||
distribution, see Documentation/laptop-mode.txt
|
||||
/sbin/service -- comes with Redhat/Fedora distributions
|
||||
/usr/sbin/hibernate -- from the Software Suspend 2 distribution,
|
||||
see http://softwaresuspend.berlios.de/
|
||||
|
||||
Toan T Nguyen <ntt@physics.ucla.edu> notes that Suse uses the
|
||||
powersave program to suspend ('powersave --suspend-to-ram') or
|
||||
hibernate ('powersave --suspend-to-disk'). This means that the
|
||||
hibernate script is not needed on that distribution.
|
||||
|
||||
Henrik Brix Andersen <brix@gentoo.org> has written a Gentoo ACPI event
|
||||
handler script for the X31. You can get the latest version from
|
||||
http://dev.gentoo.org/~brix/files/x31.sh
|
||||
|
||||
David Schweikert <dws@ee.eth.ch> has written an alternative blank.sh
|
||||
script which works on Debian systems. This scripts has now been
|
||||
extended to also work on Fedora systems and included as the default
|
||||
blank.sh in the distribution.
|
||||
0x000100: Initial sysfs support, as a single platform driver and
|
||||
device.
|
@ -16,7 +16,7 @@ situation as with tcpdump.
|
||||
|
||||
Unlike the packet socket, usbmon has an interface which provides traces
|
||||
in a text format. This is used for two purposes. First, it serves as a
|
||||
common trace exchange format for tools while most sophisticated formats
|
||||
common trace exchange format for tools while more sophisticated formats
|
||||
are finalized. Second, humans can read it in case tools are not available.
|
||||
|
||||
To collect a raw text trace, execute following steps.
|
||||
@ -34,7 +34,7 @@ if usbmon is built into the kernel.
|
||||
Verify that bus sockets are present.
|
||||
|
||||
# ls /sys/kernel/debug/usbmon
|
||||
1s 1t 2s 2t 3s 3t 4s 4t
|
||||
1s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u
|
||||
#
|
||||
|
||||
2. Find which bus connects to the desired device
|
||||
@ -54,7 +54,7 @@ Bus=03 means it's bus 3.
|
||||
|
||||
3. Start 'cat'
|
||||
|
||||
# cat /sys/kernel/debug/usbmon/3t > /tmp/1.mon.out
|
||||
# cat /sys/kernel/debug/usbmon/3u > /tmp/1.mon.out
|
||||
|
||||
This process will be reading until killed. Naturally, the output can be
|
||||
redirected to a desirable location. This is preferred, because it is going
|
||||
@ -75,46 +75,80 @@ that the file size is not excessive for your favourite editor.
|
||||
|
||||
* Raw text data format
|
||||
|
||||
The '1t' type data consists of a stream of events, such as URB submission,
|
||||
Two formats are supported currently: the original, or '1t' format, and
|
||||
the '1u' format. The '1t' format is deprecated in kernel 2.6.21. The '1u'
|
||||
format adds a few fields, such as ISO frame descriptors, interval, etc.
|
||||
It produces slightly longer lines, but otherwise is a perfect superset
|
||||
of '1t' format.
|
||||
|
||||
If it is desired to recognize one from the other in a program, look at the
|
||||
"address" word (see below), where '1u' format adds a bus number. If 2 colons
|
||||
are present, it's the '1t' format, otherwise '1u'.
|
||||
|
||||
Any text format data consists of a stream of events, such as URB submission,
|
||||
URB callback, submission error. Every event is a text line, which consists
|
||||
of whitespace separated words. The number or position of words may depend
|
||||
on the event type, but there is a set of words, common for all types.
|
||||
|
||||
Here is the list of words, from left to right:
|
||||
|
||||
- URB Tag. This is used to identify URBs is normally a kernel mode address
|
||||
of the URB structure in hexadecimal.
|
||||
|
||||
- Timestamp in microseconds, a decimal number. The timestamp's resolution
|
||||
depends on available clock, and so it can be much worse than a microsecond
|
||||
(if the implementation uses jiffies, for example).
|
||||
|
||||
- Event Type. This type refers to the format of the event, not URB type.
|
||||
Available types are: S - submission, C - callback, E - submission error.
|
||||
- "Pipe". The pipe concept is deprecated. This is a composite word, used to
|
||||
be derived from information in pipes. It consists of three fields, separated
|
||||
by colons: URB type and direction, Device address, Endpoint number.
|
||||
|
||||
- "Address" word (formerly a "pipe"). It consists of four fields, separated by
|
||||
colons: URB type and direction, Bus number, Device address, Endpoint number.
|
||||
Type and direction are encoded with two bytes in the following manner:
|
||||
Ci Co Control input and output
|
||||
Zi Zo Isochronous input and output
|
||||
Ii Io Interrupt input and output
|
||||
Bi Bo Bulk input and output
|
||||
Device address and Endpoint number are 3-digit and 2-digit (respectively)
|
||||
decimal numbers, with leading zeroes.
|
||||
- URB Status. In most cases, this field contains a number, sometimes negative,
|
||||
which represents a "status" field of the URB. This field makes no sense for
|
||||
submissions, but is present anyway to help scripts with parsing. When an
|
||||
error occurs, the field contains the error code. In case of a submission of
|
||||
a Control packet, this field contains a Setup Tag instead of an error code.
|
||||
It is easy to tell whether the Setup Tag is present because it is never a
|
||||
number. Thus if scripts find a number in this field, they proceed to read
|
||||
Data Length. If they find something else, like a letter, they read the setup
|
||||
packet before reading the Data Length.
|
||||
Bus number, Device address, and Endpoint are decimal numbers, but they may
|
||||
have leading zeros, for the sake of human readers.
|
||||
|
||||
- URB Status word. This is either a letter, or several numbers separated
|
||||
by colons: URB status, interval, start frame, and error count. Unlike the
|
||||
"address" word, all fields save the status are optional. Interval is printed
|
||||
only for interrupt and isochronous URBs. Start frame is printed only for
|
||||
isochronous URBs. Error count is printed only for isochronous callback
|
||||
events.
|
||||
|
||||
The status field is a decimal number, sometimes negative, which represents
|
||||
a "status" field of the URB. This field makes no sense for submissions, but
|
||||
is present anyway to help scripts with parsing. When an error occurs, the
|
||||
field contains the error code.
|
||||
|
||||
In case of a submission of a Control packet, this field contains a Setup Tag
|
||||
instead of an group of numbers. It is easy to tell whether the Setup Tag is
|
||||
present because it is never a number. Thus if scripts find a set of numbers
|
||||
in this word, they proceed to read Data Length (except for isochronous URBs).
|
||||
If they find something else, like a letter, they read the setup packet before
|
||||
reading the Data Length or isochronous descriptors.
|
||||
|
||||
- Setup packet, if present, consists of 5 words: one of each for bmRequestType,
|
||||
bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0.
|
||||
These words are safe to decode if Setup Tag was 's'. Otherwise, the setup
|
||||
packet was present, but not captured, and the fields contain filler.
|
||||
|
||||
- Number of isochronous frame descriptors and descriptors themselves.
|
||||
If an Isochronous transfer event has a set of descriptors, a total number
|
||||
of them in an URB is printed first, then a word per descriptor, up to a
|
||||
total of 5. The word consists of 3 colon-separated decimal numbers for
|
||||
status, offset, and length respectively. For submissions, initial length
|
||||
is reported. For callbacks, actual length is reported.
|
||||
|
||||
- Data Length. For submissions, this is the requested length. For callbacks,
|
||||
this is the actual length.
|
||||
|
||||
- Data tag. The usbmon may not always capture data, even if length is nonzero.
|
||||
The data words are present only if this tag is '='.
|
||||
|
||||
- Data words follow, in big endian hexadecimal format. Notice that they are
|
||||
not machine words, but really just a byte stream split into words to make
|
||||
it easier to read. Thus, the last word may contain from one to four bytes.
|
||||
@ -153,20 +187,18 @@ class ParsedLine {
|
||||
}
|
||||
}
|
||||
|
||||
This format may be changed in the future.
|
||||
|
||||
Examples:
|
||||
|
||||
An input control transfer to get a port status.
|
||||
|
||||
d5ea89a0 3575914555 S Ci:001:00 s a3 00 0000 0003 0004 4 <
|
||||
d5ea89a0 3575914560 C Ci:001:00 0 4 = 01050000
|
||||
d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 <
|
||||
d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000
|
||||
|
||||
An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper
|
||||
to a storage device at address 5:
|
||||
|
||||
dd65f0e8 4128379752 S Bo:005:02 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000
|
||||
dd65f0e8 4128379808 C Bo:005:02 0 31 >
|
||||
dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000
|
||||
dd65f0e8 4128379808 C Bo:1:005:2 0 31 >
|
||||
|
||||
* Raw binary format and API
|
||||
|
||||
|
@ -143,3 +143,5 @@
|
||||
142 -> Sabrent TV-FM (bttv version)
|
||||
143 -> Hauppauge ImpactVCB (bt878) [0070:13eb]
|
||||
144 -> MagicTV
|
||||
145 -> SSAI Security Video Interface [4149:5353]
|
||||
146 -> SSAI Ultrasound Video Interface [414a:5353]
|
||||
|
@ -37,7 +37,7 @@
|
||||
36 -> AVerTV 303 (M126) [1461:000a]
|
||||
37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202]
|
||||
38 -> Hauppauge Nova-SE2 DVB-S [0070:9200]
|
||||
39 -> KWorld DVB-S 100 [17de:08b2]
|
||||
39 -> KWorld DVB-S 100 [17de:08b2,1421:0341]
|
||||
40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402]
|
||||
41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802]
|
||||
42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025,1822:0019]
|
||||
|
18
Documentation/video4linux/CARDLIST.ivtv
Normal file
18
Documentation/video4linux/CARDLIST.ivtv
Normal file
@ -0,0 +1,18 @@
|
||||
1 -> Hauppauge WinTV PVR-250
|
||||
2 -> Hauppauge WinTV PVR-350
|
||||
3 -> Hauppauge WinTV PVR-150 or PVR-500
|
||||
4 -> AVerMedia M179 [1461:a3ce,1461:a3cf]
|
||||
5 -> Yuan MPG600/Kuroutoshikou iTVC16-STVLP [12ab:fff3,12ab:ffff]
|
||||
6 -> Yuan MPG160/Kuroutoshikou iTVC15-STVLP [12ab:0000,10fc:40a0]
|
||||
7 -> Yuan PG600/DiamondMM PVR-550 [ff92:0070,ffab:0600]
|
||||
8 -> Adaptec AVC-2410 [9005:0093]
|
||||
9 -> Adaptec AVC-2010 [9005:0092]
|
||||
10 -> NAGASE TRANSGEAR 5000TV [1461:bfff]
|
||||
11 -> AOpen VA2000MAX-STN6 [0000:ff5f]
|
||||
12 -> YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP [12ab:0600,fbab:0600,1154:0523]
|
||||
13 -> I/O Data GV-MVP/RX [10fc:d01e,10fc:d038,10fc:d039]
|
||||
14 -> I/O Data GV-MVP/RX2E [10fc:d025]
|
||||
15 -> GOTVIEW PCI DVD (partial support only) [12ab:0600]
|
||||
16 -> GOTVIEW PCI DVD2 Deluxe [ffac:0600]
|
||||
17 -> Yuan MPC622 [ff01:d998]
|
||||
18 -> Digital Cowboy DCT-MTVP1 [1461:bfff]
|
@ -53,7 +53,7 @@
|
||||
52 -> AverMedia AverTV/305 [1461:2108]
|
||||
53 -> ASUS TV-FM 7135 [1043:4845]
|
||||
54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,1489:0214,5168:0304]
|
||||
55 -> LifeView FlyDVB-T DUO [5168:0306]
|
||||
55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306]
|
||||
56 -> Avermedia AVerTV 307 [1461:a70a]
|
||||
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
|
||||
58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370]
|
||||
@ -76,7 +76,7 @@
|
||||
75 -> AVerMedia AVerTVHD MCE A180 [1461:1044]
|
||||
76 -> SKNet MonsterTV Mobile [1131:4ee9]
|
||||
77 -> Pinnacle PCTV 40i/50i/110i (saa7133) [11bd:002e]
|
||||
78 -> ASUSTeK P7131 Dual [1043:4862,1043:4876]
|
||||
78 -> ASUSTeK P7131 Dual [1043:4862,1043:4857]
|
||||
79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
|
||||
80 -> ASUS Digimatrix TV [1043:0210]
|
||||
81 -> Philips Tiger reference design [1131:2018]
|
||||
@ -107,3 +107,7 @@
|
||||
106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344]
|
||||
107 -> Encore ENLTV-FM [1131:230f]
|
||||
108 -> Terratec Cinergy HT PCI [153b:1175]
|
||||
109 -> Philips Tiger - S Reference design
|
||||
110 -> Avermedia M102 [1461:f31e]
|
||||
111 -> ASUS P7131 4871 [1043:4871]
|
||||
112 -> ASUSTeK P7131 Hybrid [1043:4876]
|
||||
|
64
Documentation/video4linux/CARDLIST.usbvision
Normal file
64
Documentation/video4linux/CARDLIST.usbvision
Normal file
@ -0,0 +1,64 @@
|
||||
0 -> Xanboo [0a6f:0400]
|
||||
1 -> Belkin USB VideoBus II Adapter [050d:0106]
|
||||
2 -> Belkin Components USB VideoBus [050d:0207]
|
||||
3 -> Belkin USB VideoBus II [050d:0208]
|
||||
4 -> echoFX InterView Lite [0571:0002]
|
||||
5 -> USBGear USBG-V1 resp. HAMA USB [0573:0003]
|
||||
6 -> D-Link V100 [0573:0400]
|
||||
7 -> X10 USB Camera [0573:2000]
|
||||
8 -> Hauppauge WinTV USB Live (PAL B/G) [0573:2d00]
|
||||
9 -> Hauppauge WinTV USB Live Pro (NTSC M/N) [0573:2d01]
|
||||
10 -> Zoran Co. PMD (Nogatech) AV-grabber Manhattan [0573:2101]
|
||||
11 -> Nogatech USB-TV (NTSC) FM [0573:4100]
|
||||
12 -> PNY USB-TV (NTSC) FM [0573:4110]
|
||||
13 -> PixelView PlayTv-USB PRO (PAL) FM [0573:4450]
|
||||
14 -> ZTV ZT-721 2.4GHz USB A/V Receiver [0573:4550]
|
||||
15 -> Hauppauge WinTV USB (NTSC M/N) [0573:4d00]
|
||||
16 -> Hauppauge WinTV USB (PAL B/G) [0573:4d01]
|
||||
17 -> Hauppauge WinTV USB (PAL I) [0573:4d02]
|
||||
18 -> Hauppauge WinTV USB (PAL/SECAM L) [0573:4d03]
|
||||
19 -> Hauppauge WinTV USB (PAL D/K) [0573:4d04]
|
||||
20 -> Hauppauge WinTV USB (NTSC FM) [0573:4d10]
|
||||
21 -> Hauppauge WinTV USB (PAL B/G FM) [0573:4d11]
|
||||
22 -> Hauppauge WinTV USB (PAL I FM) [0573:4d12]
|
||||
23 -> Hauppauge WinTV USB (PAL D/K FM) [0573:4d14]
|
||||
24 -> Hauppauge WinTV USB Pro (NTSC M/N) [0573:4d2a]
|
||||
25 -> Hauppauge WinTV USB Pro (NTSC M/N) V2 [0573:4d2b]
|
||||
26 -> Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) [0573:4d2c]
|
||||
27 -> Hauppauge WinTV USB Pro (NTSC M/N) V3 [0573:4d20]
|
||||
28 -> Hauppauge WinTV USB Pro (PAL B/G) [0573:4d21]
|
||||
29 -> Hauppauge WinTV USB Pro (PAL I) [0573:4d22]
|
||||
30 -> Hauppauge WinTV USB Pro (PAL/SECAM L) [0573:4d23]
|
||||
31 -> Hauppauge WinTV USB Pro (PAL D/K) [0573:4d24]
|
||||
32 -> Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) [0573:4d25]
|
||||
33 -> Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 [0573:4d26]
|
||||
34 -> Hauppauge WinTV USB Pro (PAL B/G) V2 [0573:4d27]
|
||||
35 -> Hauppauge WinTV USB Pro (PAL B/G,D/K) [0573:4d28]
|
||||
36 -> Hauppauge WinTV USB Pro (PAL I,D/K) [0573:4d29]
|
||||
37 -> Hauppauge WinTV USB Pro (NTSC M/N FM) [0573:4d30]
|
||||
38 -> Hauppauge WinTV USB Pro (PAL B/G FM) [0573:4d31]
|
||||
39 -> Hauppauge WinTV USB Pro (PAL I FM) [0573:4d32]
|
||||
40 -> Hauppauge WinTV USB Pro (PAL D/K FM) [0573:4d34]
|
||||
41 -> Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) [0573:4d35]
|
||||
42 -> Hauppauge WinTV USB Pro (Temic PAL B/G FM) [0573:4d36]
|
||||
43 -> Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) [0573:4d37]
|
||||
44 -> Hauppauge WinTV USB Pro (NTSC M/N FM) V2 [0573:4d38]
|
||||
45 -> Camtel Technology USB TV Genie Pro FM Model TVB330 [0768:0006]
|
||||
46 -> Digital Video Creator I [07d0:0001]
|
||||
47 -> Global Village GV-007 (NTSC) [07d0:0002]
|
||||
48 -> Dazzle Fusion Model DVC-50 Rev 1 (NTSC) [07d0:0003]
|
||||
49 -> Dazzle Fusion Model DVC-80 Rev 1 (PAL) [07d0:0004]
|
||||
50 -> Dazzle Fusion Model DVC-90 Rev 1 (SECAM) [07d0:0005]
|
||||
51 -> Eskape Labs MyTV2Go [07f8:9104]
|
||||
52 -> Pinnacle Studio PCTV USB (PAL) [2304:010d]
|
||||
53 -> Pinnacle Studio PCTV USB (SECAM) [2304:0109]
|
||||
54 -> Pinnacle Studio PCTV USB (PAL) FM [2304:0110]
|
||||
55 -> Miro PCTV USB [2304:0111]
|
||||
56 -> Pinnacle Studio PCTV USB (NTSC) FM [2304:0112]
|
||||
57 -> Pinnacle Studio PCTV USB (PAL) FM V2 [2304:0210]
|
||||
58 -> Pinnacle Studio PCTV USB (NTSC) FM V2 [2304:0212]
|
||||
59 -> Pinnacle Studio PCTV USB (PAL) FM V3 [2304:0214]
|
||||
60 -> Pinnacle Studio Linx Video input cable (NTSC) [2304:0300]
|
||||
61 -> Pinnacle Studio Linx Video input cable (PAL) [2304:0301]
|
||||
62 -> Pinnacle PCTV Bungee USB (PAL) FM [2304:0419]
|
||||
63 -> Hauppauge WinTv-USB [2400:4200]
|
187
Documentation/video4linux/README.ivtv
Normal file
187
Documentation/video4linux/README.ivtv
Normal file
@ -0,0 +1,187 @@
|
||||
|
||||
ivtv release notes
|
||||
==================
|
||||
|
||||
This is a v4l2 device driver for the Conexant cx23415/6 MPEG encoder/decoder.
|
||||
The cx23415 can do both encoding and decoding, the cx23416 can only do MPEG
|
||||
encoding. Currently the only card featuring full decoding support is the
|
||||
Hauppauge PVR-350.
|
||||
|
||||
NOTE: this driver requires the latest encoder firmware (version 2.06.039, size
|
||||
376836 bytes). Get the firmware from here:
|
||||
|
||||
http://dl.ivtvdriver.org/ivtv/firmware/firmware.tar.gz
|
||||
|
||||
NOTE: 'normal' TV applications do not work with this driver, you need
|
||||
an application that can handle MPEG input such as mplayer, xine, MythTV,
|
||||
etc.
|
||||
|
||||
The primary goal of the IVTV project is to provide a "clean room" Linux
|
||||
Open Source driver implementation for video capture cards based on the
|
||||
iCompression iTVC15 or Conexant CX23415/CX23416 MPEG Codec.
|
||||
|
||||
Features:
|
||||
* Hardware mpeg2 capture of broadcast video (and sound) via the tuner or
|
||||
S-Video/Composite and audio line-in.
|
||||
* Hardware mpeg2 capture of FM radio where hardware support exists
|
||||
* Supports NTSC, PAL, SECAM with stereo sound
|
||||
* Supports SAP and bilingual transmissions.
|
||||
* Supports raw VBI (closed captions and teletext).
|
||||
* Supports sliced VBI (closed captions and teletext) and is able to insert
|
||||
this into the captured MPEG stream.
|
||||
* Supports raw YUV and PCM input.
|
||||
|
||||
Additional features for the PVR-350 (CX23415 based):
|
||||
* Provides hardware mpeg2 playback
|
||||
* Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
|
||||
video signal)
|
||||
* Provides a framebuffer (allowing X applications to appear on the video
|
||||
device) (this framebuffer is not yet part of the kernel. In the meantime it
|
||||
is available from www.ivtvdriver.org).
|
||||
* Supports raw YUV output.
|
||||
|
||||
IMPORTANT: In case of problems first read this page:
|
||||
http://www.ivtvdriver.org/index.php/Troubleshooting
|
||||
|
||||
See also:
|
||||
|
||||
Homepage + Wiki
|
||||
http://www.ivtvdriver.org
|
||||
|
||||
IRC
|
||||
irc://irc.freenode.net/ivtv-dev
|
||||
|
||||
----------------------------------------------------------
|
||||
|
||||
Devices
|
||||
=======
|
||||
|
||||
A maximum of 12 ivtv boards are allowed at the moment.
|
||||
|
||||
Cards that don't have a video output capability (i.e. non PVR350 cards)
|
||||
lack the vbi8, vbi16, video16 and video48 devices. They also do not
|
||||
support the framebuffer device /dev/fbx for OSD.
|
||||
|
||||
The radio0 device may or may not be present, depending on whether the
|
||||
card has a radio tuner or not.
|
||||
|
||||
Here is a list of the base v4l devices:
|
||||
crw-rw---- 1 root video 81, 0 Jun 19 22:22 /dev/video0
|
||||
crw-rw---- 1 root video 81, 16 Jun 19 22:22 /dev/video16
|
||||
crw-rw---- 1 root video 81, 24 Jun 19 22:22 /dev/video24
|
||||
crw-rw---- 1 root video 81, 32 Jun 19 22:22 /dev/video32
|
||||
crw-rw---- 1 root video 81, 48 Jun 19 22:22 /dev/video48
|
||||
crw-rw---- 1 root video 81, 64 Jun 19 22:22 /dev/radio0
|
||||
crw-rw---- 1 root video 81, 224 Jun 19 22:22 /dev/vbi0
|
||||
crw-rw---- 1 root video 81, 228 Jun 19 22:22 /dev/vbi8
|
||||
crw-rw---- 1 root video 81, 232 Jun 19 22:22 /dev/vbi16
|
||||
|
||||
Base devices
|
||||
============
|
||||
|
||||
For every extra card you have the numbers increased by one. For example,
|
||||
/dev/video0 is listed as the 'base' encoding capture device so we have:
|
||||
|
||||
/dev/video0 is the encoding capture device for the first card (card 0)
|
||||
/dev/video1 is the encoding capture device for the second card (card 1)
|
||||
/dev/video2 is the encoding capture device for the third card (card 2)
|
||||
|
||||
Note that if the first card doesn't have a feature (eg no decoder, so no
|
||||
video16, the second card will still use video17. The simple rule is 'add
|
||||
the card number to the base device number'. If you have other capture
|
||||
cards (e.g. WinTV PCI) that are detected first, then you have to tell
|
||||
the ivtv module about it so that it will start counting at 1 (or 2, or
|
||||
whatever). Otherwise the device numbers can get confusing. The ivtv
|
||||
'ivtv_first_minor' module option can be used for that.
|
||||
|
||||
|
||||
/dev/video0
|
||||
The encoding capture device(s).
|
||||
Read-only.
|
||||
|
||||
Reading from this device gets you the MPEG1/2 program stream.
|
||||
Example:
|
||||
|
||||
cat /dev/video0 > my.mpg (you need to hit ctrl-c to exit)
|
||||
|
||||
|
||||
/dev/video16
|
||||
The decoder output device(s)
|
||||
Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
|
||||
|
||||
An mpeg2 stream sent to this device will appear on the selected video
|
||||
display, audio will appear on the line-out/audio out. It is only
|
||||
available for cards that support video out. Example:
|
||||
|
||||
cat my.mpg >/dev/video16
|
||||
|
||||
|
||||
/dev/video24
|
||||
The raw audio capture device(s).
|
||||
Read-only
|
||||
|
||||
The raw audio PCM stereo stream from the currently selected
|
||||
tuner or audio line-in. Reading from this device results in a raw
|
||||
(signed 16 bit Little Endian, 48000 Hz, stereo pcm) capture.
|
||||
This device only captures audio. This should be replaced by an ALSA
|
||||
device in the future.
|
||||
Note that there is no corresponding raw audio output device, this is
|
||||
not supported in the decoder firmware.
|
||||
|
||||
|
||||
/dev/video32
|
||||
The raw video capture device(s)
|
||||
Read-only
|
||||
|
||||
The raw YUV video output from the current video input. The YUV format
|
||||
is non-standard (V4L2_PIX_FMT_HM12).
|
||||
|
||||
Note that the YUV and PCM streams are not synchronized, so they are of
|
||||
limited use.
|
||||
|
||||
|
||||
/dev/video48
|
||||
The raw video display device(s)
|
||||
Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
|
||||
|
||||
Writes a YUV stream to the decoder of the card.
|
||||
|
||||
|
||||
/dev/radio0
|
||||
The radio tuner device(s)
|
||||
Cannot be read or written.
|
||||
|
||||
Used to enable the radio tuner and tune to a frequency. You cannot
|
||||
read or write audio streams with this device. Once you use this
|
||||
device to tune the radio, use /dev/video24 to read the raw pcm stream
|
||||
or /dev/video0 to get an mpeg2 stream with black video.
|
||||
|
||||
|
||||
/dev/vbi0
|
||||
The 'vertical blank interval' (Teletext, CC, WSS etc) capture device(s)
|
||||
Read-only
|
||||
|
||||
Captures the raw (or sliced) video data sent during the Vertical Blank
|
||||
Interval. This data is used to encode teletext, closed captions, VPS,
|
||||
widescreen signalling, electronic program guide information, and other
|
||||
services.
|
||||
|
||||
|
||||
/dev/vbi8
|
||||
Processed vbi feedback device(s)
|
||||
Read-only. Only present if the MPEG decoder (i.e. CX23415) exists.
|
||||
|
||||
The sliced VBI data embedded in an MPEG stream is reproduced on this
|
||||
device. So while playing back a recording on /dev/video16, you can
|
||||
read the embedded VBI data from /dev/vbi8.
|
||||
|
||||
|
||||
/dev/vbi16
|
||||
The vbi 'display' device(s)
|
||||
Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
|
||||
|
||||
Can be used to send sliced VBI data to the video-out connector.
|
||||
|
||||
---------------------------------
|
||||
|
||||
Hans Verkuil <hverkuil@xs4all.nl>
|
@ -624,11 +624,11 @@ out what values are bad when it hangs.
|
||||
2A00
|
||||
bits 0:2
|
||||
osd colour mode
|
||||
000 = 8 bit indexed
|
||||
001 = 16 bit (565)
|
||||
010 = 15 bit (555)
|
||||
011 = 12 bit (444)
|
||||
100 = 32 bit (8888)
|
||||
101 = 8 bit indexed
|
||||
|
||||
bits 4:5
|
||||
osd display bpp
|
||||
@ -676,9 +676,11 @@ out what values are bad when it hangs.
|
||||
completely transparent. When using 565, 555 or 444 colour modes, the
|
||||
colour key is always 16 bits wide. The colour to key on is set in Reg 2A18.
|
||||
|
||||
Local alpha is a per-pixel 256 step transparency, with 0 being transparent
|
||||
and 255 being solid. This is only available in 32 bit & 8 bit indexed
|
||||
colour modes.
|
||||
Local alpha works differently depending on the colour mode. For 32bpp & 8
|
||||
bit indexed, local alpha is a per-pixel 256 step transparency, with 0 being
|
||||
transparent and 255 being solid. For the 16bpp modes 555 & 444, the unused
|
||||
bit(s) act as a simple transparency switch, with 0 being solid & 1 being
|
||||
fully transparent. There is no local alpha support for 16bit 565.
|
||||
|
||||
Global alpha is a 256 step transparency that applies to the entire osd,
|
||||
with 0 being transparent & 255 being solid.
|
||||
@ -811,5 +813,5 @@ out what values are bad when it hangs.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
v0.3 - 2 February 2007 - Ian Armstrong (ian@iarmst.demon.co.uk)
|
||||
v0.4 - 12 March 2007 - Ian Armstrong (ian@iarmst.demon.co.uk)
|
||||
|
||||
|
@ -663,12 +663,13 @@ Param[0]
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Name CX2341X_ENC_UNKNOWN
|
||||
Name CX2341X_ENC_SET_VERT_CROP_LINE
|
||||
Enum 219/0xDB
|
||||
Description
|
||||
Unknown API, it's used by Hauppauge though.
|
||||
Something to do with 'Vertical Crop Line'
|
||||
Param[0]
|
||||
0 This is the value Hauppauge uses, Unknown what it means.
|
||||
If saa7114 and raw VBI capture and 60 Hz, then set to 10001.
|
||||
Else 0.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@ -682,11 +683,9 @@ Param[0]
|
||||
Command number:
|
||||
1=set initial SCR value when starting encoding (works).
|
||||
2=set quality mode (apparently some test setting).
|
||||
3=setup advanced VIM protection handling (supposedly only for the cx23416
|
||||
for raw YUV).
|
||||
Actually it looks like this should be 0 for saa7114/5 based card and 1
|
||||
for cx25840 based cards.
|
||||
4=generate artificial PTS timestamps
|
||||
3=setup advanced VIM protection handling.
|
||||
Always 1 for the cx23416 and 0 for cx23415.
|
||||
4=generate DVD compatible PTS timestamps
|
||||
5=USB flush mode
|
||||
6=something to do with the quantization matrix
|
||||
7=set navigation pack insertion for DVD: adds 0xbf (private stream 2)
|
||||
@ -698,7 +697,9 @@ Param[0]
|
||||
9=set history parameters of the video input module
|
||||
10=set input field order of VIM
|
||||
11=set quantization matrix
|
||||
12=reset audio interface
|
||||
12=reset audio interface after channel change or input switch (has no argument).
|
||||
Needed for the cx2584x, not needed for the mspx4xx, but it doesn't seem to
|
||||
do any harm calling it regardless.
|
||||
13=set audio volume delay
|
||||
14=set audio delay
|
||||
|
||||
|
@ -21,7 +21,11 @@ Enum 66/0x42
|
||||
Description
|
||||
Query OSD format
|
||||
Result[0]
|
||||
0=8bit index, 4=AlphaRGB 8:8:8:8
|
||||
0=8bit index
|
||||
1=16bit RGB 5:6:5
|
||||
2=16bit ARGB 1:5:5:5
|
||||
3=16bit ARGB 1:4:4:4
|
||||
4=32bit ARGB 8:8:8:8
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@ -30,7 +34,11 @@ Enum 67/0x43
|
||||
Description
|
||||
Assign pixel format
|
||||
Param[0]
|
||||
0=8bit index, 4=AlphaRGB 8:8:8:8
|
||||
0=8bit index
|
||||
1=16bit RGB 5:6:5
|
||||
2=16bit ARGB 1:5:5:5
|
||||
3=16bit ARGB 1:4:4:4
|
||||
4=32bit ARGB 8:8:8:8
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -5,10 +5,9 @@ Vaio Picturebook Motion Eye Camera Driver Readme
|
||||
Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
|
||||
|
||||
This driver enable the use of video4linux compatible applications with the
|
||||
Motion Eye camera. This driver requires the "Sony Vaio Programmable I/O
|
||||
Control Device" driver (which can be found in the "Character drivers"
|
||||
section of the kernel configuration utility) to be compiled and installed
|
||||
(using its "camera=1" parameter).
|
||||
Motion Eye camera. This driver requires the "Sony Laptop Extras" driver (which
|
||||
can be found in the "Misc devices" section of the kernel configuration utility)
|
||||
to be compiled and installed (using its "camera=1" parameter).
|
||||
|
||||
It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
|
||||
|
||||
|
@ -25,7 +25,7 @@ Index
|
||||
|
||||
1. Copyright
|
||||
============
|
||||
Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>
|
||||
Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it>
|
||||
|
||||
|
||||
2. Disclaimer
|
||||
@ -216,10 +216,10 @@ Description: Debugging information level, from 0 to 3:
|
||||
1 = critical errors
|
||||
2 = significant informations
|
||||
3 = more verbose messages
|
||||
Level 3 is useful for testing only, when only one device
|
||||
is used. It also shows some more informations about the
|
||||
hardware being detected. This parameter can be changed at
|
||||
runtime thanks to the /sys filesystem interface.
|
||||
Level 3 is useful for testing only. It also shows some more
|
||||
informations about the hardware being detected.
|
||||
This parameter can be changed at runtime thanks to the /sys
|
||||
filesystem interface.
|
||||
Default: 2
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@ -235,7 +235,7 @@ created in the /sys/class/video4linux/videoX directory. You can set the green
|
||||
channel's gain by writing the desired value to it. The value may range from 0
|
||||
to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103,
|
||||
SN9C105 and SN9C120 bridges.
|
||||
Similarly, only for the SN9C103, SN9C105 and SN9120 controllers, blue and red
|
||||
Similarly, only for the SN9C103, SN9C105 and SN9C120 controllers, blue and red
|
||||
gain control files are available in the same directory, for which accepted
|
||||
values may range from 0 to 127.
|
||||
|
||||
@ -402,38 +402,49 @@ Vendor ID Product ID
|
||||
0x0c45 0x60bc
|
||||
0x0c45 0x60be
|
||||
0x0c45 0x60c0
|
||||
0x0c45 0x60c2
|
||||
0x0c45 0x60c8
|
||||
0x0c45 0x60cc
|
||||
0x0c45 0x60ea
|
||||
0x0c45 0x60ec
|
||||
0x0c45 0x60ef
|
||||
0x0c45 0x60fa
|
||||
0x0c45 0x60fb
|
||||
0x0c45 0x60fc
|
||||
0x0c45 0x60fe
|
||||
0x0c45 0x6102
|
||||
0x0c45 0x6108
|
||||
0x0c45 0x610f
|
||||
0x0c45 0x6130
|
||||
0x0c45 0x6138
|
||||
0x0c45 0x613a
|
||||
0x0c45 0x613b
|
||||
0x0c45 0x613c
|
||||
0x0c45 0x613e
|
||||
|
||||
The list above does not imply that all those devices work with this driver: up
|
||||
until now only the ones that assemble the following image sensors are
|
||||
supported; kernel messages will always tell you whether this is the case (see
|
||||
"Module loading" paragraph):
|
||||
until now only the ones that assemble the following pairs of SN9C1xx bridges
|
||||
and image sensors are supported; kernel messages will always tell you whether
|
||||
this is the case (see "Module loading" paragraph):
|
||||
|
||||
Model Manufacturer
|
||||
----- ------------
|
||||
HV7131D Hynix Semiconductor, Inc.
|
||||
MI-0343 Micron Technology, Inc.
|
||||
OV7630 OmniVision Technologies, Inc.
|
||||
OV7660 OmniVision Technologies, Inc.
|
||||
PAS106B PixArt Imaging, Inc.
|
||||
PAS202BCA PixArt Imaging, Inc.
|
||||
PAS202BCB PixArt Imaging, Inc.
|
||||
TAS5110C1B Taiwan Advanced Sensor Corporation
|
||||
TAS5130D1B Taiwan Advanced Sensor Corporation
|
||||
Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120
|
||||
-------------------------------------------------------------------------------
|
||||
HV7131D Hynix Semiconductor | Yes No No No
|
||||
HV7131R Hynix Semiconductor | No Yes Yes Yes
|
||||
MI-0343 Micron Technology | Yes No No No
|
||||
MI-0360 Micron Technology | No Yes No No
|
||||
OV7630 OmniVision Technologies | Yes Yes No No
|
||||
OV7660 OmniVision Technologies | No No Yes Yes
|
||||
PAS106B PixArt Imaging | Yes No No No
|
||||
PAS202B PixArt Imaging | Yes Yes No No
|
||||
TAS5110C1B Taiwan Advanced Sensor | Yes No No No
|
||||
TAS5110D Taiwan Advanced Sensor | Yes No No No
|
||||
TAS5130D1B Taiwan Advanced Sensor | Yes No No No
|
||||
|
||||
Some of the available control settings of each image sensor are supported
|
||||
"Yes" means that the pair is supported by the driver, while "No" means that the
|
||||
pair does not exist or is not supported by the driver.
|
||||
|
||||
Only some of the available control settings of each image sensor are supported
|
||||
through the V4L2 interface.
|
||||
|
||||
Donations of new models for further testing and support would be much
|
||||
@ -482,8 +493,8 @@ The SN9C1xx PC Camera Controllers can send images in two possible video
|
||||
formats over the USB: either native "Sequential RGB Bayer" or compressed.
|
||||
The compression is used to achieve high frame rates. With regard to the
|
||||
SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding
|
||||
algorithm described below, while the SN9C105 and SN9C120 the compression is
|
||||
based on the JPEG standard.
|
||||
algorithm described below, while with regard to the SN9C105 and SN9C120 the
|
||||
compression is based on the JPEG standard.
|
||||
The current video format may be selected or queried from the user application
|
||||
by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2
|
||||
API specifications.
|
||||
@ -573,4 +584,5 @@ order):
|
||||
- Mizuno Takafumi for the donation of a webcam;
|
||||
- an "anonymous" donator (who didn't want his name to be revealed) for the
|
||||
donation of a webcam.
|
||||
- an anonymous donator for the donation of four webcams.
|
||||
- an anonymous donator for the donation of four webcams and two boards with ten
|
||||
image sensors.
|
||||
|
65
Documentation/video4linux/zr364xx.txt
Normal file
65
Documentation/video4linux/zr364xx.txt
Normal file
@ -0,0 +1,65 @@
|
||||
Zoran 364xx based USB webcam module version 0.72
|
||||
site: http://royale.zerezo.com/zr364xx/
|
||||
mail: royale@zerezo.com
|
||||
|
||||
introduction:
|
||||
This brings support under Linux for the Aiptek PocketDV 3300 in webcam mode.
|
||||
If you just want to get on your PC the pictures and movies on the camera, you should use the usb-storage module instead.
|
||||
The driver works with several other cameras in webcam mode (see the list below).
|
||||
Maybe this code can work for other JPEG/USB cams based on the Coach chips from Zoran?
|
||||
Possible chipsets are : ZR36430 (ZR36430BGC) and maybe ZR36431, ZR36440, ZR36442...
|
||||
You can try the experience changing the vendor/product ID values (look at the source code).
|
||||
You can get these values by looking at /var/log/messages when you plug your camera, or by typing : cat /proc/bus/usb/devices.
|
||||
If you manage to use your cam with this code, you can send me a mail (royale@zerezo.com) with the name of your cam and a patch if needed.
|
||||
This is a beta release of the driver.
|
||||
Since version 0.70, this driver is only compatible with V4L2 API and 2.6.x kernels.
|
||||
If you need V4L1 or 2.4x kernels support, please use an older version, but the code is not maintained anymore.
|
||||
Good luck!
|
||||
|
||||
install:
|
||||
In order to use this driver, you must compile it with your kernel.
|
||||
Location: Device Drivers -> Multimedia devices -> Video For Linux -> Video Capture Adapters -> V4L USB devices
|
||||
|
||||
usage:
|
||||
modprobe zr364xx debug=X mode=Y
|
||||
- debug : set to 1 to enable verbose debug messages
|
||||
- mode : 0 = 320x240, 1 = 160x120, 2 = 640x480
|
||||
You can then use the camera with V4L2 compatible applications, for example Ekiga.
|
||||
To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1
|
||||
|
||||
links :
|
||||
http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
|
||||
http://www.harmwal.nl/pccam880/ (this project also supports cameras based on this chipset)
|
||||
|
||||
supported devices:
|
||||
------ ------- ----------- -----
|
||||
Vendor Product Distributor Model
|
||||
------ ------- ----------- -----
|
||||
0x08ca 0x0109 Aiptek PocketDV 3300
|
||||
0x08ca 0x0109 Maxell Maxcam PRO DV3
|
||||
0x041e 0x4024 Creative PC-CAM 880
|
||||
0x0d64 0x0108 Aiptek Fidelity 3200
|
||||
0x0d64 0x0108 Praktica DCZ 1.3 S
|
||||
0x0d64 0x0108 Genius Digital Camera (?)
|
||||
0x0d64 0x0108 DXG Technology Fashion Cam
|
||||
0x0546 0x3187 Polaroid iON 230
|
||||
0x0d64 0x3108 Praktica Exakta DC 2200
|
||||
0x0d64 0x3108 Genius G-Shot D211
|
||||
0x0595 0x4343 Concord Eye-Q Duo 1300
|
||||
0x0595 0x4343 Concord Eye-Q Duo 2000
|
||||
0x0595 0x4343 Fujifilm EX-10
|
||||
0x0595 0x4343 Ricoh RDC-6000
|
||||
0x0595 0x4343 Digitrex DSC 1300
|
||||
0x0595 0x4343 Firstline FDC 2000
|
||||
0x0bb0 0x500d Concord EyeQ Go Wireless
|
||||
0x0feb 0x2004 CRS Electronic 3.3 Digital Camera
|
||||
0x0feb 0x2004 Packard Bell DSC-300
|
||||
0x055f 0xb500 Mustek MDC 3000
|
||||
0x08ca 0x2062 Aiptek PocketDV 5700
|
||||
0x052b 0x1a18 Chiphead Megapix V12
|
||||
0x04c8 0x0729 Konica Revio 2
|
||||
0x04f2 0xa208 Creative PC-CAM 850
|
||||
0x0784 0x0040 Traveler Slimline X5
|
||||
0x06d6 0x0034 Trust Powerc@m 750
|
||||
0x0a17 0x0062 Pentax Optio 50L
|
||||
|
@ -293,7 +293,3 @@ Debugging
|
||||
stuck (default)
|
||||
|
||||
Miscellaneous
|
||||
|
||||
noreplacement Don't replace instructions with more appropriate ones
|
||||
for the CPU. This may be useful on asymmetric MP systems
|
||||
where some CPUs have less capabilities than others.
|
||||
|
213
MAINTAINERS
213
MAINTAINERS
@ -55,7 +55,7 @@ trivial patch so apply some common sense.
|
||||
|
||||
8. Happy hacking.
|
||||
|
||||
-----------------------------------
|
||||
-----------------------------------
|
||||
|
||||
Maintainers List (try to look for most precise areas first)
|
||||
|
||||
@ -198,10 +198,25 @@ L: linux-sound@vger.kernel.org
|
||||
W: http://www.stud.uni-karlsruhe.de/~uh1b/
|
||||
S: Maintained
|
||||
|
||||
IPS SCSI RAID DRIVER
|
||||
P: Adaptec OEM Raid Solutions
|
||||
M: aacraid@adaptec.com
|
||||
L: linux-scsi@vger.kernel.org
|
||||
W: http://www.adaptec.com/
|
||||
S: Maintained
|
||||
|
||||
DPT_I2O SCSI RAID DRIVER
|
||||
P: Adaptec OEM Raid Solutions
|
||||
M: aacraid@adaptec.com
|
||||
L: linux-scsi@vger.kernel.org
|
||||
W: http://www.adaptec.com/
|
||||
S: Maintained
|
||||
|
||||
AACRAID SCSI RAID DRIVER
|
||||
P: Adaptec OEM Raid Solutions
|
||||
M: aacraid@adaptec.com
|
||||
L: linux-scsi@vger.kernel.org
|
||||
W: http://linux.dell.com/storage.shtml
|
||||
W: http://www.adaptec.com/
|
||||
S: Supported
|
||||
|
||||
ACPI
|
||||
@ -369,7 +384,7 @@ S: Supported
|
||||
|
||||
APPLETALK NETWORK LAYER
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@conectiva.com.br
|
||||
M: acme@ghostprotocols.net
|
||||
S: Maintained
|
||||
|
||||
ARC FRAMEBUFFER DRIVER
|
||||
@ -641,6 +656,7 @@ S: Supported
|
||||
ATMEL WIRELESS DRIVER
|
||||
P: Simon Kelley
|
||||
M: simon@thekelleys.org.uk
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://www.thekelleys.org.uk/atmel
|
||||
W: http://atmelwlandriver.sourceforge.net/
|
||||
S: Maintained
|
||||
@ -696,6 +712,7 @@ P: Larry Finger
|
||||
M: Larry.Finger@lwfinger.net
|
||||
P: Stefano Brivio
|
||||
M: st3@riseup.net
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://bcm43xx.berlios.de/
|
||||
S: Maintained
|
||||
|
||||
@ -856,6 +873,12 @@ W: http://linuxtv.org
|
||||
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
|
||||
S: Maintained
|
||||
|
||||
CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
|
||||
P: Jonathan Corbet
|
||||
M: corbet@lwn.net
|
||||
L: video4linux-list@redhat.com
|
||||
S: Maintained
|
||||
|
||||
CALGARY x86-64 IOMMU
|
||||
P: Muli Ben-Yehuda
|
||||
M: muli@il.ibm.com
|
||||
@ -877,6 +900,12 @@ M: maxextreme@gmail.com
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
CFG80211 and NL80211
|
||||
P: Johannes Berg
|
||||
M: johannes@sipsolutions.net
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
COMMON INTERNET FILE SYSTEM (CIFS)
|
||||
P: Steve French
|
||||
M: sfrench@samba.org
|
||||
@ -884,7 +913,7 @@ L: linux-cifs-client@lists.samba.org
|
||||
L: samba-technical@lists.samba.org
|
||||
W: http://us1.samba.org/samba/Linux_CIFS_client.html
|
||||
T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
|
||||
S: Supported
|
||||
S: Supported
|
||||
|
||||
CONFIGFS
|
||||
P: Joel Becker
|
||||
@ -952,6 +981,11 @@ M: mhw@wittsend.com
|
||||
W: http://www.wittsend.com/computone.html
|
||||
S: Maintained
|
||||
|
||||
CONEXANT ACCESSRUNNER USB DRIVER
|
||||
P: Simon Arlott
|
||||
M: cxacru@fire.lp0.eu
|
||||
S: Maintained
|
||||
|
||||
COSA/SRP SYNC SERIAL DRIVER
|
||||
P: Jan "Yenya" Kasprzak
|
||||
M: kas@fi.muni.cz
|
||||
@ -1019,9 +1053,8 @@ S: Maintained
|
||||
|
||||
CYCLADES 2X SYNC CARD DRIVER
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@conectiva.com.br
|
||||
W: http://advogato.org/person/acme
|
||||
L: cycsyn-devel@bazar.conectiva.com.br
|
||||
M: acme@ghostprotocols.net
|
||||
W: http://oops.ghostprotocols.net:81/blog
|
||||
S: Maintained
|
||||
|
||||
CYCLADES ASYNC MUX DRIVER
|
||||
@ -1062,7 +1095,7 @@ S: Maintained
|
||||
|
||||
DCCP PROTOCOL
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@mandriva.com
|
||||
M: acme@ghostprotocols.net
|
||||
L: dccp@vger.kernel.org
|
||||
W: http://linux-net.osdl.org/index.php/DCCP
|
||||
S: Maintained
|
||||
@ -1303,7 +1336,7 @@ S: Maintained
|
||||
ETHERNET BRIDGE
|
||||
P: Stephen Hemminger
|
||||
M: shemminger@linux-foundation.org
|
||||
L: bridge@lists.osdl.org
|
||||
L: bridge@lists.linux-foundation.org
|
||||
W: http://bridge.sourceforge.net/
|
||||
S: Maintained
|
||||
|
||||
@ -1340,6 +1373,11 @@ M: kevin.curtis@farsite.co.uk
|
||||
W: http://www.farsite.co.uk/
|
||||
S: Supported
|
||||
|
||||
FAULT INJECTION SUPPORT
|
||||
P: Akinobu Mita
|
||||
M: akinobu.mita@gmail.com
|
||||
S: Supported
|
||||
|
||||
FRAMEBUFFER LAYER
|
||||
P: Antonino Daplas
|
||||
M: adaplas@gmail.com
|
||||
@ -1356,6 +1394,13 @@ L: linuxppc-embedded@ozlabs.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
FREESCALE HIGHSPEED USB DEVICE DRIVER
|
||||
P: Li Yang
|
||||
M: leoli@freescale.com
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: linuxppc-embedded@ozlabs.org
|
||||
S: Maintained
|
||||
|
||||
FILE LOCKING (flock() and fcntl()/lockf())
|
||||
P: Matthew Wilcox
|
||||
M: matthew@wil.cx
|
||||
@ -1389,7 +1434,7 @@ M: hch@infradead.org
|
||||
W: ftp://ftp.openlinux.org/pub/people/hch/vxfs
|
||||
S: Maintained
|
||||
|
||||
FUJITSU FR-V PORT
|
||||
FUJITSU FR-V (FRV) PORT
|
||||
P: David Howells
|
||||
M: dhowells@redhat.com
|
||||
S: Maintained
|
||||
@ -1522,23 +1567,24 @@ P: Chirag Kantharia
|
||||
M: chirag.kantharia@hp.com
|
||||
L: iss_storagedev@hp.com
|
||||
S: Maintained
|
||||
|
||||
|
||||
HEWLETT-PACKARD SMART2 RAID DRIVER
|
||||
P: Chirag Kantharia
|
||||
M: chirag.kantharia@hp.com
|
||||
L: iss_storagedev@hp.com
|
||||
S: Maintained
|
||||
|
||||
|
||||
HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss)
|
||||
P: Mike Miller
|
||||
M: mike.miller@hp.com
|
||||
L: iss_storagedev@hp.com
|
||||
S: Supported
|
||||
|
||||
|
||||
HOST AP DRIVER
|
||||
P: Jouni Malinen
|
||||
M: jkmaline@cc.hut.fi
|
||||
L: hostap@shmoo.com
|
||||
M: j@w1.fi
|
||||
L: hostap@shmoo.com (subscribers-only)
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://hostap.epitest.fi/
|
||||
S: Maintained
|
||||
|
||||
@ -1585,12 +1631,6 @@ L: i2c@lm-sensors.org
|
||||
T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
|
||||
S: Maintained
|
||||
|
||||
I2O
|
||||
P: Markus Lidel
|
||||
M: markus.lidel@shadowconnect.com
|
||||
W: http://i2o.shadowconnect.com/
|
||||
S: Maintained
|
||||
|
||||
i386 BOOT CODE
|
||||
P: Riley H. Williams
|
||||
M: Riley@Williams.Name
|
||||
@ -1618,15 +1658,6 @@ W: http://www.ia64-linux.org/
|
||||
T: git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
|
||||
S: Maintained
|
||||
|
||||
IBM ACPI EXTRAS DRIVER
|
||||
P: Henrique de Moraes Holschuh
|
||||
M: ibm-acpi@hmh.eng.br
|
||||
L: ibm-acpi-devel@lists.sourceforge.net
|
||||
W: http://ibm-acpi.sourceforge.net
|
||||
W: http://thinkwiki.org/wiki/Ibm-acpi
|
||||
T: git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
|
||||
S: Maintained
|
||||
|
||||
SN-IA64 (Itanium) SUB-PLATFORM
|
||||
P: Jes Sorensen
|
||||
M: jes@sgi.com
|
||||
@ -1651,7 +1682,7 @@ P: Jack Hammer
|
||||
P: Dave Jeffery
|
||||
M: ipslinux@adaptec.com
|
||||
W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html
|
||||
S: Supported
|
||||
S: Supported
|
||||
|
||||
IDE SUBSYSTEM
|
||||
P: Bartlomiej Zolnierkiewicz
|
||||
@ -1681,7 +1712,7 @@ S: Maintained
|
||||
|
||||
IEEE 1394 SUBSYSTEM
|
||||
P: Ben Collins
|
||||
M: bcollins@debian.org
|
||||
M: ben.collins@ubuntu.com
|
||||
P: Stefan Richter
|
||||
M: stefanr@s5r6.in-berlin.de
|
||||
L: linux1394-devel@lists.sourceforge.net
|
||||
@ -1689,25 +1720,11 @@ W: http://www.linux1394.org/
|
||||
T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
|
||||
S: Maintained
|
||||
|
||||
IEEE 1394 IPV4 DRIVER (eth1394)
|
||||
P: Stefan Richter
|
||||
M: stefanr@s5r6.in-berlin.de
|
||||
L: linux1394-devel@lists.sourceforge.net
|
||||
S: Odd Fixes
|
||||
|
||||
IEEE 1394 PCILYNX DRIVER
|
||||
P: Jody McIntyre
|
||||
M: scjody@modernduck.com
|
||||
P: Stefan Richter
|
||||
M: stefanr@s5r6.in-berlin.de
|
||||
L: linux1394-devel@lists.sourceforge.net
|
||||
S: Odd Fixes
|
||||
|
||||
IEEE 1394 RAW I/O DRIVER
|
||||
P: Ben Collins
|
||||
M: bcollins@debian.org
|
||||
IEEE 1394 RAW I/O DRIVER (raw1394)
|
||||
P: Dan Dennedy
|
||||
M: dan@dennedy.org
|
||||
P: Stefan Richter
|
||||
M: stefanr@s5r6.in-berlin.de
|
||||
L: linux1394-devel@lists.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
@ -1794,6 +1811,7 @@ P: Jeff Kirsher
|
||||
M: jeffrey.t.kirsher@intel.com
|
||||
P: Auke Kok
|
||||
M: auke-jan.h.kok@intel.com
|
||||
L: e1000-devel@lists.sourceforge.net
|
||||
W: http://sourceforge.net/projects/e1000/
|
||||
S: Supported
|
||||
|
||||
@ -1808,6 +1826,7 @@ P: Jeff Kirsher
|
||||
M: jeffrey.t.kirsher@intel.com
|
||||
P: Auke Kok
|
||||
M: auke-jan.h.kok@intel.com
|
||||
L: e1000-devel@lists.sourceforge.net
|
||||
W: http://sourceforge.net/projects/e1000/
|
||||
S: Supported
|
||||
|
||||
@ -1822,6 +1841,7 @@ P: Jesse Brandeburg
|
||||
M: jesse.brandeburg@intel.com
|
||||
P: Auke Kok
|
||||
M: auke-jan.h.kok@intel.com
|
||||
L: e1000-devel@lists.sourceforge.net
|
||||
W: http://sourceforge.net/projects/e1000/
|
||||
S: Supported
|
||||
|
||||
@ -1830,6 +1850,7 @@ P: Yi Zhu
|
||||
M: yi.zhu@intel.com
|
||||
P: James Ketrenos
|
||||
M: jketreno@linux.intel.com
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ipw2100-devel@lists.sourceforge.net
|
||||
L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
|
||||
W: http://ipw2100.sourceforge.net
|
||||
@ -1840,6 +1861,7 @@ P: Yi Zhu
|
||||
M: yi.zhu@intel.com
|
||||
P: James Ketrenos
|
||||
M: jketreno@linux.intel.com
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ipw2100-devel@lists.sourceforge.net
|
||||
L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
|
||||
W: http://ipw2200.sourceforge.net
|
||||
@ -1871,7 +1893,7 @@ S: Supported
|
||||
|
||||
IPX NETWORK LAYER
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@conectiva.com.br
|
||||
M: acme@ghostprotocols.net
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
@ -1942,7 +1964,7 @@ P: Vivek Goyal
|
||||
M: vgoyal@in.ibm.com
|
||||
P: Haren Myneni
|
||||
M: hbabu@us.ibm.com
|
||||
L: fastboot@lists.osdl.org
|
||||
L: fastboot@lists.linux-foundation.org
|
||||
L: linux-kernel@vger.kernel.org
|
||||
W: http://lse.sourceforge.net/kdump/
|
||||
S: Maintained
|
||||
@ -1965,11 +1987,11 @@ M: kai@germaschewski.name
|
||||
P: Sam Ravnborg
|
||||
M: sam@ravnborg.org
|
||||
T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
|
||||
S: Maintained
|
||||
S: Maintained
|
||||
|
||||
KERNEL JANITORS
|
||||
P: Several
|
||||
L: kernel-janitors@lists.osdl.org
|
||||
L: kernel-janitors@lists.linux-foundation.org
|
||||
W: http://www.kerneljanitors.org/
|
||||
S: Maintained
|
||||
|
||||
@ -1992,7 +2014,7 @@ P: Eric Biederman
|
||||
M: ebiederm@xmission.com
|
||||
W: http://www.xmission.com/~ebiederm/files/kexec/
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: fastboot@lists.osdl.org
|
||||
L: fastboot@lists.linux-foundation.org
|
||||
S: Maintained
|
||||
|
||||
KPROBES
|
||||
@ -2108,7 +2130,7 @@ S: Supported
|
||||
|
||||
LLC (802.2)
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@conectiva.com.br
|
||||
M: acme@ghostprotocols.net
|
||||
S: Maintained
|
||||
|
||||
LINUX FOR 64BIT POWERPC
|
||||
@ -2145,7 +2167,7 @@ S: Maintained
|
||||
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
|
||||
P: Richard Russon (FlatCap)
|
||||
M: ldm@flatcap.org
|
||||
L: ldm-devel@lists.sourceforge.net
|
||||
L: ldm-devel@lists.sourceforge.net
|
||||
W: http://ldm.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
@ -2236,6 +2258,14 @@ L: linux-mtd@lists.infradead.org
|
||||
T: git git://git.infradead.org/mtd-2.6.git
|
||||
S: Maintained
|
||||
|
||||
UNSORTED BLOCK IMAGES (UBI)
|
||||
P: Artem Bityutskiy
|
||||
M: dedekind@infradead.org
|
||||
W: http://www.linux-mtd.infradead.org/
|
||||
L: linux-mtd@lists.infradead.org
|
||||
T: git git://git.infradead.org/ubi-2.6.git
|
||||
S: Maintained
|
||||
|
||||
MICROTEK X6 SCANNER
|
||||
P: Oliver Neukum
|
||||
M: oliver@neukum.name
|
||||
@ -2330,7 +2360,7 @@ S: Maintained
|
||||
NETEM NETWORK EMULATOR
|
||||
P: Stephen Hemminger
|
||||
M: shemminger@linux-foundation.org
|
||||
L: netem@lists.osdl.org
|
||||
L: netem@lists.linux-foundation.org
|
||||
S: Maintained
|
||||
|
||||
NETFILTER/IPTABLES/IPCHAINS
|
||||
@ -2473,6 +2503,19 @@ M: adaplas@gmail.com
|
||||
L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
NETERION (S2IO) Xframe 10GbE DRIVER
|
||||
P: Ramkrishna Vepa
|
||||
M: ram.vepa@neterion.com
|
||||
P: Rastapur Santosh
|
||||
M: santosh.rastapur@neterion.com
|
||||
P: Sivakumar Subramani
|
||||
M: sivakumar.subramani@neterion.com
|
||||
P: Sreenivasa Honnur
|
||||
M: sreenivasa.honnur@neterion.com
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/TitleIndex?anonymous
|
||||
S: Supported
|
||||
|
||||
OPENCORES I2C BUS DRIVER
|
||||
P: Peter Korsgaard
|
||||
M: jacmet@sunsite.dk
|
||||
@ -2486,13 +2529,13 @@ P: Kurt Hackel
|
||||
M: kurt.hackel@oracle.com
|
||||
L: ocfs2-devel@oss.oracle.com
|
||||
W: http://oss.oracle.com/projects/ocfs2/
|
||||
S: Supported
|
||||
S: Supported
|
||||
|
||||
OLYMPIC NETWORK DRIVER
|
||||
P: Peter De Shrijver
|
||||
M: p2@ace.ulyssis.student.kuleuven.ac.be
|
||||
P: Mike Phillips
|
||||
M: mikep@linuxtr.net
|
||||
M: mikep@linuxtr.net
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-tr@linuxtr.net
|
||||
W: http://www.linuxtr.net
|
||||
@ -2508,6 +2551,12 @@ P: Harald Welte
|
||||
M: laforge@gnumonks.org
|
||||
S: Maintained
|
||||
|
||||
OMNIVISION OV7670 SENSOR DRIVER
|
||||
P: Jonathan Corbet
|
||||
M: corbet@lwn.net
|
||||
L: video4linux-list@redhat.com
|
||||
S: Maintained
|
||||
|
||||
ONSTREAM SCSI TAPE DRIVER
|
||||
P: Willem Riede
|
||||
M: osst@riede.org
|
||||
@ -2532,6 +2581,7 @@ P: Pavel Roskin
|
||||
M: proski@gnu.org
|
||||
P: David Gibson
|
||||
M: hermes@gibson.dropbear.id.au
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: orinoco-users@lists.sourceforge.net
|
||||
L: orinoco-devel@lists.sourceforge.net
|
||||
W: http://www.nongnu.org/orinoco/
|
||||
@ -2711,7 +2761,7 @@ S: Supported
|
||||
PRISM54 WIRELESS DRIVER
|
||||
P: Prism54 Development Team
|
||||
M: developers@islsm.org
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://prism54.org
|
||||
S: Maintained
|
||||
|
||||
@ -2782,7 +2832,7 @@ S: Maintained
|
||||
RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
|
||||
P: Corey Thomas
|
||||
M: corey@world.std.com
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
RANDOM NUMBER DRIVER
|
||||
@ -2928,9 +2978,12 @@ L: linux-scsi@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
SCTP PROTOCOL
|
||||
P: Vlad Yasevich
|
||||
M: vladislav.yasevich@hp.com
|
||||
P: Sridhar Samudrala
|
||||
M: sri@us.ibm.com
|
||||
L: lksctp-developers@lists.sourceforge.net
|
||||
W: http://lksctp.sourceforge.net
|
||||
S: Supported
|
||||
|
||||
SCx200 CPU SUPPORT
|
||||
@ -2958,8 +3011,10 @@ P: Stephen Smalley
|
||||
M: sds@tycho.nsa.gov
|
||||
P: James Morris
|
||||
M: jmorris@namei.org
|
||||
P: Eric Paris
|
||||
M: eparis@parisplace.org
|
||||
L: linux-kernel@vger.kernel.org (kernel issues)
|
||||
L: selinux@tycho.nsa.gov (general discussion)
|
||||
L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
|
||||
W: http://www.nsa.gov/selinux
|
||||
S: Supported
|
||||
|
||||
@ -3021,7 +3076,7 @@ SIS FRAMEBUFFER DRIVER
|
||||
P: Thomas Winischhofer
|
||||
M: thomas@winischhofer.net
|
||||
W: http://www.winischhofer.net/linuxsisvga.shtml
|
||||
S: Maintained
|
||||
S: Maintained
|
||||
|
||||
SIS USB2VGA DRIVER
|
||||
P: Thomas Winischhofer
|
||||
@ -3042,7 +3097,7 @@ M: josejx@gentoo.org
|
||||
P: Daniel Drake
|
||||
M: dsd@gentoo.org
|
||||
W: http://softmac.sipsolutions.net/
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
SOFTWARE RAID (Multiple Disks) SUPPORT
|
||||
@ -3056,7 +3111,7 @@ S: Supported
|
||||
SOFTWARE SUSPEND:
|
||||
P: Pavel Machek
|
||||
M: pavel@suse.cz
|
||||
L: linux-pm@lists.osdl.org
|
||||
L: linux-pm@lists.linux-foundation.org
|
||||
S: Maintained
|
||||
|
||||
SONIC NETWORK DRIVER
|
||||
@ -3118,6 +3173,15 @@ P: Chris Zankel
|
||||
M: chris@zankel.net
|
||||
S: Maintained
|
||||
|
||||
THINKPAD ACPI EXTRAS DRIVER
|
||||
P: Henrique de Moraes Holschuh
|
||||
M: ibm-acpi@hmh.eng.br
|
||||
L: ibm-acpi-devel@lists.sourceforge.net
|
||||
W: http://ibm-acpi.sourceforge.net
|
||||
W: http://thinkwiki.org/wiki/Ibm-acpi
|
||||
T: git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
|
||||
S: Maintained
|
||||
|
||||
UltraSPARC (sparc64):
|
||||
P: David S. Miller
|
||||
M: davem@davemloft.net
|
||||
@ -3570,7 +3634,7 @@ L: linux-usb-devel@lists.sourceforge.net
|
||||
W: http://www.connecttech.com
|
||||
S: Supported
|
||||
|
||||
USB SN9C10x DRIVER
|
||||
USB SN9C1xx DRIVER
|
||||
P: Luca Risolia
|
||||
M: luca.risolia@studio.unibo.it
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
@ -3625,6 +3689,14 @@ L: linux-usb-devel@lists.sourceforge.net
|
||||
W: http://linux-lc100020.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
USB ZR364XX DRIVER
|
||||
P: Antoine Jacquet
|
||||
M: royale@zerezo.com
|
||||
L: linux-usb-devel@lists.sourceforge.net
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://royale.zerezo.com/zr364xx/
|
||||
S: Maintained
|
||||
|
||||
USER-MODE LINUX
|
||||
P: Jeff Dike
|
||||
M: jdike@karaya.com
|
||||
@ -3632,7 +3704,7 @@ L: user-mode-linux-devel@lists.sourceforge.net
|
||||
L: user-mode-linux-user@lists.sourceforge.net
|
||||
W: http://user-mode-linux.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
|
||||
FAT/VFAT/MSDOS FILESYSTEM:
|
||||
P: OGAWA Hirofumi
|
||||
M: hirofumi@mail.parknet.co.jp
|
||||
@ -3747,6 +3819,7 @@ S: Maintained
|
||||
WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS
|
||||
P: Jean Tourrilhes
|
||||
M: jt@hpl.hp.com
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
|
||||
S: Maintained
|
||||
|
||||
@ -3763,8 +3836,9 @@ S: Maintained
|
||||
|
||||
WL3501 WIRELESS PCMCIA CARD DRIVER
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@conectiva.com.br
|
||||
W: http://advogato.org/person/acme
|
||||
M: acme@ghostprotocols.net
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://oops.ghostprotocols.net:81/blog
|
||||
S: Maintained
|
||||
|
||||
X.25 NETWORK LAYER
|
||||
@ -3827,6 +3901,7 @@ M: dsd@gentoo.org
|
||||
P: Ulrich Kunitz
|
||||
M: kune@deine-taler.de
|
||||
W: http://zd1211.ath.cx/wiki/DriverRewrite
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: zd1211-devs@lists.sourceforge.net (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 21
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION =
|
||||
NAME = Nocturnal Monster Puppy
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -40,8 +40,6 @@
|
||||
# define DBG_CFG(args)
|
||||
#endif
|
||||
|
||||
#define MCPCIA_MAX_HOSES 4
|
||||
|
||||
/*
|
||||
* Given a bus, device, and function number, compute resulting
|
||||
* configuration space address and setup the MCPCIA_HAXR2 register
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <asm/smp.h>
|
||||
#include <asm/err_common.h>
|
||||
#include <asm/err_ev6.h>
|
||||
#include <asm/irq_regs.h>
|
||||
|
||||
#include "err_impl.h"
|
||||
#include "proto.h"
|
||||
|
@ -285,12 +285,12 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
|
||||
reloc_overflow:
|
||||
if (ELF64_ST_TYPE (sym->st_info) == STT_SECTION)
|
||||
printk(KERN_ERR
|
||||
"module %s: Relocation overflow vs section %d\n",
|
||||
me->name, sym->st_shndx);
|
||||
"module %s: Relocation (type %lu) overflow vs section %d\n",
|
||||
me->name, r_type, sym->st_shndx);
|
||||
else
|
||||
printk(KERN_ERR
|
||||
"module %s: Relocation overflow vs %s\n",
|
||||
me->name, strtab + sym->st_name);
|
||||
"module %s: Relocation (type %lu) overflow vs %s\n",
|
||||
me->name, r_type, strtab + sym->st_name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,12 @@ nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||
/* Preserve the IRQ set up by the console. */
|
||||
|
||||
u8 irq;
|
||||
/* UP1500: AGP INTA is actually routed to IRQ 5, not IRQ 10 as
|
||||
console reports. Check the device id of AGP bridge to distinguish
|
||||
UP1500 from UP1000/1100. Note: 'pin' is 2 due to bridge swizzle. */
|
||||
if (slot == 1 && pin == 2 &&
|
||||
dev->bus->self && dev->bus->self->device == 0x700f)
|
||||
return 5;
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
|
||||
return irq;
|
||||
}
|
||||
|
@ -66,6 +66,13 @@ noritake_startup_irq(unsigned int irq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
noritake_end_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
noritake_enable_irq(irq);
|
||||
}
|
||||
|
||||
static struct hw_interrupt_type noritake_irq_type = {
|
||||
.typename = "NORITAKE",
|
||||
.startup = noritake_startup_irq,
|
||||
@ -73,7 +80,7 @@ static struct hw_interrupt_type noritake_irq_type = {
|
||||
.enable = noritake_enable_irq,
|
||||
.disable = noritake_disable_irq,
|
||||
.ack = noritake_disable_irq,
|
||||
.end = noritake_enable_irq,
|
||||
.end = noritake_end_irq,
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -52,6 +52,9 @@ rawhide_update_irq_hw(int hose, int mask)
|
||||
*(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose));
|
||||
}
|
||||
|
||||
#define hose_exists(h) \
|
||||
(((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0))
|
||||
|
||||
static inline void
|
||||
rawhide_enable_irq(unsigned int irq)
|
||||
{
|
||||
@ -59,6 +62,9 @@ rawhide_enable_irq(unsigned int irq)
|
||||
|
||||
irq -= 16;
|
||||
hose = irq / 24;
|
||||
if (!hose_exists(hose)) /* if hose non-existent, exit */
|
||||
return;
|
||||
|
||||
irq -= hose * 24;
|
||||
mask = 1 << irq;
|
||||
|
||||
@ -76,6 +82,9 @@ rawhide_disable_irq(unsigned int irq)
|
||||
|
||||
irq -= 16;
|
||||
hose = irq / 24;
|
||||
if (!hose_exists(hose)) /* if hose non-existent, exit */
|
||||
return;
|
||||
|
||||
irq -= hose * 24;
|
||||
mask = ~(1 << irq) | hose_irq_masks[hose];
|
||||
|
||||
@ -93,6 +102,9 @@ rawhide_mask_and_ack_irq(unsigned int irq)
|
||||
|
||||
irq -= 16;
|
||||
hose = irq / 24;
|
||||
if (!hose_exists(hose)) /* if hose non-existent, exit */
|
||||
return;
|
||||
|
||||
irq -= hose * 24;
|
||||
mask1 = 1 << irq;
|
||||
mask = ~mask1 | hose_irq_masks[hose];
|
||||
@ -169,6 +181,9 @@ rawhide_init_irq(void)
|
||||
|
||||
mcpcia_init_hoses();
|
||||
|
||||
/* Clear them all; only hoses that exist will be non-zero. */
|
||||
for (i = 0; i < MCPCIA_MAX_HOSES; i++) cached_irq_masks[i] = 0;
|
||||
|
||||
for (hose = hose_head; hose; hose = hose->next) {
|
||||
unsigned int h = hose->index;
|
||||
unsigned int mask = hose_irq_masks[h];
|
||||
|
@ -84,12 +84,16 @@ alphabook1_init_arch(void)
|
||||
static void __init
|
||||
sio_pci_route(void)
|
||||
{
|
||||
#if defined(ALPHA_RESTORE_SRM_SETUP)
|
||||
/* First, read and save the original setting. */
|
||||
unsigned int orig_route_tab;
|
||||
|
||||
/* First, ALWAYS read and print the original setting. */
|
||||
pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
|
||||
&saved_config.orig_route_tab);
|
||||
&orig_route_tab);
|
||||
printk("%s: PIRQ original 0x%x new 0x%x\n", __FUNCTION__,
|
||||
saved_config.orig_route_tab, alpha_mv.sys.sio.route_tab);
|
||||
orig_route_tab, alpha_mv.sys.sio.route_tab);
|
||||
|
||||
#if defined(ALPHA_RESTORE_SRM_SETUP)
|
||||
saved_config.orig_route_tab = orig_route_tab;
|
||||
#endif
|
||||
|
||||
/* Now override with desired setting. */
|
||||
@ -334,7 +338,7 @@ struct alpha_machine_vector avanti_mv __initmv = {
|
||||
.pci_swizzle = common_swizzle,
|
||||
|
||||
.sys = { .sio = {
|
||||
.route_tab = 0x0b0a0e0f,
|
||||
.route_tab = 0x0b0a050f, /* leave 14 for IDE, 9 for SND */
|
||||
}}
|
||||
};
|
||||
ALIAS_MV(avanti)
|
||||
|
@ -132,7 +132,7 @@ sx164_init_arch(void)
|
||||
|
||||
if (amask(AMASK_MAX) != 0
|
||||
&& alpha_using_srm
|
||||
&& (cpu->pal_revision & 0xffff) == 0x117) {
|
||||
&& (cpu->pal_revision & 0xffff) <= 0x117) {
|
||||
__asm__ __volatile__(
|
||||
"lda $16,8($31)\n"
|
||||
"call_pal 9\n" /* Allow PALRES insns in kernel mode */
|
||||
|
@ -257,8 +257,7 @@ titan_dispatch_irqs(u64 mask)
|
||||
*/
|
||||
while (mask) {
|
||||
/* convert to SRM vector... priority is <63> -> <0> */
|
||||
__asm__("ctlz %1, %0" : "=r"(vector) : "r"(mask));
|
||||
vector = 63 - vector;
|
||||
vector = 63 - __kernel_ctlz(mask);
|
||||
mask &= ~(1UL << vector); /* clear it out */
|
||||
vector = 0x900 + (vector << 4); /* convert to SRM vector */
|
||||
|
||||
|
@ -36,7 +36,6 @@ lib-y = __divqu.o __remqu.o __divlu.o __remlu.o \
|
||||
$(ev6-y)csum_ipv6_magic.o \
|
||||
$(ev6-y)clear_page.o \
|
||||
$(ev6-y)copy_page.o \
|
||||
strcasecmp.o \
|
||||
fpreg.o \
|
||||
callback_srm.o srm_puts.o srm_printk.o
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* linux/arch/alpha/lib/strcasecmp.c
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
|
||||
|
||||
/* We handle nothing here except the C locale. Since this is used in
|
||||
only one place, on strings known to contain only 7 bit ASCII, this
|
||||
is ok. */
|
||||
|
||||
int strcasecmp(const char *a, const char *b)
|
||||
{
|
||||
int ca, cb;
|
||||
|
||||
do {
|
||||
ca = *a++ & 0xff;
|
||||
cb = *b++ & 0xff;
|
||||
if (ca >= 'A' && ca <= 'Z')
|
||||
ca += 'a' - 'A';
|
||||
if (cb >= 'A' && cb <= 'Z')
|
||||
cb += 'a' - 'A';
|
||||
} while (ca == cb && ca != '\0');
|
||||
|
||||
return ca - cb;
|
||||
}
|
@ -766,10 +766,10 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
|
||||
}
|
||||
|
||||
static struct pm_ops sharpsl_pm_ops = {
|
||||
.pm_disk_mode = PM_DISK_FIRMWARE,
|
||||
.prepare = pxa_pm_prepare,
|
||||
.enter = corgi_pxa_pm_enter,
|
||||
.finish = pxa_pm_finish,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init sharpsl_pm_probe(struct platform_device *pdev)
|
||||
|
@ -1,10 +1,11 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.21-rc1
|
||||
# Wed Feb 21 16:48:01 2007
|
||||
# Linux kernel version: 2.6.21-rc6
|
||||
# Mon Apr 9 10:12:58 2007
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
CONFIG_GENERIC_GPIO=y
|
||||
# CONFIG_GENERIC_TIME is not set
|
||||
CONFIG_MMU=y
|
||||
CONFIG_NO_IOPORT=y
|
||||
@ -45,6 +46,7 @@ CONFIG_SYSVIPC_SYSCTL=y
|
||||
# CONFIG_IKCONFIG is not set
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
# CONFIG_RELAY is not set
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_SYSCTL=y
|
||||
@ -531,7 +533,6 @@ CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||
CONFIG_BLK_DEV_RAM_SIZE=4096
|
||||
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
CONFIG_ATA_OVER_ETH=m
|
||||
|
||||
@ -560,7 +561,6 @@ CONFIG_IDE_GENERIC=y
|
||||
CONFIG_BLK_DEV_IDE_BAST=y
|
||||
# CONFIG_IDE_CHIPSETS is not set
|
||||
# CONFIG_BLK_DEV_IDEDMA is not set
|
||||
# CONFIG_IDEDMA_AUTO is not set
|
||||
# CONFIG_BLK_DEV_HD is not set
|
||||
|
||||
#
|
||||
@ -941,6 +941,7 @@ CONFIG_LEDS_CLASS=m
|
||||
# LED drivers
|
||||
#
|
||||
CONFIG_LEDS_S3C24XX=m
|
||||
CONFIG_LEDS_H1940=m
|
||||
|
||||
#
|
||||
# LED Triggers
|
||||
@ -1125,6 +1126,7 @@ CONFIG_USB_MON=y
|
||||
# CONFIG_USB_APPLEDISPLAY is not set
|
||||
# CONFIG_USB_LD is not set
|
||||
# CONFIG_USB_TRANCEVIBRATOR is not set
|
||||
# CONFIG_USB_IOWARRIOR is not set
|
||||
# CONFIG_USB_TEST is not set
|
||||
|
||||
#
|
||||
@ -1169,7 +1171,6 @@ CONFIG_RTC_INTF_DEV=y
|
||||
# CONFIG_RTC_DRV_DS1672 is not set
|
||||
# CONFIG_RTC_DRV_DS1742 is not set
|
||||
# CONFIG_RTC_DRV_PCF8563 is not set
|
||||
# CONFIG_RTC_DRV_PCF8583 is not set
|
||||
# CONFIG_RTC_DRV_RS5C348 is not set
|
||||
# CONFIG_RTC_DRV_RS5C372 is not set
|
||||
CONFIG_RTC_DRV_S3C=y
|
||||
|
@ -228,6 +228,7 @@ int dma_channel_active(dmach_t channel)
|
||||
{
|
||||
return dma_chan[channel].active;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_channel_active);
|
||||
|
||||
void set_dma_page(dmach_t channel, char pagenr)
|
||||
{
|
||||
|
@ -320,16 +320,16 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
|
||||
at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
|
||||
| AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
|
||||
|
||||
at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5)
|
||||
| AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5));
|
||||
at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
|
||||
| AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
|
||||
|
||||
at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7));
|
||||
at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
|
||||
|
||||
if (data->bus_width_16)
|
||||
mode = AT91_SMC_DBW_16;
|
||||
else
|
||||
mode = AT91_SMC_DBW_8;
|
||||
at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1));
|
||||
at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
|
||||
|
||||
/* enable pin */
|
||||
if (data->enable_pin)
|
||||
|
@ -201,7 +201,6 @@ error:
|
||||
|
||||
|
||||
static struct pm_ops at91_pm_ops ={
|
||||
.pm_disk_mode = 0,
|
||||
.valid = at91_pm_valid_state,
|
||||
.prepare = at91_pm_prepare,
|
||||
.enter = at91_pm_enter,
|
||||
|
@ -698,10 +698,10 @@ static struct irqaction omap_wakeup_irq = {
|
||||
|
||||
|
||||
static struct pm_ops omap_pm_ops ={
|
||||
.pm_disk_mode = 0,
|
||||
.prepare = omap_pm_prepare,
|
||||
.enter = omap_pm_enter,
|
||||
.finish = omap_pm_finish,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init omap_pm_init(void)
|
||||
|
@ -370,10 +370,10 @@ static int omap2_pm_finish(suspend_state_t state)
|
||||
}
|
||||
|
||||
static struct pm_ops omap_pm_ops = {
|
||||
.pm_disk_mode = 0,
|
||||
.prepare = omap2_pm_prepare,
|
||||
.enter = omap2_pm_enter,
|
||||
.finish = omap2_pm_finish,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
|
||||
int __init omap2_pm_init(void)
|
||||
|
@ -107,50 +107,19 @@ static int pnx4008_pm_enter(suspend_state_t state)
|
||||
case PM_SUSPEND_MEM:
|
||||
pnx4008_suspend();
|
||||
break;
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after processes are frozen, but before we shut down devices.
|
||||
*/
|
||||
static int pnx4008_pm_prepare(suspend_state_t state)
|
||||
static int pnx4008_pm_valid(suspend_state_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return (state == PM_SUSPEND_STANDBY) ||
|
||||
(state == PM_SUSPEND_MEM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after devices are re-setup, but before processes are thawed.
|
||||
*/
|
||||
static int pnx4008_pm_finish(suspend_state_t state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
|
||||
*/
|
||||
static struct pm_ops pnx4008_pm_ops = {
|
||||
.prepare = pnx4008_pm_prepare,
|
||||
.enter = pnx4008_pm_enter,
|
||||
.finish = pnx4008_pm_finish,
|
||||
.valid = pnx4008_pm_valid,
|
||||
};
|
||||
|
||||
static int __init pnx4008_pm_init(void)
|
||||
|
@ -223,14 +223,11 @@ int pxa_pm_finish(suspend_state_t state)
|
||||
|
||||
EXPORT_SYMBOL_GPL(pxa_pm_finish);
|
||||
|
||||
/*
|
||||
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
|
||||
*/
|
||||
static struct pm_ops pxa_pm_ops = {
|
||||
.pm_disk_mode = PM_DISK_FIRMWARE,
|
||||
.prepare = pxa_pm_prepare,
|
||||
.enter = pxa_pm_enter,
|
||||
.finish = pxa_pm_finish,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init pxa_pm_init(void)
|
||||
|
@ -59,9 +59,6 @@ static int sa11x0_pm_enter(suspend_state_t state)
|
||||
unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
|
||||
struct timespec delta, rtc;
|
||||
|
||||
if (state != PM_SUSPEND_MEM)
|
||||
return -EINVAL;
|
||||
|
||||
/* preserve current time */
|
||||
rtc.tv_sec = RCNR;
|
||||
rtc.tv_nsec = 0;
|
||||
@ -134,12 +131,9 @@ unsigned long sleep_phys_sp(void *sp)
|
||||
return virt_to_phys(sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
|
||||
*/
|
||||
static struct pm_ops sa11x0_pm_ops = {
|
||||
.pm_disk_mode = PM_DISK_FIRMWARE,
|
||||
.enter = sa11x0_pm_enter,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init sa11x0_pm_init(void)
|
||||
|
@ -511,11 +511,6 @@ static int s3c2410_pm_enter(suspend_state_t state)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (state != PM_SUSPEND_MEM) {
|
||||
printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check if we have anything to wake-up with... bad things seem
|
||||
* to happen if you suspend with no wakeup (system will often
|
||||
* require a full power-cycle)
|
||||
@ -617,30 +612,9 @@ static int s3c2410_pm_enter(suspend_state_t state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after processes are frozen, but before we shut down devices.
|
||||
*/
|
||||
static int s3c2410_pm_prepare(suspend_state_t state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after devices are re-setup, but before processes are thawed.
|
||||
*/
|
||||
static int s3c2410_pm_finish(suspend_state_t state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
|
||||
*/
|
||||
static struct pm_ops s3c2410_pm_ops = {
|
||||
.pm_disk_mode = PM_DISK_FIRMWARE,
|
||||
.prepare = s3c2410_pm_prepare,
|
||||
.enter = s3c2410_pm_enter,
|
||||
.finish = s3c2410_pm_finish,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
|
||||
/* s3c2410_pm_init
|
||||
|
@ -12,7 +12,7 @@
|
||||
#
|
||||
# http://www.arm.linux.org.uk/developer/machines/?action=new
|
||||
#
|
||||
# Last update: Tue Jan 16 16:52:56 2007
|
||||
# Last update: Mon Apr 16 21:01:04 2007
|
||||
#
|
||||
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
|
||||
#
|
||||
@ -1190,13 +1190,12 @@ g500 MACH_G500 G500 1178
|
||||
bug MACH_BUG BUG 1179
|
||||
mx33ads MACH_MX33ADS MX33ADS 1180
|
||||
chub MACH_CHUB CHUB 1181
|
||||
gta01 MACH_GTA01 GTA01 1182
|
||||
neo1973_gta01 MACH_NEO1973_GTA01 NEO1973_GTA01 1182
|
||||
w90n740 MACH_W90N740 W90N740 1183
|
||||
medallion_sa2410 MACH_MEDALLION_SA2410 MEDALLION_SA2410 1184
|
||||
ia_cpu_9200_2 MACH_IA_CPU_9200_2 IA_CPU_9200_2 1185
|
||||
dimmrm9200 MACH_DIMMRM9200 DIMMRM9200 1186
|
||||
pm9261 MACH_PM9261 PM9261 1187
|
||||
mx21 MACH_MX21 MX21 1188
|
||||
ml7304 MACH_ML7304 ML7304 1189
|
||||
ucp250 MACH_UCP250 UCP250 1190
|
||||
intboard MACH_INTBOARD INTBOARD 1191
|
||||
@ -1242,3 +1241,97 @@ xscale_treo680 MACH_XSCALE_TREO680 XSCALE_TREO680 1230
|
||||
tecon_tmezon MACH_TECON_TMEZON TECON_TMEZON 1231
|
||||
zylonite MACH_ZYLONITE ZYLONITE 1233
|
||||
gene1270 MACH_GENE1270 GENE1270 1234
|
||||
zir2412 MACH_ZIR2412 ZIR2412 1235
|
||||
mx31lite MACH_MX31LITE MX31LITE 1236
|
||||
t700wx MACH_T700WX T700WX 1237
|
||||
vf100 MACH_VF100 VF100 1238
|
||||
nsb2 MACH_NSB2 NSB2 1239
|
||||
nxhmi_bb MACH_NXHMI_BB NXHMI_BB 1240
|
||||
nxhmi_re MACH_NXHMI_RE NXHMI_RE 1241
|
||||
n4100pro MACH_N4100PRO N4100PRO 1242
|
||||
sam9260 MACH_SAM9260 SAM9260 1243
|
||||
omap_treo600 MACH_OMAP_TREO600 OMAP_TREO600 1244
|
||||
indy2410 MACH_INDY2410 INDY2410 1245
|
||||
nelt_a MACH_NELT_A NELT_A 1246
|
||||
n311 MACH_N311 N311 1248
|
||||
at91sam9260vgk MACH_AT91SAM9260VGK AT91SAM9260VGK 1249
|
||||
at91leppe MACH_AT91LEPPE AT91LEPPE 1250
|
||||
at91lepccn MACH_AT91LEPCCN AT91LEPCCN 1251
|
||||
apc7100 MACH_APC7100 APC7100 1252
|
||||
stargazer MACH_STARGAZER STARGAZER 1253
|
||||
sonata MACH_SONATA SONATA 1254
|
||||
schmoogie MACH_SCHMOOGIE SCHMOOGIE 1255
|
||||
aztool MACH_AZTOOL AZTOOL 1256
|
||||
mioa701 MACH_MIOA701 MIOA701 1257
|
||||
sxni9260 MACH_SXNI9260 SXNI9260 1258
|
||||
mxc27520evb MACH_MXC27520EVB MXC27520EVB 1259
|
||||
armadillo5x0 MACH_ARMADILLO5X0 ARMADILLO5X0 1260
|
||||
mb9260 MACH_MB9260 MB9260 1261
|
||||
mb9263 MACH_MB9263 MB9263 1262
|
||||
ipac9302 MACH_IPAC9302 IPAC9302 1263
|
||||
cc9p9360js MACH_CC9P9360JS CC9P9360JS 1264
|
||||
gallium MACH_GALLIUM GALLIUM 1265
|
||||
msc2410 MACH_MSC2410 MSC2410 1266
|
||||
ghi270 MACH_GHI270 GHI270 1267
|
||||
davinci_leonardo MACH_DAVINCI_LEONARDO DAVINCI_LEONARDO 1268
|
||||
oiab MACH_OIAB OIAB 1269
|
||||
smdk6400 MACH_SMDK6400 SMDK6400 1270
|
||||
nokia_n800 MACH_NOKIA_N800 NOKIA_N800 1271
|
||||
greenphone MACH_GREENPHONE GREENPHONE 1272
|
||||
compex42x MACH_COMPEXWP18 COMPEXWP18 1273
|
||||
xmate MACH_XMATE XMATE 1274
|
||||
energizer MACH_ENERGIZER ENERGIZER 1275
|
||||
ime1 MACH_IME1 IME1 1276
|
||||
sweda_tms MACH_SWEDATMS SWEDATMS 1277
|
||||
ntnp435c MACH_NTNP435C NTNP435C 1278
|
||||
spectro2 MACH_SPECTRO2 SPECTRO2 1279
|
||||
h6039 MACH_H6039 H6039 1280
|
||||
ep80219 MACH_EP80219 EP80219 1281
|
||||
samoa_ii MACH_SAMOA_II SAMOA_II 1282
|
||||
cwmxl MACH_CWMXL CWMXL 1283
|
||||
as9200 MACH_AS9200 AS9200 1284
|
||||
sfx1149 MACH_SFX1149 SFX1149 1285
|
||||
navi010 MACH_NAVI010 NAVI010 1286
|
||||
multmdp MACH_MULTMDP MULTMDP 1287
|
||||
scb9520 MACH_SCB9520 SCB9520 1288
|
||||
htcathena MACH_HTCATHENA HTCATHENA 1289
|
||||
xp179 MACH_XP179 XP179 1290
|
||||
h4300 MACH_H4300 H4300 1291
|
||||
goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292
|
||||
mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293
|
||||
adsbitsymx MACH_ADSBITSIMX ADSBITSIMX 1294
|
||||
adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295
|
||||
mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296
|
||||
em_x270 MACH_EM_X270 EM_X270 1297
|
||||
tpp302 MACH_TPP302 TPP302 1298
|
||||
tpp104 MACH_TPM104 TPM104 1299
|
||||
tpm102 MACH_TPM102 TPM102 1300
|
||||
tpm109 MACH_TPM109 TPM109 1301
|
||||
fbxo1 MACH_FBXO1 FBXO1 1302
|
||||
hxd8 MACH_HXD8 HXD8 1303
|
||||
neo1973_gta02 MACH_NEO1973_GTA02 NEO1973_GTA02 1304
|
||||
emtest MACH_EMTEST EMTEST 1305
|
||||
ad6900 MACH_AD6900 AD6900 1306
|
||||
europa MACH_EUROPA EUROPA 1307
|
||||
metroconnect MACH_METROCONNECT METROCONNECT 1308
|
||||
ez_s2410 MACH_EZ_S2410 EZ_S2410 1309
|
||||
ez_s2440 MACH_EZ_S2440 EZ_S2440 1310
|
||||
ez_ep9312 MACH_EZ_EP9312 EZ_EP9312 1311
|
||||
ez_ep9315 MACH_EZ_EP9315 EZ_EP9315 1312
|
||||
ez_x7 MACH_EZ_X7 EZ_X7 1313
|
||||
godotdb MACH_GODOTDB GODOTDB 1314
|
||||
mistral MACH_MISTRAL MISTRAL 1315
|
||||
msm MACH_MSM MSM 1316
|
||||
ct5910 MACH_CT5910 CT5910 1317
|
||||
ct5912 MACH_CT5912 CT5912 1318
|
||||
hynet_ine MACH_HYNET_INE HYNET_INE 1319
|
||||
hynet_app MACH_HYNET_APP HYNET_APP 1320
|
||||
msm7200 MACH_MSM7200 MSM7200 1321
|
||||
msm7600 MACH_MSM7600 MSM7600 1322
|
||||
ceb255 MACH_CEB255 CEB255 1323
|
||||
ciel MACH_CIEL CIEL 1324
|
||||
slm5650 MACH_SLM5650 SLM5650 1325
|
||||
at91sam9rlek MACH_AT91SAM9RLEK AT91SAM9RLEK 1326
|
||||
comtech_router MACH_COMTECH_ROUTER COMTECH_ROUTER 1327
|
||||
sbc2410x MACH_SBC2410X SBC2410X 1328
|
||||
at4x0bd MACH_AT4X0BD AT4X0BD 1329
|
||||
|
@ -57,9 +57,6 @@ config ARCH_HAS_ILOG2_U64
|
||||
bool
|
||||
default n
|
||||
|
||||
config GENERIC_BUST_SPINLOCK
|
||||
bool
|
||||
|
||||
config GENERIC_HWEIGHT
|
||||
bool
|
||||
default y
|
||||
@ -68,6 +65,11 @@ config GENERIC_CALIBRATE_DELAY
|
||||
bool
|
||||
default y
|
||||
|
||||
config GENERIC_BUG
|
||||
bool
|
||||
default y
|
||||
depends on BUG
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
menu "System Type and features"
|
||||
@ -106,6 +108,9 @@ choice
|
||||
config BOARD_ATSTK1000
|
||||
bool "ATSTK1000 evaluation board"
|
||||
select BOARD_ATSTK1002 if CPU_AT32AP7000
|
||||
|
||||
config BOARD_ATNGW100
|
||||
bool "ATNGW100 Network Gateway"
|
||||
endchoice
|
||||
|
||||
choice
|
||||
@ -116,6 +121,8 @@ config LOADER_U_BOOT
|
||||
bool "U-Boot (or similar) bootloader"
|
||||
endchoice
|
||||
|
||||
source "arch/avr32/mach-at32ap/Kconfig"
|
||||
|
||||
config LOAD_ADDRESS
|
||||
hex
|
||||
default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y
|
||||
|
@ -27,6 +27,7 @@ head-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/head.o
|
||||
head-y += arch/avr32/kernel/head.o
|
||||
core-$(CONFIG_PLATFORM_AT32AP) += arch/avr32/mach-at32ap/
|
||||
core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/
|
||||
core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/
|
||||
core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/
|
||||
core-y += arch/avr32/kernel/
|
||||
core-y += arch/avr32/mm/
|
||||
|
1
arch/avr32/boards/atngw100/Makefile
Normal file
1
arch/avr32/boards/atngw100/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-y += setup.o flash.o
|
95
arch/avr32/boards/atngw100/flash.c
Normal file
95
arch/avr32/boards/atngw100/flash.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* ATNGW100 board-specific flash initialization
|
||||
*
|
||||
* Copyright (C) 2005-2006 Atmel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
|
||||
#include <asm/arch/smc.h>
|
||||
|
||||
static struct smc_config flash_config __initdata = {
|
||||
.ncs_read_setup = 0,
|
||||
.nrd_setup = 40,
|
||||
.ncs_write_setup = 0,
|
||||
.nwe_setup = 10,
|
||||
|
||||
.ncs_read_pulse = 80,
|
||||
.nrd_pulse = 40,
|
||||
.ncs_write_pulse = 65,
|
||||
.nwe_pulse = 55,
|
||||
|
||||
.read_cycle = 120,
|
||||
.write_cycle = 120,
|
||||
|
||||
.bus_width = 2,
|
||||
.nrd_controlled = 1,
|
||||
.nwe_controlled = 1,
|
||||
.byte_write = 1,
|
||||
};
|
||||
|
||||
static struct mtd_partition flash_parts[] = {
|
||||
{
|
||||
.name = "u-boot",
|
||||
.offset = 0x00000000,
|
||||
.size = 0x00020000, /* 128 KiB */
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},
|
||||
{
|
||||
.name = "root",
|
||||
.offset = 0x00020000,
|
||||
.size = 0x007d0000,
|
||||
},
|
||||
{
|
||||
.name = "env",
|
||||
.offset = 0x007f0000,
|
||||
.size = 0x00010000,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data flash_data = {
|
||||
.width = 2,
|
||||
.nr_parts = ARRAY_SIZE(flash_parts),
|
||||
.parts = flash_parts,
|
||||
};
|
||||
|
||||
static struct resource flash_resource = {
|
||||
.start = 0x00000000,
|
||||
.end = 0x007fffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device flash_device = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.resource = &flash_resource,
|
||||
.num_resources = 1,
|
||||
.dev = {
|
||||
.platform_data = &flash_data,
|
||||
},
|
||||
};
|
||||
|
||||
/* This needs to be called after the SMC has been initialized */
|
||||
static int __init atngw100_flash_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = smc_set_configuration(0, &flash_config);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "atngw100: failed to set NOR flash timing\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_device_register(&flash_device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(atngw100_flash_init);
|
124
arch/avr32/boards/atngw100/setup.c
Normal file
124
arch/avr32/boards/atngw100/setup.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Board-specific setup code for the ATNGW100 Network Gateway
|
||||
*
|
||||
* Copyright (C) 2005-2006 Atmel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <asm/arch/at32ap7000.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/init.h>
|
||||
|
||||
/* Initialized by bootloader-specific startup code. */
|
||||
struct tag *bootloader_tags __initdata;
|
||||
|
||||
struct eth_addr {
|
||||
u8 addr[6];
|
||||
};
|
||||
static struct eth_addr __initdata hw_addr[2];
|
||||
static struct eth_platform_data __initdata eth_data[2];
|
||||
|
||||
static struct spi_board_info spi0_board_info[] __initdata = {
|
||||
{
|
||||
.modalias = "mtd_dataflash",
|
||||
.max_speed_hz = 10000000,
|
||||
.chip_select = 0,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* The next two functions should go away as the boot loader is
|
||||
* supposed to initialize the macb address registers with a valid
|
||||
* ethernet address. But we need to keep it around for a while until
|
||||
* we can be reasonably sure the boot loader does this.
|
||||
*
|
||||
* The phy_id is ignored as the driver will probe for it.
|
||||
*/
|
||||
static int __init parse_tag_ethernet(struct tag *tag)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = tag->u.ethernet.mac_index;
|
||||
if (i < ARRAY_SIZE(hw_addr))
|
||||
memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
|
||||
sizeof(hw_addr[i].addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
|
||||
|
||||
static void __init set_hw_addr(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
const u8 *addr;
|
||||
void __iomem *regs;
|
||||
struct clk *pclk;
|
||||
|
||||
if (!res)
|
||||
return;
|
||||
if (pdev->id >= ARRAY_SIZE(hw_addr))
|
||||
return;
|
||||
|
||||
addr = hw_addr[pdev->id].addr;
|
||||
if (!is_valid_ether_addr(addr))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Since this is board-specific code, we'll cheat and use the
|
||||
* physical address directly as we happen to know that it's
|
||||
* the same as the virtual address.
|
||||
*/
|
||||
regs = (void __iomem __force *)res->start;
|
||||
pclk = clk_get(&pdev->dev, "pclk");
|
||||
if (!pclk)
|
||||
return;
|
||||
|
||||
clk_enable(pclk);
|
||||
__raw_writel((addr[3] << 24) | (addr[2] << 16)
|
||||
| (addr[1] << 8) | addr[0], regs + 0x98);
|
||||
__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
|
||||
clk_disable(pclk);
|
||||
clk_put(pclk);
|
||||
}
|
||||
|
||||
struct platform_device *at32_usart_map[1];
|
||||
unsigned int at32_nr_usarts = 1;
|
||||
|
||||
void __init setup_board(void)
|
||||
{
|
||||
at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */
|
||||
at32_setup_serial_console(0);
|
||||
}
|
||||
|
||||
static int __init atngw100_init(void)
|
||||
{
|
||||
/*
|
||||
* ATNGW100 uses 16-bit SDRAM interface, so we don't need to
|
||||
* reserve any pins for it.
|
||||
*/
|
||||
|
||||
at32_add_system_devices();
|
||||
|
||||
at32_add_device_usart(0);
|
||||
|
||||
set_hw_addr(at32_add_device_eth(0, ð_data[0]));
|
||||
set_hw_addr(at32_add_device_eth(1, ð_data[1]));
|
||||
|
||||
at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
|
||||
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(atngw100_init);
|
@ -33,7 +33,7 @@ struct eth_addr {
|
||||
static struct eth_addr __initdata hw_addr[2];
|
||||
|
||||
static struct eth_platform_data __initdata eth_data[2];
|
||||
extern struct lcdc_platform_data atstk1000_fb0_data;
|
||||
static struct lcdc_platform_data atstk1000_fb0_data;
|
||||
|
||||
static struct spi_board_info spi0_board_info[] __initdata = {
|
||||
{
|
||||
@ -148,6 +148,8 @@ static int __init atstk1002_init(void)
|
||||
set_hw_addr(at32_add_device_eth(0, ð_data[0]));
|
||||
|
||||
at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
|
||||
atstk1000_fb0_data.fbmem_start = fbmem_start;
|
||||
atstk1000_fb0_data.fbmem_size = fbmem_size;
|
||||
at32_add_device_lcdc(0, &atstk1000_fb0_data);
|
||||
|
||||
return 0;
|
||||
|
@ -18,33 +18,3 @@
|
||||
|
||||
/* Initialized by bootloader-specific startup code. */
|
||||
struct tag *bootloader_tags __initdata;
|
||||
|
||||
struct lcdc_platform_data __initdata atstk1000_fb0_data;
|
||||
|
||||
void __init board_setup_fbmem(unsigned long fbmem_start,
|
||||
unsigned long fbmem_size)
|
||||
{
|
||||
if (!fbmem_size)
|
||||
return;
|
||||
|
||||
if (!fbmem_start) {
|
||||
void *fbmem;
|
||||
|
||||
fbmem = alloc_bootmem_low_pages(fbmem_size);
|
||||
fbmem_start = __pa(fbmem);
|
||||
} else {
|
||||
pg_data_t *pgdat;
|
||||
|
||||
for_each_online_pgdat(pgdat) {
|
||||
if (fbmem_start >= pgdat->bdata->node_boot_start
|
||||
&& fbmem_start <= pgdat->bdata->node_low_pfn)
|
||||
reserve_bootmem_node(pgdat, fbmem_start,
|
||||
fbmem_size);
|
||||
}
|
||||
}
|
||||
|
||||
printk("%luKiB framebuffer memory at address 0x%08lx\n",
|
||||
fbmem_size >> 10, fbmem_start);
|
||||
atstk1000_fb0_data.fbmem_start = fbmem_start;
|
||||
atstk1000_fb0_data.fbmem_size = fbmem_size;
|
||||
}
|
||||
|
1085
arch/avr32/configs/atngw100_defconfig
Normal file
1085
arch/avr32/configs/atngw100_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
@ -209,16 +209,17 @@ static const char *mmu_types[] = {
|
||||
void __init setup_processor(void)
|
||||
{
|
||||
unsigned long config0, config1;
|
||||
unsigned long features;
|
||||
unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type;
|
||||
unsigned tmp;
|
||||
|
||||
config0 = sysreg_read(CONFIG0); /* 0x0000013e; */
|
||||
config1 = sysreg_read(CONFIG1); /* 0x01f689a2; */
|
||||
cpu_id = config0 >> 24;
|
||||
cpu_rev = (config0 >> 16) & 0xff;
|
||||
arch_id = (config0 >> 13) & 0x07;
|
||||
arch_rev = (config0 >> 10) & 0x07;
|
||||
mmu_type = (config0 >> 7) & 0x03;
|
||||
config0 = sysreg_read(CONFIG0);
|
||||
config1 = sysreg_read(CONFIG1);
|
||||
cpu_id = SYSREG_BFEXT(PROCESSORID, config0);
|
||||
cpu_rev = SYSREG_BFEXT(PROCESSORREVISION, config0);
|
||||
arch_id = SYSREG_BFEXT(AT, config0);
|
||||
arch_rev = SYSREG_BFEXT(AR, config0);
|
||||
mmu_type = SYSREG_BFEXT(MMUT, config0);
|
||||
|
||||
boot_cpu_data.arch_type = arch_id;
|
||||
boot_cpu_data.cpu_type = cpu_id;
|
||||
@ -226,16 +227,16 @@ void __init setup_processor(void)
|
||||
boot_cpu_data.cpu_revision = cpu_rev;
|
||||
boot_cpu_data.tlb_config = mmu_type;
|
||||
|
||||
tmp = (config1 >> 13) & 0x07;
|
||||
tmp = SYSREG_BFEXT(ILSZ, config1);
|
||||
if (tmp) {
|
||||
boot_cpu_data.icache.ways = 1 << ((config1 >> 10) & 0x07);
|
||||
boot_cpu_data.icache.sets = 1 << ((config1 >> 16) & 0x0f);
|
||||
boot_cpu_data.icache.ways = 1 << SYSREG_BFEXT(IASS, config1);
|
||||
boot_cpu_data.icache.sets = 1 << SYSREG_BFEXT(ISET, config1);
|
||||
boot_cpu_data.icache.linesz = 1 << (tmp + 1);
|
||||
}
|
||||
tmp = (config1 >> 3) & 0x07;
|
||||
tmp = SYSREG_BFEXT(DLSZ, config1);
|
||||
if (tmp) {
|
||||
boot_cpu_data.dcache.ways = 1 << (config1 & 0x07);
|
||||
boot_cpu_data.dcache.sets = 1 << ((config1 >> 6) & 0x0f);
|
||||
boot_cpu_data.dcache.ways = 1 << SYSREG_BFEXT(DASS, config1);
|
||||
boot_cpu_data.dcache.sets = 1 << SYSREG_BFEXT(DSET, config1);
|
||||
boot_cpu_data.dcache.linesz = 1 << (tmp + 1);
|
||||
}
|
||||
|
||||
@ -250,16 +251,39 @@ void __init setup_processor(void)
|
||||
cpu_names[cpu_id], cpu_id, cpu_rev,
|
||||
arch_names[arch_id], arch_rev);
|
||||
printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]);
|
||||
|
||||
printk ("CPU: features:");
|
||||
if (config0 & (1 << 6))
|
||||
printk(" fpu");
|
||||
if (config0 & (1 << 5))
|
||||
printk(" java");
|
||||
if (config0 & (1 << 4))
|
||||
printk(" perfctr");
|
||||
if (config0 & (1 << 3))
|
||||
features = 0;
|
||||
if (config0 & SYSREG_BIT(CONFIG0_R)) {
|
||||
features |= AVR32_FEATURE_RMW;
|
||||
printk(" rmw");
|
||||
}
|
||||
if (config0 & SYSREG_BIT(CONFIG0_D)) {
|
||||
features |= AVR32_FEATURE_DSP;
|
||||
printk(" dsp");
|
||||
}
|
||||
if (config0 & SYSREG_BIT(CONFIG0_S)) {
|
||||
features |= AVR32_FEATURE_SIMD;
|
||||
printk(" simd");
|
||||
}
|
||||
if (config0 & SYSREG_BIT(CONFIG0_O)) {
|
||||
features |= AVR32_FEATURE_OCD;
|
||||
printk(" ocd");
|
||||
}
|
||||
if (config0 & SYSREG_BIT(CONFIG0_P)) {
|
||||
features |= AVR32_FEATURE_PCTR;
|
||||
printk(" perfctr");
|
||||
}
|
||||
if (config0 & SYSREG_BIT(CONFIG0_J)) {
|
||||
features |= AVR32_FEATURE_JAVA;
|
||||
printk(" java");
|
||||
}
|
||||
if (config0 & SYSREG_BIT(CONFIG0_F)) {
|
||||
features |= AVR32_FEATURE_FPU;
|
||||
printk(" fpu");
|
||||
}
|
||||
printk("\n");
|
||||
boot_cpu_data.features = features;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
@ -100,55 +100,49 @@ dtlb_miss_write:
|
||||
|
||||
.global tlb_miss_common
|
||||
tlb_miss_common:
|
||||
mfsr r0, SYSREG_PTBR
|
||||
mfsr r1, SYSREG_TLBEAR
|
||||
mfsr r0, SYSREG_TLBEAR
|
||||
mfsr r1, SYSREG_PTBR
|
||||
|
||||
/* Is it the vmalloc space? */
|
||||
bld r1, 31
|
||||
bld r0, 31
|
||||
brcs handle_vmalloc_miss
|
||||
|
||||
/* First level lookup */
|
||||
pgtbl_lookup:
|
||||
lsr r2, r1, PGDIR_SHIFT
|
||||
ld.w r0, r0[r2 << 2]
|
||||
bld r0, _PAGE_BIT_PRESENT
|
||||
lsr r2, r0, PGDIR_SHIFT
|
||||
ld.w r3, r1[r2 << 2]
|
||||
bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT
|
||||
bld r3, _PAGE_BIT_PRESENT
|
||||
brcc page_table_not_present
|
||||
|
||||
/* TODO: Check access rights on page table if necessary */
|
||||
|
||||
/* Translate to virtual address in P1. */
|
||||
andl r0, 0xf000
|
||||
sbr r0, 31
|
||||
andl r3, 0xf000
|
||||
sbr r3, 31
|
||||
|
||||
/* Second level lookup */
|
||||
lsl r1, (32 - PGDIR_SHIFT)
|
||||
lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT
|
||||
add r2, r0, r1 << 2
|
||||
ld.w r1, r2[0]
|
||||
bld r1, _PAGE_BIT_PRESENT
|
||||
ld.w r2, r3[r1 << 2]
|
||||
mfsr r0, SYSREG_TLBARLO
|
||||
bld r2, _PAGE_BIT_PRESENT
|
||||
brcc page_not_present
|
||||
|
||||
/* Mark the page as accessed */
|
||||
sbr r1, _PAGE_BIT_ACCESSED
|
||||
st.w r2[0], r1
|
||||
sbr r2, _PAGE_BIT_ACCESSED
|
||||
st.w r3[r1 << 2], r2
|
||||
|
||||
/* Drop software flags */
|
||||
andl r1, _PAGE_FLAGS_HARDWARE_MASK & 0xffff
|
||||
mtsr SYSREG_TLBELO, r1
|
||||
andl r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff
|
||||
mtsr SYSREG_TLBELO, r2
|
||||
|
||||
/* Figure out which entry we want to replace */
|
||||
mfsr r0, SYSREG_TLBARLO
|
||||
mfsr r1, SYSREG_MMUCR
|
||||
clz r2, r0
|
||||
brcc 1f
|
||||
mov r1, -1 /* All entries have been accessed, */
|
||||
mtsr SYSREG_TLBARLO, r1 /* so reset TLBAR */
|
||||
mov r2, 0 /* and start at 0 */
|
||||
1: mfsr r1, SYSREG_MMUCR
|
||||
lsl r2, 14
|
||||
andl r1, 0x3fff, COH
|
||||
or r1, r2
|
||||
mtsr SYSREG_MMUCR, r1
|
||||
mov r3, -1 /* All entries have been accessed, */
|
||||
mov r2, 0 /* so start at 0 */
|
||||
mtsr SYSREG_TLBARLO, r3 /* and reset TLBAR */
|
||||
|
||||
1: bfins r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE
|
||||
mtsr SYSREG_MMUCR, r1
|
||||
tlbw
|
||||
|
||||
tlbmiss_restore
|
||||
@ -156,8 +150,8 @@ pgtbl_lookup:
|
||||
|
||||
handle_vmalloc_miss:
|
||||
/* Simply do the lookup in init's page table */
|
||||
mov r0, lo(swapper_pg_dir)
|
||||
orh r0, hi(swapper_pg_dir)
|
||||
mov r1, lo(swapper_pg_dir)
|
||||
orh r1, hi(swapper_pg_dir)
|
||||
rjmp pgtbl_lookup
|
||||
|
||||
|
||||
@ -340,12 +334,34 @@ do_bus_error_read:
|
||||
do_nmi_ll:
|
||||
sub sp, 4
|
||||
stmts --sp, r0-lr
|
||||
/* FIXME: Make sure RAR_NMI and RSR_NMI are pushed instead of *_EX */
|
||||
rcall save_full_context_ex
|
||||
mfsr r9, SYSREG_RSR_NMI
|
||||
mfsr r8, SYSREG_RAR_NMI
|
||||
bfextu r0, r9, MODE_SHIFT, 3
|
||||
brne 2f
|
||||
|
||||
1: pushm r8, r9 /* PC and SR */
|
||||
mfsr r12, SYSREG_ECR
|
||||
mov r11, sp
|
||||
rcall do_nmi
|
||||
rjmp bad_return
|
||||
popm r8-r9
|
||||
mtsr SYSREG_RAR_NMI, r8
|
||||
tst r0, r0
|
||||
mtsr SYSREG_RSR_NMI, r9
|
||||
brne 3f
|
||||
|
||||
ldmts sp++, r0-lr
|
||||
sub sp, -4 /* skip r12_orig */
|
||||
rete
|
||||
|
||||
2: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR)
|
||||
stdsp sp[4], r10 /* replace saved SP */
|
||||
rjmp 1b
|
||||
|
||||
3: popm lr
|
||||
sub sp, -4 /* skip sp */
|
||||
popm r0-r12
|
||||
sub sp, -4 /* skip r12_orig */
|
||||
rete
|
||||
|
||||
handle_address_fault:
|
||||
sub sp, 4
|
||||
@ -630,9 +646,12 @@ irq_level\level:
|
||||
rcall do_IRQ
|
||||
|
||||
lddsp r4, sp[REG_SR]
|
||||
andh r4, (MODE_MASK >> 16), COH
|
||||
bfextu r4, r4, SYSREG_M0_OFFSET, 3
|
||||
cp.w r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET
|
||||
breq 2f
|
||||
cp.w r4, MODE_USER >> SYSREG_M0_OFFSET
|
||||
#ifdef CONFIG_PREEMPT
|
||||
brne 2f
|
||||
brne 3f
|
||||
#else
|
||||
brne 1f
|
||||
#endif
|
||||
@ -649,9 +668,18 @@ irq_level\level:
|
||||
sub sp, -4 /* ignore r12_orig */
|
||||
rete
|
||||
|
||||
2: get_thread_info r0
|
||||
ld.w r1, r0[TI_flags]
|
||||
bld r1, TIF_CPU_GOING_TO_SLEEP
|
||||
#ifdef CONFIG_PREEMPT
|
||||
2:
|
||||
get_thread_info r0
|
||||
brcc 3f
|
||||
#else
|
||||
brcc 1b
|
||||
#endif
|
||||
sub r1, pc, . - cpu_idle_skip_sleep
|
||||
stdsp sp[REG_PC], r1
|
||||
#ifdef CONFIG_PREEMPT
|
||||
3: get_thread_info r0
|
||||
ld.w r2, r0[TI_preempt_count]
|
||||
cp.w r2, 0
|
||||
brne 1b
|
||||
@ -662,12 +690,32 @@ irq_level\level:
|
||||
bld r4, SYSREG_GM_OFFSET
|
||||
brcs 1b
|
||||
rcall preempt_schedule_irq
|
||||
rjmp 1b
|
||||
#endif
|
||||
rjmp 1b
|
||||
.endm
|
||||
|
||||
.section .irq.text,"ax",@progbits
|
||||
|
||||
.global cpu_idle_sleep
|
||||
cpu_idle_sleep:
|
||||
mask_interrupts
|
||||
get_thread_info r8
|
||||
ld.w r9, r8[TI_flags]
|
||||
bld r9, TIF_NEED_RESCHED
|
||||
brcs cpu_idle_enable_int_and_exit
|
||||
sbr r9, TIF_CPU_GOING_TO_SLEEP
|
||||
st.w r8[TI_flags], r9
|
||||
unmask_interrupts
|
||||
sleep 0
|
||||
cpu_idle_skip_sleep:
|
||||
mask_interrupts
|
||||
ld.w r9, r8[TI_flags]
|
||||
cbr r9, TIF_CPU_GOING_TO_SLEEP
|
||||
st.w r8[TI_flags], r9
|
||||
cpu_idle_enable_int_and_exit:
|
||||
unmask_interrupts
|
||||
retal r12
|
||||
|
||||
.global irq_level0
|
||||
.global irq_level1
|
||||
.global irq_level2
|
||||
|
@ -12,10 +12,11 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
void *module_alloc(unsigned long size)
|
||||
@ -315,10 +316,10 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
|
||||
vfree(module->arch.syminfo);
|
||||
module->arch.syminfo = NULL;
|
||||
|
||||
return 0;
|
||||
return module_bug_finalize(hdr, sechdrs, module);
|
||||
}
|
||||
|
||||
void module_arch_cleanup(struct module *module)
|
||||
{
|
||||
|
||||
module_bug_cleanup(module);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/fs.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include <asm/sysreg.h>
|
||||
@ -19,6 +20,8 @@
|
||||
void (*pm_power_off)(void) = NULL;
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
|
||||
extern void cpu_idle_sleep(void);
|
||||
|
||||
/*
|
||||
* This file handles the architecture-dependent parts of process handling..
|
||||
*/
|
||||
@ -27,9 +30,8 @@ void cpu_idle(void)
|
||||
{
|
||||
/* endless idle loop with no priority at all */
|
||||
while (1) {
|
||||
/* TODO: Enter sleep mode */
|
||||
while (!need_resched())
|
||||
cpu_relax();
|
||||
cpu_idle_sleep();
|
||||
preempt_enable_no_resched();
|
||||
schedule();
|
||||
preempt_disable();
|
||||
@ -114,39 +116,178 @@ void release_thread(struct task_struct *dead_task)
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static void dump_mem(const char *str, const char *log_lvl,
|
||||
unsigned long bottom, unsigned long top)
|
||||
{
|
||||
unsigned long p;
|
||||
int i;
|
||||
|
||||
printk("%s%s(0x%08lx to 0x%08lx)\n", log_lvl, str, bottom, top);
|
||||
|
||||
for (p = bottom & ~31; p < top; ) {
|
||||
printk("%s%04lx: ", log_lvl, p & 0xffff);
|
||||
|
||||
for (i = 0; i < 8; i++, p += 4) {
|
||||
unsigned int val;
|
||||
|
||||
if (p < bottom || p >= top)
|
||||
printk(" ");
|
||||
else {
|
||||
if (__get_user(val, (unsigned int __user *)p)) {
|
||||
printk("\n");
|
||||
goto out;
|
||||
}
|
||||
printk("%08x ", val);
|
||||
}
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p)
|
||||
{
|
||||
return (p > (unsigned long)tinfo)
|
||||
&& (p < (unsigned long)tinfo + THREAD_SIZE - 3);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
static void show_trace_log_lvl(struct task_struct *tsk, unsigned long *sp,
|
||||
struct pt_regs *regs, const char *log_lvl)
|
||||
{
|
||||
unsigned long lr, fp;
|
||||
struct thread_info *tinfo;
|
||||
|
||||
if (regs)
|
||||
fp = regs->r7;
|
||||
else if (tsk == current)
|
||||
asm("mov %0, r7" : "=r"(fp));
|
||||
else
|
||||
fp = tsk->thread.cpu_context.r7;
|
||||
|
||||
/*
|
||||
* Walk the stack as long as the frame pointer (a) is within
|
||||
* the kernel stack of the task, and (b) it doesn't move
|
||||
* downwards.
|
||||
*/
|
||||
tinfo = task_thread_info(tsk);
|
||||
printk("%sCall trace:\n", log_lvl);
|
||||
while (valid_stack_ptr(tinfo, fp)) {
|
||||
unsigned long new_fp;
|
||||
|
||||
lr = *(unsigned long *)fp;
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
printk("%s [<%08lx>] ", log_lvl, lr);
|
||||
#else
|
||||
printk(" [<%08lx>] ", lr);
|
||||
#endif
|
||||
print_symbol("%s\n", lr);
|
||||
|
||||
new_fp = *(unsigned long *)(fp + 4);
|
||||
if (new_fp <= fp)
|
||||
break;
|
||||
fp = new_fp;
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
#else
|
||||
static void show_trace_log_lvl(struct task_struct *tsk, unsigned long *sp,
|
||||
struct pt_regs *regs, const char *log_lvl)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
printk("%sCall trace:\n", log_lvl);
|
||||
|
||||
while (!kstack_end(sp)) {
|
||||
addr = *sp++;
|
||||
if (kernel_text_address(addr)) {
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
printk("%s [<%08lx>] ", log_lvl, addr);
|
||||
#else
|
||||
printk(" [<%08lx>] ", addr);
|
||||
#endif
|
||||
print_symbol("%s\n", addr);
|
||||
}
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp,
|
||||
struct pt_regs *regs, const char *log_lvl)
|
||||
{
|
||||
struct thread_info *tinfo;
|
||||
|
||||
if (sp == 0) {
|
||||
if (tsk)
|
||||
sp = tsk->thread.cpu_context.ksp;
|
||||
else
|
||||
sp = (unsigned long)&tinfo;
|
||||
}
|
||||
if (!tsk)
|
||||
tsk = current;
|
||||
|
||||
tinfo = task_thread_info(tsk);
|
||||
|
||||
if (valid_stack_ptr(tinfo, sp)) {
|
||||
dump_mem("Stack: ", log_lvl, sp,
|
||||
THREAD_SIZE + (unsigned long)tinfo);
|
||||
show_trace_log_lvl(tsk, (unsigned long *)sp, regs, log_lvl);
|
||||
}
|
||||
}
|
||||
|
||||
void show_stack(struct task_struct *tsk, unsigned long *stack)
|
||||
{
|
||||
show_stack_log_lvl(tsk, (unsigned long)stack, NULL, "");
|
||||
}
|
||||
|
||||
void dump_stack(void)
|
||||
{
|
||||
unsigned long stack;
|
||||
|
||||
show_trace_log_lvl(current, &stack, NULL, "");
|
||||
}
|
||||
EXPORT_SYMBOL(dump_stack);
|
||||
|
||||
static const char *cpu_modes[] = {
|
||||
"Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
|
||||
"Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
|
||||
};
|
||||
|
||||
void show_regs(struct pt_regs *regs)
|
||||
void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl)
|
||||
{
|
||||
unsigned long sp = regs->sp;
|
||||
unsigned long lr = regs->lr;
|
||||
unsigned long mode = (regs->sr & MODE_MASK) >> MODE_SHIFT;
|
||||
|
||||
if (!user_mode(regs))
|
||||
if (!user_mode(regs)) {
|
||||
sp = (unsigned long)regs + FRAME_SIZE_FULL;
|
||||
|
||||
print_symbol("PC is at %s\n", instruction_pointer(regs));
|
||||
print_symbol("LR is at %s\n", lr);
|
||||
printk("pc : [<%08lx>] lr : [<%08lx>] %s\n"
|
||||
"sp : %08lx r12: %08lx r11: %08lx\n",
|
||||
instruction_pointer(regs),
|
||||
lr, print_tainted(), sp, regs->r12, regs->r11);
|
||||
printk("r10: %08lx r9 : %08lx r8 : %08lx\n",
|
||||
regs->r10, regs->r9, regs->r8);
|
||||
printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
|
||||
regs->r7, regs->r6, regs->r5, regs->r4);
|
||||
printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
|
||||
regs->r3, regs->r2, regs->r1, regs->r0);
|
||||
printk("Flags: %c%c%c%c%c\n",
|
||||
printk("%s", log_lvl);
|
||||
print_symbol("PC is at %s\n", instruction_pointer(regs));
|
||||
printk("%s", log_lvl);
|
||||
print_symbol("LR is at %s\n", lr);
|
||||
}
|
||||
|
||||
printk("%spc : [<%08lx>] lr : [<%08lx>] %s\n"
|
||||
"%ssp : %08lx r12: %08lx r11: %08lx\n",
|
||||
log_lvl, instruction_pointer(regs), lr, print_tainted(),
|
||||
log_lvl, sp, regs->r12, regs->r11);
|
||||
printk("%sr10: %08lx r9 : %08lx r8 : %08lx\n",
|
||||
log_lvl, regs->r10, regs->r9, regs->r8);
|
||||
printk("%sr7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
|
||||
log_lvl, regs->r7, regs->r6, regs->r5, regs->r4);
|
||||
printk("%sr3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
|
||||
log_lvl, regs->r3, regs->r2, regs->r1, regs->r0);
|
||||
printk("%sFlags: %c%c%c%c%c\n", log_lvl,
|
||||
regs->sr & SR_Q ? 'Q' : 'q',
|
||||
regs->sr & SR_V ? 'V' : 'v',
|
||||
regs->sr & SR_N ? 'N' : 'n',
|
||||
regs->sr & SR_Z ? 'Z' : 'z',
|
||||
regs->sr & SR_C ? 'C' : 'c');
|
||||
printk("Mode bits: %c%c%c%c%c%c%c%c%c\n",
|
||||
printk("%sMode bits: %c%c%c%c%c%c%c%c%c\n", log_lvl,
|
||||
regs->sr & SR_H ? 'H' : 'h',
|
||||
regs->sr & SR_R ? 'R' : 'r',
|
||||
regs->sr & SR_J ? 'J' : 'j',
|
||||
@ -156,9 +297,21 @@ void show_regs(struct pt_regs *regs)
|
||||
regs->sr & SR_I1M ? '1' : '.',
|
||||
regs->sr & SR_I0M ? '0' : '.',
|
||||
regs->sr & SR_GM ? 'G' : 'g');
|
||||
printk("CPU Mode: %s\n", cpu_modes[mode]);
|
||||
printk("%sCPU Mode: %s\n", log_lvl, cpu_modes[mode]);
|
||||
printk("%sProcess: %s [%d] (task: %p thread: %p)\n",
|
||||
log_lvl, current->comm, current->pid, current,
|
||||
task_thread_info(current));
|
||||
}
|
||||
|
||||
show_trace(NULL, (unsigned long *)sp, regs);
|
||||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long sp = regs->sp;
|
||||
|
||||
if (!user_mode(regs))
|
||||
sp = (unsigned long)regs + FRAME_SIZE_FULL;
|
||||
|
||||
show_regs_log_lvl(regs, "");
|
||||
show_trace_log_lvl(current, (unsigned long *)sp, regs, "");
|
||||
}
|
||||
EXPORT_SYMBOL(show_regs);
|
||||
|
||||
|
@ -8,12 +8,14 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pfn.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -29,13 +31,6 @@
|
||||
|
||||
extern int root_mountflags;
|
||||
|
||||
/*
|
||||
* Bootloader-provided information about physical memory
|
||||
*/
|
||||
struct tag_mem_range *mem_phys;
|
||||
struct tag_mem_range *mem_reserved;
|
||||
struct tag_mem_range *mem_ramdisk;
|
||||
|
||||
/*
|
||||
* Initialize loops_per_jiffy as 5000000 (500MIPS).
|
||||
* Better make it too large than too small...
|
||||
@ -47,49 +42,194 @@ EXPORT_SYMBOL(boot_cpu_data);
|
||||
|
||||
static char __initdata command_line[COMMAND_LINE_SIZE];
|
||||
|
||||
/*
|
||||
* Should be more than enough, but if you have a _really_ complex
|
||||
* setup, you might need to increase the size of this...
|
||||
*/
|
||||
static struct tag_mem_range __initdata mem_range_cache[32];
|
||||
static unsigned mem_range_next_free;
|
||||
|
||||
/*
|
||||
* Standard memory resources
|
||||
*/
|
||||
static struct resource mem_res[] = {
|
||||
{
|
||||
.name = "Kernel code",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
{
|
||||
.name = "Kernel data",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
static struct resource __initdata kernel_data = {
|
||||
.name = "Kernel data",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
static struct resource __initdata kernel_code = {
|
||||
.name = "Kernel code",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_MEM,
|
||||
.sibling = &kernel_data,
|
||||
};
|
||||
|
||||
#define kernel_code mem_res[0]
|
||||
#define kernel_data mem_res[1]
|
||||
/*
|
||||
* Available system RAM and reserved regions as singly linked
|
||||
* lists. These lists are traversed using the sibling pointer in
|
||||
* struct resource and are kept sorted at all times.
|
||||
*/
|
||||
static struct resource *__initdata system_ram;
|
||||
static struct resource *__initdata reserved = &kernel_code;
|
||||
|
||||
/*
|
||||
* We need to allocate these before the bootmem allocator is up and
|
||||
* running, so we need this "cache". 32 entries are probably enough
|
||||
* for all but the most insanely complex systems.
|
||||
*/
|
||||
static struct resource __initdata res_cache[32];
|
||||
static unsigned int __initdata res_cache_next_free;
|
||||
|
||||
static void __init resource_init(void)
|
||||
{
|
||||
struct resource *mem, *res;
|
||||
struct resource *new;
|
||||
|
||||
kernel_code.start = __pa(init_mm.start_code);
|
||||
|
||||
for (mem = system_ram; mem; mem = mem->sibling) {
|
||||
new = alloc_bootmem_low(sizeof(struct resource));
|
||||
memcpy(new, mem, sizeof(struct resource));
|
||||
|
||||
new->sibling = NULL;
|
||||
if (request_resource(&iomem_resource, new))
|
||||
printk(KERN_WARNING "Bad RAM resource %08x-%08x\n",
|
||||
mem->start, mem->end);
|
||||
}
|
||||
|
||||
for (res = reserved; res; res = res->sibling) {
|
||||
new = alloc_bootmem_low(sizeof(struct resource));
|
||||
memcpy(new, res, sizeof(struct resource));
|
||||
|
||||
new->sibling = NULL;
|
||||
if (insert_resource(&iomem_resource, new))
|
||||
printk(KERN_WARNING
|
||||
"Bad reserved resource %s (%08x-%08x)\n",
|
||||
res->name, res->start, res->end);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init
|
||||
add_physical_memory(resource_size_t start, resource_size_t end)
|
||||
{
|
||||
struct resource *new, *next, **pprev;
|
||||
|
||||
for (pprev = &system_ram, next = system_ram; next;
|
||||
pprev = &next->sibling, next = next->sibling) {
|
||||
if (end < next->start)
|
||||
break;
|
||||
if (start <= next->end) {
|
||||
printk(KERN_WARNING
|
||||
"Warning: Physical memory map is broken\n");
|
||||
printk(KERN_WARNING
|
||||
"Warning: %08x-%08x overlaps %08x-%08x\n",
|
||||
start, end, next->start, next->end);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (res_cache_next_free >= ARRAY_SIZE(res_cache)) {
|
||||
printk(KERN_WARNING
|
||||
"Warning: Failed to add physical memory %08x-%08x\n",
|
||||
start, end);
|
||||
return;
|
||||
}
|
||||
|
||||
new = &res_cache[res_cache_next_free++];
|
||||
new->start = start;
|
||||
new->end = end;
|
||||
new->name = "System RAM";
|
||||
new->flags = IORESOURCE_MEM;
|
||||
|
||||
*pprev = new;
|
||||
}
|
||||
|
||||
static int __init
|
||||
add_reserved_region(resource_size_t start, resource_size_t end,
|
||||
const char *name)
|
||||
{
|
||||
struct resource *new, *next, **pprev;
|
||||
|
||||
if (end < start)
|
||||
return -EINVAL;
|
||||
|
||||
if (res_cache_next_free >= ARRAY_SIZE(res_cache))
|
||||
return -ENOMEM;
|
||||
|
||||
for (pprev = &reserved, next = reserved; next;
|
||||
pprev = &next->sibling, next = next->sibling) {
|
||||
if (end < next->start)
|
||||
break;
|
||||
if (start <= next->end)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
new = &res_cache[res_cache_next_free++];
|
||||
new->start = start;
|
||||
new->end = end;
|
||||
new->name = name;
|
||||
new->flags = IORESOURCE_MEM;
|
||||
|
||||
*pprev = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long __init
|
||||
find_free_region(const struct resource *mem, resource_size_t size,
|
||||
resource_size_t align)
|
||||
{
|
||||
struct resource *res;
|
||||
unsigned long target;
|
||||
|
||||
target = ALIGN(mem->start, align);
|
||||
for (res = reserved; res; res = res->sibling) {
|
||||
if ((target + size) <= res->start)
|
||||
break;
|
||||
if (target <= res->end)
|
||||
target = ALIGN(res->end + 1, align);
|
||||
}
|
||||
|
||||
if ((target + size) > (mem->end + 1))
|
||||
return mem->end + 1;
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
static int __init
|
||||
alloc_reserved_region(resource_size_t *start, resource_size_t size,
|
||||
resource_size_t align, const char *name)
|
||||
{
|
||||
struct resource *mem;
|
||||
resource_size_t target;
|
||||
int ret;
|
||||
|
||||
for (mem = system_ram; mem; mem = mem->sibling) {
|
||||
target = find_free_region(mem, size, align);
|
||||
if (target <= mem->end) {
|
||||
ret = add_reserved_region(target, target + size - 1,
|
||||
name);
|
||||
if (!ret)
|
||||
*start = target;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Early framebuffer allocation. Works as follows:
|
||||
* - If fbmem_size is zero, nothing will be allocated or reserved.
|
||||
* - If fbmem_start is zero when setup_bootmem() is called,
|
||||
* fbmem_size bytes will be allocated from the bootmem allocator.
|
||||
* a block of fbmem_size bytes will be reserved before bootmem
|
||||
* initialization. It will be aligned to the largest page size
|
||||
* that fbmem_size is a multiple of.
|
||||
* - If fbmem_start is nonzero, an area of size fbmem_size will be
|
||||
* reserved at the physical address fbmem_start if necessary. If
|
||||
* the area isn't in a memory region known to the kernel, it will
|
||||
* be left alone.
|
||||
* reserved at the physical address fbmem_start if possible. If
|
||||
* it collides with other reserved memory, a different block of
|
||||
* same size will be allocated, just as if fbmem_start was zero.
|
||||
*
|
||||
* Board-specific code may use these variables to set up platform data
|
||||
* for the framebuffer driver if fbmem_size is nonzero.
|
||||
*/
|
||||
static unsigned long __initdata fbmem_start;
|
||||
static unsigned long __initdata fbmem_size;
|
||||
resource_size_t __initdata fbmem_start;
|
||||
resource_size_t __initdata fbmem_size;
|
||||
|
||||
/*
|
||||
* "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
|
||||
@ -103,49 +243,43 @@ static unsigned long __initdata fbmem_size;
|
||||
*/
|
||||
static int __init early_parse_fbmem(char *p)
|
||||
{
|
||||
int ret;
|
||||
unsigned long align;
|
||||
|
||||
fbmem_size = memparse(p, &p);
|
||||
if (*p == '@')
|
||||
if (*p == '@') {
|
||||
fbmem_start = memparse(p, &p);
|
||||
ret = add_reserved_region(fbmem_start,
|
||||
fbmem_start + fbmem_size - 1,
|
||||
"Framebuffer");
|
||||
if (ret) {
|
||||
printk(KERN_WARNING
|
||||
"Failed to reserve framebuffer memory\n");
|
||||
fbmem_start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fbmem_start) {
|
||||
if ((fbmem_size & 0x000fffffUL) == 0)
|
||||
align = 0x100000; /* 1 MiB */
|
||||
else if ((fbmem_size & 0x0000ffffUL) == 0)
|
||||
align = 0x10000; /* 64 KiB */
|
||||
else
|
||||
align = 0x1000; /* 4 KiB */
|
||||
|
||||
ret = alloc_reserved_region(&fbmem_start, fbmem_size,
|
||||
align, "Framebuffer");
|
||||
if (ret) {
|
||||
printk(KERN_WARNING
|
||||
"Failed to allocate framebuffer memory\n");
|
||||
fbmem_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("fbmem", early_parse_fbmem);
|
||||
|
||||
static inline void __init resource_init(void)
|
||||
{
|
||||
struct tag_mem_range *region;
|
||||
|
||||
kernel_code.start = __pa(init_mm.start_code);
|
||||
kernel_code.end = __pa(init_mm.end_code - 1);
|
||||
kernel_data.start = __pa(init_mm.end_code);
|
||||
kernel_data.end = __pa(init_mm.brk - 1);
|
||||
|
||||
for (region = mem_phys; region; region = region->next) {
|
||||
struct resource *res;
|
||||
unsigned long phys_start, phys_end;
|
||||
|
||||
if (region->size == 0)
|
||||
continue;
|
||||
|
||||
phys_start = region->addr;
|
||||
phys_end = phys_start + region->size - 1;
|
||||
|
||||
res = alloc_bootmem_low(sizeof(*res));
|
||||
res->name = "System RAM";
|
||||
res->start = phys_start;
|
||||
res->end = phys_end;
|
||||
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
||||
|
||||
request_resource (&iomem_resource, res);
|
||||
|
||||
if (kernel_code.start >= res->start &&
|
||||
kernel_code.end <= res->end)
|
||||
request_resource (res, &kernel_code);
|
||||
if (kernel_data.start >= res->start &&
|
||||
kernel_data.end <= res->end)
|
||||
request_resource (res, &kernel_data);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init parse_tag_core(struct tag *tag)
|
||||
{
|
||||
if (tag->hdr.size > 2) {
|
||||
@ -157,11 +291,9 @@ static int __init parse_tag_core(struct tag *tag)
|
||||
}
|
||||
__tagtable(ATAG_CORE, parse_tag_core);
|
||||
|
||||
static int __init parse_tag_mem_range(struct tag *tag,
|
||||
struct tag_mem_range **root)
|
||||
static int __init parse_tag_mem(struct tag *tag)
|
||||
{
|
||||
struct tag_mem_range *cur, **pprev;
|
||||
struct tag_mem_range *new;
|
||||
unsigned long start, end;
|
||||
|
||||
/*
|
||||
* Ignore zero-sized entries. If we're running standalone, the
|
||||
@ -171,34 +303,53 @@ static int __init parse_tag_mem_range(struct tag *tag,
|
||||
if (tag->u.mem_range.size == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Copy the data so the bootmem init code doesn't need to care
|
||||
* about it.
|
||||
*/
|
||||
if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache))
|
||||
panic("Physical memory map too complex!\n");
|
||||
start = tag->u.mem_range.addr;
|
||||
end = tag->u.mem_range.addr + tag->u.mem_range.size - 1;
|
||||
|
||||
new = &mem_range_cache[mem_range_next_free++];
|
||||
*new = tag->u.mem_range;
|
||||
add_physical_memory(start, end);
|
||||
return 0;
|
||||
}
|
||||
__tagtable(ATAG_MEM, parse_tag_mem);
|
||||
|
||||
pprev = root;
|
||||
cur = *root;
|
||||
while (cur) {
|
||||
pprev = &cur->next;
|
||||
cur = cur->next;
|
||||
static int __init parse_tag_rdimg(struct tag *tag)
|
||||
{
|
||||
#ifdef CONFIG_INITRD
|
||||
struct tag_mem_range *mem = &tag->u.mem_range;
|
||||
int ret;
|
||||
|
||||
if (initrd_start) {
|
||||
printk(KERN_WARNING
|
||||
"Warning: Only the first initrd image will be used\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pprev = new;
|
||||
new->next = NULL;
|
||||
ret = add_reserved_region(mem->start, mem->start + mem->size - 1,
|
||||
"initrd");
|
||||
if (ret) {
|
||||
printk(KERN_WARNING
|
||||
"Warning: Failed to reserve initrd memory\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
initrd_start = (unsigned long)__va(mem->addr);
|
||||
initrd_end = initrd_start + mem->size;
|
||||
#else
|
||||
printk(KERN_WARNING "RAM disk image present, but "
|
||||
"no initrd support in kernel, ignoring\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
__tagtable(ATAG_RDIMG, parse_tag_rdimg);
|
||||
|
||||
static int __init parse_tag_mem(struct tag *tag)
|
||||
static int __init parse_tag_rsvd_mem(struct tag *tag)
|
||||
{
|
||||
return parse_tag_mem_range(tag, &mem_phys);
|
||||
struct tag_mem_range *mem = &tag->u.mem_range;
|
||||
|
||||
return add_reserved_region(mem->addr, mem->addr + mem->size - 1,
|
||||
"Reserved");
|
||||
}
|
||||
__tagtable(ATAG_MEM, parse_tag_mem);
|
||||
__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem);
|
||||
|
||||
static int __init parse_tag_cmdline(struct tag *tag)
|
||||
{
|
||||
@ -207,12 +358,6 @@ static int __init parse_tag_cmdline(struct tag *tag)
|
||||
}
|
||||
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
|
||||
|
||||
static int __init parse_tag_rdimg(struct tag *tag)
|
||||
{
|
||||
return parse_tag_mem_range(tag, &mem_ramdisk);
|
||||
}
|
||||
__tagtable(ATAG_RDIMG, parse_tag_rdimg);
|
||||
|
||||
static int __init parse_tag_clock(struct tag *tag)
|
||||
{
|
||||
/*
|
||||
@ -223,12 +368,6 @@ static int __init parse_tag_clock(struct tag *tag)
|
||||
}
|
||||
__tagtable(ATAG_CLOCK, parse_tag_clock);
|
||||
|
||||
static int __init parse_tag_rsvd_mem(struct tag *tag)
|
||||
{
|
||||
return parse_tag_mem_range(tag, &mem_reserved);
|
||||
}
|
||||
__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem);
|
||||
|
||||
/*
|
||||
* Scan the tag table for this tag, and call its parse function. The
|
||||
* tag table is built by the linker from all the __tagtable
|
||||
@ -260,10 +399,137 @@ static void __init parse_tags(struct tag *t)
|
||||
t->hdr.tag);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a free memory region large enough for storing the
|
||||
* bootmem bitmap.
|
||||
*/
|
||||
static unsigned long __init
|
||||
find_bootmap_pfn(const struct resource *mem)
|
||||
{
|
||||
unsigned long bootmap_pages, bootmap_len;
|
||||
unsigned long node_pages = PFN_UP(mem->end - mem->start + 1);
|
||||
unsigned long bootmap_start;
|
||||
|
||||
bootmap_pages = bootmem_bootmap_pages(node_pages);
|
||||
bootmap_len = bootmap_pages << PAGE_SHIFT;
|
||||
|
||||
/*
|
||||
* Find a large enough region without reserved pages for
|
||||
* storing the bootmem bitmap. We can take advantage of the
|
||||
* fact that all lists have been sorted.
|
||||
*
|
||||
* We have to check that we don't collide with any reserved
|
||||
* regions, which includes the kernel image and any RAMDISK
|
||||
* images.
|
||||
*/
|
||||
bootmap_start = find_free_region(mem, bootmap_len, PAGE_SIZE);
|
||||
|
||||
return bootmap_start >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
#define MAX_LOWMEM HIGHMEM_START
|
||||
#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM)
|
||||
|
||||
static void __init setup_bootmem(void)
|
||||
{
|
||||
unsigned bootmap_size;
|
||||
unsigned long first_pfn, bootmap_pfn, pages;
|
||||
unsigned long max_pfn, max_low_pfn;
|
||||
unsigned node = 0;
|
||||
struct resource *res;
|
||||
|
||||
printk(KERN_INFO "Physical memory:\n");
|
||||
for (res = system_ram; res; res = res->sibling)
|
||||
printk(" %08x-%08x\n", res->start, res->end);
|
||||
printk(KERN_INFO "Reserved memory:\n");
|
||||
for (res = reserved; res; res = res->sibling)
|
||||
printk(" %08x-%08x: %s\n",
|
||||
res->start, res->end, res->name);
|
||||
|
||||
nodes_clear(node_online_map);
|
||||
|
||||
if (system_ram->sibling)
|
||||
printk(KERN_WARNING "Only using first memory bank\n");
|
||||
|
||||
for (res = system_ram; res; res = NULL) {
|
||||
first_pfn = PFN_UP(res->start);
|
||||
max_low_pfn = max_pfn = PFN_DOWN(res->end + 1);
|
||||
bootmap_pfn = find_bootmap_pfn(res);
|
||||
if (bootmap_pfn > max_pfn)
|
||||
panic("No space for bootmem bitmap!\n");
|
||||
|
||||
if (max_low_pfn > MAX_LOWMEM_PFN) {
|
||||
max_low_pfn = MAX_LOWMEM_PFN;
|
||||
#ifndef CONFIG_HIGHMEM
|
||||
/*
|
||||
* Lowmem is memory that can be addressed
|
||||
* directly through P1/P2
|
||||
*/
|
||||
printk(KERN_WARNING
|
||||
"Node %u: Only %ld MiB of memory will be used.\n",
|
||||
node, MAX_LOWMEM >> 20);
|
||||
printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
|
||||
#else
|
||||
#error HIGHMEM is not supported by AVR32 yet
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the boot-time allocator with low memory only. */
|
||||
bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn,
|
||||
first_pfn, max_low_pfn);
|
||||
|
||||
/*
|
||||
* Register fully available RAM pages with the bootmem
|
||||
* allocator.
|
||||
*/
|
||||
pages = max_low_pfn - first_pfn;
|
||||
free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn),
|
||||
PFN_PHYS(pages));
|
||||
|
||||
/* Reserve space for the bootmem bitmap... */
|
||||
reserve_bootmem_node(NODE_DATA(node),
|
||||
PFN_PHYS(bootmap_pfn),
|
||||
bootmap_size);
|
||||
|
||||
/* ...and any other reserved regions. */
|
||||
for (res = reserved; res; res = res->sibling) {
|
||||
if (res->start > PFN_PHYS(max_pfn))
|
||||
break;
|
||||
|
||||
/*
|
||||
* resource_init will complain about partial
|
||||
* overlaps, so we'll just ignore such
|
||||
* resources for now.
|
||||
*/
|
||||
if (res->start >= PFN_PHYS(first_pfn)
|
||||
&& res->end < PFN_PHYS(max_pfn))
|
||||
reserve_bootmem_node(
|
||||
NODE_DATA(node), res->start,
|
||||
res->end - res->start + 1);
|
||||
}
|
||||
|
||||
node_set_online(node);
|
||||
}
|
||||
}
|
||||
|
||||
void __init setup_arch (char **cmdline_p)
|
||||
{
|
||||
struct clk *cpu_clk;
|
||||
|
||||
init_mm.start_code = (unsigned long)_text;
|
||||
init_mm.end_code = (unsigned long)_etext;
|
||||
init_mm.end_data = (unsigned long)_edata;
|
||||
init_mm.brk = (unsigned long)_end;
|
||||
|
||||
/*
|
||||
* Include .init section to make allocations easier. It will
|
||||
* be removed before the resource is actually requested.
|
||||
*/
|
||||
kernel_code.start = __pa(__init_begin);
|
||||
kernel_code.end = __pa(init_mm.end_code - 1);
|
||||
kernel_data.start = __pa(init_mm.end_code);
|
||||
kernel_data.end = __pa(init_mm.brk - 1);
|
||||
|
||||
parse_tags(bootloader_tags);
|
||||
|
||||
setup_processor();
|
||||
@ -289,24 +555,16 @@ void __init setup_arch (char **cmdline_p)
|
||||
((cpu_hz + 500) / 1000) % 1000);
|
||||
}
|
||||
|
||||
init_mm.start_code = (unsigned long) &_text;
|
||||
init_mm.end_code = (unsigned long) &_etext;
|
||||
init_mm.end_data = (unsigned long) &_edata;
|
||||
init_mm.brk = (unsigned long) &_end;
|
||||
|
||||
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
|
||||
*cmdline_p = command_line;
|
||||
parse_early_param();
|
||||
|
||||
setup_bootmem();
|
||||
|
||||
board_setup_fbmem(fbmem_start, fbmem_size);
|
||||
|
||||
#ifdef CONFIG_VT
|
||||
conswitchp = &dummy_con;
|
||||
#endif
|
||||
|
||||
paging_init();
|
||||
|
||||
resource_init();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2006 Atmel Corporation
|
||||
* Copyright (C) 2004-2007 Atmel Corporation
|
||||
*
|
||||
* Based on MIPS implementation arch/mips/kernel/time.c
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
@ -20,18 +20,25 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
static cycle_t read_cycle_count(void)
|
||||
/* how many counter cycles in a jiffy? */
|
||||
static u32 cycles_per_jiffy;
|
||||
|
||||
/* the count value for the next timer interrupt */
|
||||
static u32 expirelo;
|
||||
|
||||
cycle_t __weak read_cycle_count(void)
|
||||
{
|
||||
return (cycle_t)sysreg_read(COUNT);
|
||||
}
|
||||
|
||||
static struct clocksource clocksource_avr32 = {
|
||||
struct clocksource __weak clocksource_avr32 = {
|
||||
.name = "avr32",
|
||||
.rating = 350,
|
||||
.read = read_cycle_count,
|
||||
@ -40,12 +47,20 @@ static struct clocksource clocksource_avr32 = {
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
irqreturn_t __weak timer_interrupt(int irq, void *dev_id);
|
||||
|
||||
struct irqaction timer_irqaction = {
|
||||
.handler = timer_interrupt,
|
||||
.flags = IRQF_DISABLED,
|
||||
.name = "timer",
|
||||
};
|
||||
|
||||
/*
|
||||
* By default we provide the null RTC ops
|
||||
*/
|
||||
static unsigned long null_rtc_get_time(void)
|
||||
{
|
||||
return mktime(2004, 1, 1, 0, 0, 0);
|
||||
return mktime(2007, 1, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
static int null_rtc_set_time(unsigned long sec)
|
||||
@ -56,23 +71,14 @@ static int null_rtc_set_time(unsigned long sec)
|
||||
static unsigned long (*rtc_get_time)(void) = null_rtc_get_time;
|
||||
static int (*rtc_set_time)(unsigned long) = null_rtc_set_time;
|
||||
|
||||
/* how many counter cycles in a jiffy? */
|
||||
static unsigned long cycles_per_jiffy;
|
||||
|
||||
/* cycle counter value at the previous timer interrupt */
|
||||
static unsigned int timerhi, timerlo;
|
||||
|
||||
/* the count value for the next timer interrupt */
|
||||
static unsigned int expirelo;
|
||||
|
||||
static void avr32_timer_ack(void)
|
||||
{
|
||||
unsigned int count;
|
||||
u32 count;
|
||||
|
||||
/* Ack this timer interrupt and set the next one */
|
||||
expirelo += cycles_per_jiffy;
|
||||
/* setting COMPARE to 0 stops the COUNT-COMPARE */
|
||||
if (expirelo == 0) {
|
||||
printk(KERN_DEBUG "expirelo == 0\n");
|
||||
sysreg_write(COMPARE, expirelo + 1);
|
||||
} else {
|
||||
sysreg_write(COMPARE, expirelo);
|
||||
@ -86,27 +92,56 @@ static void avr32_timer_ack(void)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int avr32_hpt_read(void)
|
||||
int __weak avr32_hpt_init(void)
|
||||
{
|
||||
return sysreg_read(COUNT);
|
||||
int ret;
|
||||
unsigned long mult, shift, count_hz;
|
||||
|
||||
count_hz = clk_get_rate(boot_cpu_data.clk);
|
||||
shift = clocksource_avr32.shift;
|
||||
mult = clocksource_hz2mult(count_hz, shift);
|
||||
clocksource_avr32.mult = mult;
|
||||
|
||||
{
|
||||
u64 tmp;
|
||||
|
||||
tmp = TICK_NSEC;
|
||||
tmp <<= shift;
|
||||
tmp += mult / 2;
|
||||
do_div(tmp, mult);
|
||||
|
||||
cycles_per_jiffy = tmp;
|
||||
}
|
||||
|
||||
ret = setup_irq(0, &timer_irqaction);
|
||||
if (ret) {
|
||||
pr_debug("timer: could not request IRQ 0: %d\n", ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "timer: AT32AP COUNT-COMPARE at irq 0, "
|
||||
"%lu.%03lu MHz\n",
|
||||
((count_hz + 500) / 1000) / 1000,
|
||||
((count_hz + 500) / 1000) % 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Taken from MIPS c0_hpt_timer_init().
|
||||
*
|
||||
* Why is it so complicated, and what is "count"? My assumption is
|
||||
* that `count' specifies the "reference cycle", i.e. the cycle since
|
||||
* reset that should mean "zero". The reason COUNT is written twice is
|
||||
* probably to make sure we don't get any timer interrupts while we
|
||||
* are messing with the counter.
|
||||
* The reason COUNT is written twice is probably to make sure we don't get any
|
||||
* timer interrupts while we are messing with the counter.
|
||||
*/
|
||||
static void avr32_hpt_init(unsigned int count)
|
||||
int __weak avr32_hpt_start(void)
|
||||
{
|
||||
count = sysreg_read(COUNT) - count;
|
||||
u32 count = sysreg_read(COUNT);
|
||||
expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy;
|
||||
sysreg_write(COUNT, expirelo - cycles_per_jiffy);
|
||||
sysreg_write(COMPARE, expirelo);
|
||||
sysreg_write(COUNT, count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -115,26 +150,18 @@ static void avr32_hpt_init(unsigned int count)
|
||||
*
|
||||
* In UP mode, it is invoked from the (global) timer_interrupt.
|
||||
*/
|
||||
static void local_timer_interrupt(int irq, void *dev_id)
|
||||
void local_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
if (current->pid)
|
||||
profile_tick(CPU_PROFILING);
|
||||
update_process_times(user_mode(get_irq_regs()));
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
timer_interrupt(int irq, void *dev_id)
|
||||
irqreturn_t __weak timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
/* ack timer interrupt and try to set next interrupt */
|
||||
count = avr32_hpt_read();
|
||||
avr32_timer_ack();
|
||||
|
||||
/* Update timerhi/timerlo for intra-jiffy calibration */
|
||||
timerhi += count < timerlo; /* Wrap around */
|
||||
timerlo = count;
|
||||
|
||||
/*
|
||||
* Call the generic timer interrupt handler
|
||||
*/
|
||||
@ -153,60 +180,37 @@ timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction timer_irqaction = {
|
||||
.handler = timer_interrupt,
|
||||
.flags = IRQF_DISABLED,
|
||||
.name = "timer",
|
||||
};
|
||||
|
||||
void __init time_init(void)
|
||||
{
|
||||
unsigned long mult, shift, count_hz;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Make sure we don't get any COMPARE interrupts before we can
|
||||
* handle them.
|
||||
*/
|
||||
sysreg_write(COMPARE, 0);
|
||||
|
||||
xtime.tv_sec = rtc_get_time();
|
||||
xtime.tv_nsec = 0;
|
||||
|
||||
set_normalized_timespec(&wall_to_monotonic,
|
||||
-xtime.tv_sec, -xtime.tv_nsec);
|
||||
|
||||
printk("Before time_init: count=%08lx, compare=%08lx\n",
|
||||
(unsigned long)sysreg_read(COUNT),
|
||||
(unsigned long)sysreg_read(COMPARE));
|
||||
|
||||
count_hz = clk_get_rate(boot_cpu_data.clk);
|
||||
shift = clocksource_avr32.shift;
|
||||
mult = clocksource_hz2mult(count_hz, shift);
|
||||
clocksource_avr32.mult = mult;
|
||||
|
||||
printk("Cycle counter: mult=%lu, shift=%lu\n", mult, shift);
|
||||
|
||||
{
|
||||
u64 tmp;
|
||||
|
||||
tmp = TICK_NSEC;
|
||||
tmp <<= shift;
|
||||
tmp += mult / 2;
|
||||
do_div(tmp, mult);
|
||||
|
||||
cycles_per_jiffy = tmp;
|
||||
ret = avr32_hpt_init();
|
||||
if (ret) {
|
||||
pr_debug("timer: failed setup: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This sets up the high precision timer for the first interrupt. */
|
||||
avr32_hpt_init(avr32_hpt_read());
|
||||
|
||||
printk("After time_init: count=%08lx, compare=%08lx\n",
|
||||
(unsigned long)sysreg_read(COUNT),
|
||||
(unsigned long)sysreg_read(COMPARE));
|
||||
|
||||
ret = clocksource_register(&clocksource_avr32);
|
||||
if (ret)
|
||||
printk(KERN_ERR
|
||||
"timer: could not register clocksource: %d\n", ret);
|
||||
pr_debug("timer: could not register clocksource: %d\n", ret);
|
||||
|
||||
ret = setup_irq(0, &timer_irqaction);
|
||||
if (ret)
|
||||
printk("timer: could not request IRQ 0: %d\n", ret);
|
||||
ret = avr32_hpt_start();
|
||||
if (ret) {
|
||||
pr_debug("timer: failed starting: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static struct sysdev_class timer_class = {
|
||||
|
@ -5,158 +5,25 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#undef DEBUG
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/traps.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/ocd.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
|
||||
{
|
||||
unsigned long p;
|
||||
int i;
|
||||
|
||||
printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
|
||||
|
||||
for (p = bottom & ~31; p < top; ) {
|
||||
printk("%04lx: ", p & 0xffff);
|
||||
|
||||
for (i = 0; i < 8; i++, p += 4) {
|
||||
unsigned int val;
|
||||
|
||||
if (p < bottom || p >= top)
|
||||
printk(" ");
|
||||
else {
|
||||
if (__get_user(val, (unsigned int __user *)p)) {
|
||||
printk("\n");
|
||||
goto out;
|
||||
}
|
||||
printk("%08x ", val);
|
||||
}
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p)
|
||||
{
|
||||
return (p > (unsigned long)tinfo)
|
||||
&& (p < (unsigned long)tinfo + THREAD_SIZE - 3);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long lr, fp;
|
||||
struct thread_info *tinfo;
|
||||
|
||||
tinfo = (struct thread_info *)
|
||||
((unsigned long)sp & ~(THREAD_SIZE - 1));
|
||||
|
||||
if (regs)
|
||||
fp = regs->r7;
|
||||
else if (tsk == current)
|
||||
asm("mov %0, r7" : "=r"(fp));
|
||||
else
|
||||
fp = tsk->thread.cpu_context.r7;
|
||||
|
||||
/*
|
||||
* Walk the stack as long as the frame pointer (a) is within
|
||||
* the kernel stack of the task, and (b) it doesn't move
|
||||
* downwards.
|
||||
*/
|
||||
while (valid_stack_ptr(tinfo, fp)) {
|
||||
unsigned long new_fp;
|
||||
|
||||
lr = *(unsigned long *)fp;
|
||||
printk(" [<%08lx>] ", lr);
|
||||
print_symbol("%s\n", lr);
|
||||
|
||||
new_fp = *(unsigned long *)(fp + 4);
|
||||
if (new_fp <= fp)
|
||||
break;
|
||||
fp = new_fp;
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
#else
|
||||
static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
while (!kstack_end(sp)) {
|
||||
addr = *sp++;
|
||||
if (kernel_text_address(addr)) {
|
||||
printk(" [<%08lx>] ", addr);
|
||||
print_symbol("%s\n", addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void show_trace(struct task_struct *tsk, unsigned long *sp,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
if (regs &&
|
||||
(((regs->sr & MODE_MASK) == MODE_EXCEPTION) ||
|
||||
((regs->sr & MODE_MASK) == MODE_USER)))
|
||||
return;
|
||||
|
||||
printk ("Call trace:");
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
printk("\n");
|
||||
#endif
|
||||
|
||||
__show_trace(tsk, sp, regs);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
void show_stack(struct task_struct *tsk, unsigned long *sp)
|
||||
{
|
||||
unsigned long stack;
|
||||
|
||||
if (!tsk)
|
||||
tsk = current;
|
||||
if (sp == 0) {
|
||||
if (tsk == current) {
|
||||
register unsigned long *real_sp __asm__("sp");
|
||||
sp = real_sp;
|
||||
} else {
|
||||
sp = (unsigned long *)tsk->thread.cpu_context.ksp;
|
||||
}
|
||||
}
|
||||
|
||||
stack = (unsigned long)sp;
|
||||
dump_mem("Stack: ", stack,
|
||||
THREAD_SIZE + (unsigned long)tsk->thread_info);
|
||||
show_trace(tsk, sp, NULL);
|
||||
}
|
||||
|
||||
void dump_stack(void)
|
||||
{
|
||||
show_stack(NULL, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(dump_stack);
|
||||
#include <asm/ocd.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
ATOMIC_NOTIFIER_HEAD(avr32_die_chain);
|
||||
|
||||
int register_die_notifier(struct notifier_block *nb)
|
||||
{
|
||||
pr_debug("register_die_notifier: %p\n", nb);
|
||||
|
||||
return atomic_notifier_chain_register(&avr32_die_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL(register_die_notifier);
|
||||
@ -169,93 +36,103 @@ EXPORT_SYMBOL(unregister_die_notifier);
|
||||
|
||||
static DEFINE_SPINLOCK(die_lock);
|
||||
|
||||
void __die(const char *str, struct pt_regs *regs, unsigned long err,
|
||||
const char *file, const char *func, unsigned long line)
|
||||
void NORET_TYPE die(const char *str, struct pt_regs *regs, long err)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
static int die_counter;
|
||||
|
||||
console_verbose();
|
||||
spin_lock_irq(&die_lock);
|
||||
bust_spinlocks(1);
|
||||
|
||||
printk(KERN_ALERT "%s", str);
|
||||
if (file && func)
|
||||
printk(" in %s:%s, line %ld", file, func, line);
|
||||
printk("[#%d]:\n", ++die_counter);
|
||||
print_modules();
|
||||
show_regs(regs);
|
||||
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
|
||||
tsk->comm, tsk->pid, tsk->thread_info + 1);
|
||||
|
||||
if (!user_mode(regs) || in_interrupt()) {
|
||||
dump_mem("Stack: ", regs->sp,
|
||||
THREAD_SIZE + (unsigned long)tsk->thread_info);
|
||||
printk(KERN_ALERT "Oops: %s, sig: %ld [#%d]\n" KERN_EMERG,
|
||||
str, err, ++die_counter);
|
||||
#ifdef CONFIG_PREEMPT
|
||||
printk("PREEMPT ");
|
||||
#endif
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
printk("FRAME_POINTER ");
|
||||
#endif
|
||||
if (current_cpu_data.features & AVR32_FEATURE_OCD) {
|
||||
unsigned long did = __mfdr(DBGREG_DID);
|
||||
printk("chip: 0x%03lx:0x%04lx rev %lu\n",
|
||||
(did >> 1) & 0x7ff,
|
||||
(did >> 12) & 0x7fff,
|
||||
(did >> 28) & 0xf);
|
||||
} else {
|
||||
printk("cpu: arch %u r%u / core %u r%u\n",
|
||||
current_cpu_data.arch_type,
|
||||
current_cpu_data.arch_revision,
|
||||
current_cpu_data.cpu_type,
|
||||
current_cpu_data.cpu_revision);
|
||||
}
|
||||
|
||||
print_modules();
|
||||
show_regs_log_lvl(regs, KERN_EMERG);
|
||||
show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG);
|
||||
bust_spinlocks(0);
|
||||
spin_unlock_irq(&die_lock);
|
||||
do_exit(SIGSEGV);
|
||||
|
||||
if (in_interrupt())
|
||||
panic("Fatal exception in interrupt");
|
||||
|
||||
if (panic_on_oops)
|
||||
panic("Fatal exception");
|
||||
|
||||
do_exit(err);
|
||||
}
|
||||
|
||||
void __die_if_kernel(const char *str, struct pt_regs *regs, unsigned long err,
|
||||
const char *file, const char *func, unsigned long line)
|
||||
void _exception(long signr, struct pt_regs *regs, int code,
|
||||
unsigned long addr)
|
||||
{
|
||||
siginfo_t info;
|
||||
|
||||
if (!user_mode(regs))
|
||||
__die(str, regs, err, file, func, line);
|
||||
die("Unhandled exception in kernel mode", regs, signr);
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.si_signo = signr;
|
||||
info.si_code = code;
|
||||
info.si_addr = (void __user *)addr;
|
||||
force_sig_info(signr, &info, current);
|
||||
|
||||
/*
|
||||
* Init gets no signals that it doesn't have a handler for.
|
||||
* That's all very well, but if it has caused a synchronous
|
||||
* exception and we ignore the resulting signal, it will just
|
||||
* generate the same exception over and over again and we get
|
||||
* nowhere. Better to kill it and let the kernel panic.
|
||||
*/
|
||||
if (is_init(current)) {
|
||||
__sighandler_t handler;
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
handler = current->sighand->action[signr-1].sa.sa_handler;
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
if (handler == SIG_DFL) {
|
||||
/* init has generated a synchronous exception
|
||||
and it doesn't have a handler for the signal */
|
||||
printk(KERN_CRIT "init has generated signal %ld "
|
||||
"but has no handler for it\n", signr);
|
||||
do_exit(signr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_SUBARCH_AVR32B
|
||||
/*
|
||||
* The exception entry always saves RSR_EX. For NMI, this is
|
||||
* wrong; it should be RSR_NMI
|
||||
*/
|
||||
regs->sr = sysreg_read(RSR_NMI);
|
||||
#endif
|
||||
|
||||
printk("NMI taken!!!!\n");
|
||||
die("NMI", regs, ecr);
|
||||
BUG();
|
||||
printk(KERN_ALERT "Got Non-Maskable Interrupt, dumping regs\n");
|
||||
show_regs_log_lvl(regs, KERN_ALERT);
|
||||
show_stack_log_lvl(current, regs->sp, regs, KERN_ALERT);
|
||||
}
|
||||
|
||||
asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs)
|
||||
{
|
||||
printk("Unable to handle critical exception %lu at pc = %08lx!\n",
|
||||
ecr, regs->pc);
|
||||
die("Oops", regs, ecr);
|
||||
BUG();
|
||||
die("Critical exception", regs, SIGKILL);
|
||||
}
|
||||
|
||||
asmlinkage void do_address_exception(unsigned long ecr, struct pt_regs *regs)
|
||||
{
|
||||
siginfo_t info;
|
||||
|
||||
die_if_kernel("Oops: Address exception in kernel mode", regs, ecr);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ecr == ECR_ADDR_ALIGN_X)
|
||||
pr_debug("Instruction Address Exception at pc = %08lx\n",
|
||||
regs->pc);
|
||||
else if (ecr == ECR_ADDR_ALIGN_R)
|
||||
pr_debug("Data Address Exception (Read) at pc = %08lx\n",
|
||||
regs->pc);
|
||||
else if (ecr == ECR_ADDR_ALIGN_W)
|
||||
pr_debug("Data Address Exception (Write) at pc = %08lx\n",
|
||||
regs->pc);
|
||||
else
|
||||
BUG();
|
||||
|
||||
show_regs(regs);
|
||||
#endif
|
||||
|
||||
info.si_signo = SIGBUS;
|
||||
info.si_errno = 0;
|
||||
info.si_code = BUS_ADRALN;
|
||||
info.si_addr = (void __user *)regs->pc;
|
||||
|
||||
force_sig_info(SIGBUS, &info, current);
|
||||
_exception(SIGBUS, regs, BUS_ADRALN, regs->pc);
|
||||
}
|
||||
|
||||
/* This way of handling undefined instructions is stolen from ARM */
|
||||
@ -280,7 +157,8 @@ static int do_cop_absent(u32 insn)
|
||||
{
|
||||
int cop_nr;
|
||||
u32 cpucr;
|
||||
if ( (insn & 0xfdf00000) == 0xf1900000 )
|
||||
|
||||
if ((insn & 0xfdf00000) == 0xf1900000)
|
||||
/* LDC0 */
|
||||
cop_nr = 0;
|
||||
else
|
||||
@ -292,136 +170,91 @@ static int do_cop_absent(u32 insn)
|
||||
sysreg_write(CPUCR, cpucr);
|
||||
|
||||
cpucr = sysreg_read(CPUCR);
|
||||
if ( !(cpucr & (1 << (24 + cop_nr))) ){
|
||||
printk("Coprocessor #%i not found!\n", cop_nr);
|
||||
return -1;
|
||||
}
|
||||
if (!(cpucr & (1 << (24 + cop_nr))))
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||
static inline void do_bug_verbose(struct pt_regs *regs, u32 insn)
|
||||
int is_valid_bugaddr(unsigned long pc)
|
||||
{
|
||||
char *file;
|
||||
u16 line;
|
||||
char c;
|
||||
unsigned short opcode;
|
||||
|
||||
if (__get_user(line, (u16 __user *)(regs->pc + 2)))
|
||||
return;
|
||||
if (__get_user(file, (char * __user *)(regs->pc + 4))
|
||||
|| (unsigned long)file < PAGE_OFFSET
|
||||
|| __get_user(c, file))
|
||||
file = "<bad filename>";
|
||||
if (pc < PAGE_OFFSET)
|
||||
return 0;
|
||||
if (probe_kernel_address((u16 *)pc, opcode))
|
||||
return 0;
|
||||
|
||||
printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line);
|
||||
return opcode == AVR32_BUG_OPCODE;
|
||||
}
|
||||
#else
|
||||
static inline void do_bug_verbose(struct pt_regs *regs, u32 insn)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs)
|
||||
{
|
||||
u32 insn;
|
||||
struct undef_hook *hook;
|
||||
siginfo_t info;
|
||||
void __user *pc;
|
||||
long code;
|
||||
|
||||
if (!user_mode(regs))
|
||||
goto kernel_trap;
|
||||
if (!user_mode(regs) && (ecr == ECR_ILLEGAL_OPCODE)) {
|
||||
enum bug_trap_type type;
|
||||
|
||||
type = report_bug(regs->pc);
|
||||
switch (type) {
|
||||
case BUG_TRAP_TYPE_NONE:
|
||||
break;
|
||||
case BUG_TRAP_TYPE_WARN:
|
||||
regs->pc += 2;
|
||||
return;
|
||||
case BUG_TRAP_TYPE_BUG:
|
||||
die("Kernel BUG", regs, SIGKILL);
|
||||
}
|
||||
}
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
pc = (void __user *)instruction_pointer(regs);
|
||||
if (__get_user(insn, (u32 __user *)pc))
|
||||
goto invalid_area;
|
||||
if (user_mode(regs)) {
|
||||
pc = (void __user *)instruction_pointer(regs);
|
||||
if (get_user(insn, (u32 __user *)pc))
|
||||
goto invalid_area;
|
||||
|
||||
if (ecr == ECR_COPROC_ABSENT) {
|
||||
if (do_cop_absent(insn) == 0)
|
||||
if (ecr == ECR_COPROC_ABSENT && !do_cop_absent(insn))
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irq(&undef_lock);
|
||||
list_for_each_entry(hook, &undef_hook, node) {
|
||||
if ((insn & hook->insn_mask) == hook->insn_val) {
|
||||
if (hook->fn(regs, insn) == 0) {
|
||||
spin_unlock_irq(&undef_lock);
|
||||
return;
|
||||
spin_lock_irq(&undef_lock);
|
||||
list_for_each_entry(hook, &undef_hook, node) {
|
||||
if ((insn & hook->insn_mask) == hook->insn_val) {
|
||||
if (hook->fn(regs, insn) == 0) {
|
||||
spin_unlock_irq(&undef_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&undef_lock);
|
||||
}
|
||||
spin_unlock_irq(&undef_lock);
|
||||
|
||||
invalid_area:
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("Illegal instruction at pc = %08lx\n", regs->pc);
|
||||
if (regs->pc < TASK_SIZE) {
|
||||
unsigned long ptbr, pgd, pte, *p;
|
||||
|
||||
ptbr = sysreg_read(PTBR);
|
||||
p = (unsigned long *)ptbr;
|
||||
pgd = p[regs->pc >> 22];
|
||||
p = (unsigned long *)((pgd & 0x1ffff000) | 0x80000000);
|
||||
pte = p[(regs->pc >> 12) & 0x3ff];
|
||||
printk("page table: 0x%08lx -> 0x%08lx -> 0x%08lx\n", ptbr, pgd, pte);
|
||||
}
|
||||
#endif
|
||||
|
||||
info.si_signo = SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_addr = (void __user *)regs->pc;
|
||||
switch (ecr) {
|
||||
case ECR_ILLEGAL_OPCODE:
|
||||
case ECR_UNIMPL_INSTRUCTION:
|
||||
info.si_code = ILL_ILLOPC;
|
||||
break;
|
||||
case ECR_PRIVILEGE_VIOLATION:
|
||||
info.si_code = ILL_PRVOPC;
|
||||
code = ILL_PRVOPC;
|
||||
break;
|
||||
case ECR_COPROC_ABSENT:
|
||||
info.si_code = ILL_COPROC;
|
||||
code = ILL_COPROC;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
code = ILL_ILLOPC;
|
||||
break;
|
||||
}
|
||||
|
||||
force_sig_info(SIGILL, &info, current);
|
||||
_exception(SIGILL, regs, code, regs->pc);
|
||||
return;
|
||||
|
||||
kernel_trap:
|
||||
#ifdef CONFIG_BUG
|
||||
if (__kernel_text_address(instruction_pointer(regs))) {
|
||||
insn = *(u16 *)instruction_pointer(regs);
|
||||
if (insn == AVR32_BUG_OPCODE) {
|
||||
do_bug_verbose(regs, insn);
|
||||
die("Kernel BUG", regs, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
die("Oops: Illegal instruction in kernel code", regs, ecr);
|
||||
invalid_area:
|
||||
_exception(SIGSEGV, regs, SEGV_MAPERR, regs->pc);
|
||||
}
|
||||
|
||||
asmlinkage void do_fpe(unsigned long ecr, struct pt_regs *regs)
|
||||
{
|
||||
siginfo_t info;
|
||||
|
||||
printk("Floating-point exception at pc = %08lx\n", regs->pc);
|
||||
|
||||
/* We have no FPU... */
|
||||
info.si_signo = SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_addr = (void __user *)regs->pc;
|
||||
info.si_code = ILL_COPROC;
|
||||
|
||||
force_sig_info(SIGILL, &info, current);
|
||||
/* We have no FPU yet */
|
||||
_exception(SIGILL, regs, ILL_COPROC, regs->pc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,6 +26,12 @@ SECTIONS
|
||||
_sinittext = .;
|
||||
*(.text.reset)
|
||||
*(.init.text)
|
||||
/*
|
||||
* .exit.text is discarded at runtime, not
|
||||
* link time, to deal with references from
|
||||
* __bug_table
|
||||
*/
|
||||
*(.exit.text)
|
||||
_einittext = .;
|
||||
. = ALIGN(4);
|
||||
__tagtable_begin = .;
|
||||
@ -86,6 +92,8 @@ SECTIONS
|
||||
__stop___ex_table = .;
|
||||
}
|
||||
|
||||
BUG_TABLE
|
||||
|
||||
RODATA
|
||||
|
||||
. = ALIGN(8192);
|
||||
@ -126,7 +134,6 @@ SECTIONS
|
||||
* thrown away, as cleanup code is never called unless it's a module.
|
||||
*/
|
||||
/DISCARD/ : {
|
||||
*(.exit.text)
|
||||
*(.exit.data)
|
||||
*(.exitcall.exit)
|
||||
}
|
||||
|
31
arch/avr32/mach-at32ap/Kconfig
Normal file
31
arch/avr32/mach-at32ap/Kconfig
Normal file
@ -0,0 +1,31 @@
|
||||
if PLATFORM_AT32AP
|
||||
|
||||
menu "Atmel AVR32 AP options"
|
||||
|
||||
choice
|
||||
prompt "AT32AP7000 static memory bus width"
|
||||
depends on CPU_AT32AP7000
|
||||
default AP7000_16_BIT_SMC
|
||||
help
|
||||
Define the width of the AP7000 external static memory interface.
|
||||
This is used to determine how to mangle the address and/or data
|
||||
when doing little-endian port access.
|
||||
|
||||
The current code can only support a single external memory bus
|
||||
width for all chip selects, excluding the flash (which is using
|
||||
raw access and is thus not affected by any of this.)
|
||||
|
||||
config AP7000_32_BIT_SMC
|
||||
bool "32 bit"
|
||||
|
||||
config AP7000_16_BIT_SMC
|
||||
bool "16 bit"
|
||||
|
||||
config AP7000_8_BIT_SMC
|
||||
bool "8 bit"
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
endif # PLATFORM_AT32AP
|
@ -1,2 +1,3 @@
|
||||
obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o
|
||||
obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o
|
||||
obj-$(CONFIG_CPU_AT32AP7000) += time-tc.o
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <asm/arch/sm.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "hmatrix.h"
|
||||
#include "pio.h"
|
||||
#include "sm.h"
|
||||
|
||||
@ -416,7 +417,15 @@ struct platform_device at32_sm_device = {
|
||||
.resource = sm_resource,
|
||||
.num_resources = ARRAY_SIZE(sm_resource),
|
||||
};
|
||||
DEV_CLK(pclk, at32_sm, pbb, 0);
|
||||
static struct clk at32_sm_pclk = {
|
||||
.name = "pclk",
|
||||
.dev = &at32_sm_device.dev,
|
||||
.parent = &pbb_clk,
|
||||
.mode = pbb_clk_mode,
|
||||
.get_rate = pbb_clk_get_rate,
|
||||
.users = 1,
|
||||
.index = 0,
|
||||
};
|
||||
|
||||
static struct resource intc0_resource[] = {
|
||||
PBMEM(0xfff00400),
|
||||
@ -442,6 +451,7 @@ static struct clk hramc_clk = {
|
||||
.mode = hsb_clk_mode,
|
||||
.get_rate = hsb_clk_get_rate,
|
||||
.users = 1,
|
||||
.index = 3,
|
||||
};
|
||||
|
||||
static struct resource smc0_resource[] = {
|
||||
@ -466,6 +476,57 @@ static struct clk pico_clk = {
|
||||
.users = 1,
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* HMATRIX
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
static struct clk hmatrix_clk = {
|
||||
.name = "hmatrix_clk",
|
||||
.parent = &pbb_clk,
|
||||
.mode = pbb_clk_mode,
|
||||
.get_rate = pbb_clk_get_rate,
|
||||
.index = 2,
|
||||
.users = 1,
|
||||
};
|
||||
#define HMATRIX_BASE ((void __iomem *)0xfff00800)
|
||||
|
||||
#define hmatrix_readl(reg) \
|
||||
__raw_readl((HMATRIX_BASE) + HMATRIX_##reg)
|
||||
#define hmatrix_writel(reg,value) \
|
||||
__raw_writel((value), (HMATRIX_BASE) + HMATRIX_##reg)
|
||||
|
||||
/*
|
||||
* Set bits in the HMATRIX Special Function Register (SFR) used by the
|
||||
* External Bus Interface (EBI). This can be used to enable special
|
||||
* features like CompactFlash support, NAND Flash support, etc. on
|
||||
* certain chipselects.
|
||||
*/
|
||||
static inline void set_ebi_sfr_bits(u32 mask)
|
||||
{
|
||||
u32 sfr;
|
||||
|
||||
clk_enable(&hmatrix_clk);
|
||||
sfr = hmatrix_readl(SFR4);
|
||||
sfr |= mask;
|
||||
hmatrix_writel(SFR4, sfr);
|
||||
clk_disable(&hmatrix_clk);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* System Timer/Counter (TC)
|
||||
* -------------------------------------------------------------------- */
|
||||
static struct resource at32_systc0_resource[] = {
|
||||
PBMEM(0xfff00c00),
|
||||
IRQ(22),
|
||||
};
|
||||
struct platform_device at32_systc0_device = {
|
||||
.name = "systc",
|
||||
.id = 0,
|
||||
.resource = at32_systc0_resource,
|
||||
.num_resources = ARRAY_SIZE(at32_systc0_resource),
|
||||
};
|
||||
DEV_CLK(pclk, at32_systc0, pbb, 3);
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* PIO
|
||||
* -------------------------------------------------------------------- */
|
||||
@ -514,6 +575,8 @@ void __init at32_add_system_devices(void)
|
||||
platform_device_register(&smc0_device);
|
||||
platform_device_register(&pdc_device);
|
||||
|
||||
platform_device_register(&at32_systc0_device);
|
||||
|
||||
platform_device_register(&pio0_device);
|
||||
platform_device_register(&pio1_device);
|
||||
platform_device_register(&pio2_device);
|
||||
@ -950,6 +1013,7 @@ struct clk *at32_clock_list[] = {
|
||||
&pbb_clk,
|
||||
&at32_sm_pclk,
|
||||
&at32_intc0_pclk,
|
||||
&hmatrix_clk,
|
||||
&ebi_clk,
|
||||
&hramc_clk,
|
||||
&smc0_pclk,
|
||||
@ -962,6 +1026,7 @@ struct clk *at32_clock_list[] = {
|
||||
&pio2_mck,
|
||||
&pio3_mck,
|
||||
&pio4_mck,
|
||||
&at32_systc0_pclk,
|
||||
&atmel_usart0_usart,
|
||||
&atmel_usart1_usart,
|
||||
&atmel_usart2_usart,
|
||||
@ -1024,6 +1089,9 @@ void __init at32_clock_init(void)
|
||||
for (i = 0; i < ARRAY_SIZE(at32_clock_list); i++) {
|
||||
struct clk *clk = at32_clock_list[i];
|
||||
|
||||
if (clk->users == 0)
|
||||
continue;
|
||||
|
||||
if (clk->mode == &cpu_clk_mode)
|
||||
cpu_mask |= 1 << clk->index;
|
||||
else if (clk->mode == &hsb_clk_mode)
|
||||
|
182
arch/avr32/mach-at32ap/hmatrix.h
Normal file
182
arch/avr32/mach-at32ap/hmatrix.h
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Register definitions for High-Speed Bus Matrix
|
||||
*/
|
||||
#ifndef __HMATRIX_H
|
||||
#define __HMATRIX_H
|
||||
|
||||
/* HMATRIX register offsets */
|
||||
#define HMATRIX_MCFG0 0x0000
|
||||
#define HMATRIX_MCFG1 0x0004
|
||||
#define HMATRIX_MCFG2 0x0008
|
||||
#define HMATRIX_MCFG3 0x000c
|
||||
#define HMATRIX_MCFG4 0x0010
|
||||
#define HMATRIX_MCFG5 0x0014
|
||||
#define HMATRIX_MCFG6 0x0018
|
||||
#define HMATRIX_MCFG7 0x001c
|
||||
#define HMATRIX_MCFG8 0x0020
|
||||
#define HMATRIX_MCFG9 0x0024
|
||||
#define HMATRIX_MCFG10 0x0028
|
||||
#define HMATRIX_MCFG11 0x002c
|
||||
#define HMATRIX_MCFG12 0x0030
|
||||
#define HMATRIX_MCFG13 0x0034
|
||||
#define HMATRIX_MCFG14 0x0038
|
||||
#define HMATRIX_MCFG15 0x003c
|
||||
#define HMATRIX_SCFG0 0x0040
|
||||
#define HMATRIX_SCFG1 0x0044
|
||||
#define HMATRIX_SCFG2 0x0048
|
||||
#define HMATRIX_SCFG3 0x004c
|
||||
#define HMATRIX_SCFG4 0x0050
|
||||
#define HMATRIX_SCFG5 0x0054
|
||||
#define HMATRIX_SCFG6 0x0058
|
||||
#define HMATRIX_SCFG7 0x005c
|
||||
#define HMATRIX_SCFG8 0x0060
|
||||
#define HMATRIX_SCFG9 0x0064
|
||||
#define HMATRIX_SCFG10 0x0068
|
||||
#define HMATRIX_SCFG11 0x006c
|
||||
#define HMATRIX_SCFG12 0x0070
|
||||
#define HMATRIX_SCFG13 0x0074
|
||||
#define HMATRIX_SCFG14 0x0078
|
||||
#define HMATRIX_SCFG15 0x007c
|
||||
#define HMATRIX_PRAS0 0x0080
|
||||
#define HMATRIX_PRBS0 0x0084
|
||||
#define HMATRIX_PRAS1 0x0088
|
||||
#define HMATRIX_PRBS1 0x008c
|
||||
#define HMATRIX_PRAS2 0x0090
|
||||
#define HMATRIX_PRBS2 0x0094
|
||||
#define HMATRIX_PRAS3 0x0098
|
||||
#define HMATRIX_PRBS3 0x009c
|
||||
#define HMATRIX_PRAS4 0x00a0
|
||||
#define HMATRIX_PRBS4 0x00a4
|
||||
#define HMATRIX_PRAS5 0x00a8
|
||||
#define HMATRIX_PRBS5 0x00ac
|
||||
#define HMATRIX_PRAS6 0x00b0
|
||||
#define HMATRIX_PRBS6 0x00b4
|
||||
#define HMATRIX_PRAS7 0x00b8
|
||||
#define HMATRIX_PRBS7 0x00bc
|
||||
#define HMATRIX_PRAS8 0x00c0
|
||||
#define HMATRIX_PRBS8 0x00c4
|
||||
#define HMATRIX_PRAS9 0x00c8
|
||||
#define HMATRIX_PRBS9 0x00cc
|
||||
#define HMATRIX_PRAS10 0x00d0
|
||||
#define HMATRIX_PRBS10 0x00d4
|
||||
#define HMATRIX_PRAS11 0x00d8
|
||||
#define HMATRIX_PRBS11 0x00dc
|
||||
#define HMATRIX_PRAS12 0x00e0
|
||||
#define HMATRIX_PRBS12 0x00e4
|
||||
#define HMATRIX_PRAS13 0x00e8
|
||||
#define HMATRIX_PRBS13 0x00ec
|
||||
#define HMATRIX_PRAS14 0x00f0
|
||||
#define HMATRIX_PRBS14 0x00f4
|
||||
#define HMATRIX_PRAS15 0x00f8
|
||||
#define HMATRIX_PRBS15 0x00fc
|
||||
#define HMATRIX_MRCR 0x0100
|
||||
#define HMATRIX_SFR0 0x0110
|
||||
#define HMATRIX_SFR1 0x0114
|
||||
#define HMATRIX_SFR2 0x0118
|
||||
#define HMATRIX_SFR3 0x011c
|
||||
#define HMATRIX_SFR4 0x0120
|
||||
#define HMATRIX_SFR5 0x0124
|
||||
#define HMATRIX_SFR6 0x0128
|
||||
#define HMATRIX_SFR7 0x012c
|
||||
#define HMATRIX_SFR8 0x0130
|
||||
#define HMATRIX_SFR9 0x0134
|
||||
#define HMATRIX_SFR10 0x0138
|
||||
#define HMATRIX_SFR11 0x013c
|
||||
#define HMATRIX_SFR12 0x0140
|
||||
#define HMATRIX_SFR13 0x0144
|
||||
#define HMATRIX_SFR14 0x0148
|
||||
#define HMATRIX_SFR15 0x014c
|
||||
|
||||
/* Bitfields in MCFGx */
|
||||
#define HMATRIX_ULBT_OFFSET 0
|
||||
#define HMATRIX_ULBT_SIZE 3
|
||||
|
||||
/* Bitfields in SCFGx */
|
||||
#define HMATRIX_SLOT_CYCLE_OFFSET 0
|
||||
#define HMATRIX_SLOT_CYCLE_SIZE 8
|
||||
#define HMATRIX_DEFMSTR_TYPE_OFFSET 16
|
||||
#define HMATRIX_DEFMSTR_TYPE_SIZE 2
|
||||
#define HMATRIX_FIXED_DEFMSTR_OFFSET 18
|
||||
#define HMATRIX_FIXED_DEFMSTR_SIZE 4
|
||||
#define HMATRIX_ARBT_OFFSET 24
|
||||
#define HMATRIX_ARBT_SIZE 2
|
||||
|
||||
/* Bitfields in PRASx */
|
||||
#define HMATRIX_M0PR_OFFSET 0
|
||||
#define HMATRIX_M0PR_SIZE 4
|
||||
#define HMATRIX_M1PR_OFFSET 4
|
||||
#define HMATRIX_M1PR_SIZE 4
|
||||
#define HMATRIX_M2PR_OFFSET 8
|
||||
#define HMATRIX_M2PR_SIZE 4
|
||||
#define HMATRIX_M3PR_OFFSET 12
|
||||
#define HMATRIX_M3PR_SIZE 4
|
||||
#define HMATRIX_M4PR_OFFSET 16
|
||||
#define HMATRIX_M4PR_SIZE 4
|
||||
#define HMATRIX_M5PR_OFFSET 20
|
||||
#define HMATRIX_M5PR_SIZE 4
|
||||
#define HMATRIX_M6PR_OFFSET 24
|
||||
#define HMATRIX_M6PR_SIZE 4
|
||||
#define HMATRIX_M7PR_OFFSET 28
|
||||
#define HMATRIX_M7PR_SIZE 4
|
||||
|
||||
/* Bitfields in PRBSx */
|
||||
#define HMATRIX_M8PR_OFFSET 0
|
||||
#define HMATRIX_M8PR_SIZE 4
|
||||
#define HMATRIX_M9PR_OFFSET 4
|
||||
#define HMATRIX_M9PR_SIZE 4
|
||||
#define HMATRIX_M10PR_OFFSET 8
|
||||
#define HMATRIX_M10PR_SIZE 4
|
||||
#define HMATRIX_M11PR_OFFSET 12
|
||||
#define HMATRIX_M11PR_SIZE 4
|
||||
#define HMATRIX_M12PR_OFFSET 16
|
||||
#define HMATRIX_M12PR_SIZE 4
|
||||
#define HMATRIX_M13PR_OFFSET 20
|
||||
#define HMATRIX_M13PR_SIZE 4
|
||||
#define HMATRIX_M14PR_OFFSET 24
|
||||
#define HMATRIX_M14PR_SIZE 4
|
||||
#define HMATRIX_M15PR_OFFSET 28
|
||||
#define HMATRIX_M15PR_SIZE 4
|
||||
|
||||
/* Bitfields in SFR4 */
|
||||
#define HMATRIX_CS1A_OFFSET 1
|
||||
#define HMATRIX_CS1A_SIZE 1
|
||||
#define HMATRIX_CS3A_OFFSET 3
|
||||
#define HMATRIX_CS3A_SIZE 1
|
||||
#define HMATRIX_CS4A_OFFSET 4
|
||||
#define HMATRIX_CS4A_SIZE 1
|
||||
#define HMATRIX_CS5A_OFFSET 5
|
||||
#define HMATRIX_CS5A_SIZE 1
|
||||
#define HMATRIX_DBPUC_OFFSET 8
|
||||
#define HMATRIX_DBPUC_SIZE 1
|
||||
|
||||
/* Constants for ULBT */
|
||||
#define HMATRIX_ULBT_INFINITE 0
|
||||
#define HMATRIX_ULBT_SINGLE 1
|
||||
#define HMATRIX_ULBT_FOUR_BEAT 2
|
||||
#define HMATRIX_ULBT_EIGHT_BEAT 3
|
||||
#define HMATRIX_ULBT_SIXTEEN_BEAT 4
|
||||
|
||||
/* Constants for DEFMSTR_TYPE */
|
||||
#define HMATRIX_DEFMSTR_TYPE_NO_DEFAULT 0
|
||||
#define HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT 1
|
||||
#define HMATRIX_DEFMSTR_TYPE_FIXED_DEFAULT 2
|
||||
|
||||
/* Constants for ARBT */
|
||||
#define HMATRIX_ARBT_ROUND_ROBIN 0
|
||||
#define HMATRIX_ARBT_FIXED_PRIORITY 1
|
||||
|
||||
/* Bit manipulation macros */
|
||||
#define HMATRIX_BIT(name) \
|
||||
(1 << HMATRIX_##name##_OFFSET)
|
||||
#define HMATRIX_BF(name,value) \
|
||||
(((value) & ((1 << HMATRIX_##name##_SIZE) - 1)) \
|
||||
<< HMATRIX_##name##_OFFSET)
|
||||
#define HMATRIX_BFEXT(name,value) \
|
||||
(((value) >> HMATRIX_##name##_OFFSET) \
|
||||
& ((1 << HMATRIX_##name##_SIZE) - 1))
|
||||
#define HMATRIX_BFINS(name,value,old) \
|
||||
(((old) & ~(((1 << HMATRIX_##name##_SIZE) - 1) \
|
||||
<< HMATRIX_##name##_OFFSET)) \
|
||||
| HMATRIX_BF(name,value))
|
||||
|
||||
#endif /* __HMATRIX_H */
|
@ -75,12 +75,35 @@ int smc_set_configuration(int cs, const struct smc_config *config)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (config->nwait_mode) {
|
||||
case 0:
|
||||
mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_DISABLED);
|
||||
break;
|
||||
case 1:
|
||||
mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_RESERVED);
|
||||
break;
|
||||
case 2:
|
||||
mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_FROZEN);
|
||||
break;
|
||||
case 3:
|
||||
mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_READY);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (config->tdf_cycles) {
|
||||
mode |= HSMC_BF(TDF_CYCLES, config->tdf_cycles);
|
||||
}
|
||||
|
||||
if (config->nrd_controlled)
|
||||
mode |= HSMC_BIT(READ_MODE);
|
||||
if (config->nwe_controlled)
|
||||
mode |= HSMC_BIT(WRITE_MODE);
|
||||
if (config->byte_write)
|
||||
mode |= HSMC_BIT(BAT);
|
||||
if (config->tdf_mode)
|
||||
mode |= HSMC_BIT(TDF_MODE);
|
||||
|
||||
pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n",
|
||||
cs, setup, pulse, cycle, mode);
|
||||
|
218
arch/avr32/mach-at32ap/time-tc.c
Normal file
218
arch/avr32/mach-at32ap/time-tc.c
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2007 Atmel Corporation
|
||||
*
|
||||
* Based on MIPS implementation arch/mips/kernel/time.c
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#include <asm/arch/time.h>
|
||||
|
||||
/* how many counter cycles in a jiffy? */
|
||||
static u32 cycles_per_jiffy;
|
||||
|
||||
/* the count value for the next timer interrupt */
|
||||
static u32 expirelo;
|
||||
|
||||
/* the I/O registers of the TC module */
|
||||
static void __iomem *ioregs;
|
||||
|
||||
cycle_t read_cycle_count(void)
|
||||
{
|
||||
return (cycle_t)timer_read(ioregs, 0, CV);
|
||||
}
|
||||
|
||||
struct clocksource clocksource_avr32 = {
|
||||
.name = "avr32",
|
||||
.rating = 342,
|
||||
.read = read_cycle_count,
|
||||
.mask = CLOCKSOURCE_MASK(16),
|
||||
.shift = 16,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static void avr32_timer_ack(void)
|
||||
{
|
||||
u16 count = expirelo;
|
||||
|
||||
/* Ack this timer interrupt and set the next one, use a u16
|
||||
* variable so it will wrap around correctly */
|
||||
count += cycles_per_jiffy;
|
||||
expirelo = count;
|
||||
timer_write(ioregs, 0, RC, expirelo);
|
||||
|
||||
/* Check to see if we have missed any timer interrupts */
|
||||
count = timer_read(ioregs, 0, CV);
|
||||
if ((count - expirelo) < 0x7fff) {
|
||||
expirelo = count + cycles_per_jiffy;
|
||||
timer_write(ioregs, 0, RC, expirelo);
|
||||
}
|
||||
}
|
||||
|
||||
u32 avr32_hpt_read(void)
|
||||
{
|
||||
return timer_read(ioregs, 0, CV);
|
||||
}
|
||||
|
||||
static int avr32_timer_calc_div_and_set_jiffies(struct clk *pclk)
|
||||
{
|
||||
unsigned int cycles_max = (clocksource_avr32.mask + 1) / 2;
|
||||
unsigned int divs[] = { 4, 8, 16, 32 };
|
||||
int divs_size = sizeof(divs) / sizeof(*divs);
|
||||
int i = 0;
|
||||
unsigned long count_hz;
|
||||
unsigned long shift;
|
||||
unsigned long mult;
|
||||
int clock_div = -1;
|
||||
u64 tmp;
|
||||
|
||||
shift = clocksource_avr32.shift;
|
||||
|
||||
do {
|
||||
count_hz = clk_get_rate(pclk) / divs[i];
|
||||
mult = clocksource_hz2mult(count_hz, shift);
|
||||
clocksource_avr32.mult = mult;
|
||||
|
||||
tmp = TICK_NSEC;
|
||||
tmp <<= shift;
|
||||
tmp += mult / 2;
|
||||
do_div(tmp, mult);
|
||||
|
||||
cycles_per_jiffy = tmp;
|
||||
} while (cycles_per_jiffy > cycles_max && ++i < divs_size);
|
||||
|
||||
clock_div = i + 1;
|
||||
|
||||
if (clock_div > divs_size) {
|
||||
pr_debug("timer: could not calculate clock divider\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Set the clock divider */
|
||||
timer_write(ioregs, 0, CMR, TIMER_BF(CMR_TCCLKS, clock_div));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avr32_hpt_init(unsigned int count)
|
||||
{
|
||||
struct resource *regs;
|
||||
struct clk *pclk;
|
||||
int irq = -1;
|
||||
int ret = 0;
|
||||
|
||||
ret = -ENXIO;
|
||||
|
||||
irq = platform_get_irq(&at32_systc0_device, 0);
|
||||
if (irq < 0) {
|
||||
pr_debug("timer: could not get irq\n");
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
pclk = clk_get(&at32_systc0_device.dev, "pclk");
|
||||
if (IS_ERR(pclk)) {
|
||||
pr_debug("timer: could not get clk: %ld\n", PTR_ERR(pclk));
|
||||
goto out_error;
|
||||
}
|
||||
clk_enable(pclk);
|
||||
|
||||
regs = platform_get_resource(&at32_systc0_device, IORESOURCE_MEM, 0);
|
||||
if (!regs) {
|
||||
pr_debug("timer: could not get resource\n");
|
||||
goto out_error_clk;
|
||||
}
|
||||
|
||||
ioregs = ioremap(regs->start, regs->end - regs->start + 1);
|
||||
if (!ioregs) {
|
||||
pr_debug("timer: could not get ioregs\n");
|
||||
goto out_error_clk;
|
||||
}
|
||||
|
||||
ret = avr32_timer_calc_div_and_set_jiffies(pclk);
|
||||
if (ret)
|
||||
goto out_error_io;
|
||||
|
||||
ret = setup_irq(irq, &timer_irqaction);
|
||||
if (ret) {
|
||||
pr_debug("timer: could not request irq %d: %d\n",
|
||||
irq, ret);
|
||||
goto out_error_io;
|
||||
}
|
||||
|
||||
expirelo = (timer_read(ioregs, 0, CV) / cycles_per_jiffy + 1)
|
||||
* cycles_per_jiffy;
|
||||
|
||||
/* Enable clock and interrupts on RC compare */
|
||||
timer_write(ioregs, 0, CCR, TIMER_BIT(CCR_CLKEN));
|
||||
timer_write(ioregs, 0, IER, TIMER_BIT(IER_CPCS));
|
||||
/* Set cycles to first interrupt */
|
||||
timer_write(ioregs, 0, RC, expirelo);
|
||||
|
||||
printk(KERN_INFO "timer: AT32AP system timer/counter at 0x%p irq %d\n",
|
||||
ioregs, irq);
|
||||
|
||||
return 0;
|
||||
|
||||
out_error_io:
|
||||
iounmap(ioregs);
|
||||
out_error_clk:
|
||||
clk_put(pclk);
|
||||
out_error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int avr32_hpt_start(void)
|
||||
{
|
||||
timer_write(ioregs, 0, CCR, TIMER_BIT(CCR_SWTRG));
|
||||
return 0;
|
||||
}
|
||||
|
||||
irqreturn_t timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
unsigned int sr = timer_read(ioregs, 0, SR);
|
||||
|
||||
if (sr & TIMER_BIT(SR_CPCS)) {
|
||||
/* ack timer interrupt and try to set next interrupt */
|
||||
avr32_timer_ack();
|
||||
|
||||
/*
|
||||
* Call the generic timer interrupt handler
|
||||
*/
|
||||
write_seqlock(&xtime_lock);
|
||||
do_timer(1);
|
||||
write_sequnlock(&xtime_lock);
|
||||
|
||||
/*
|
||||
* In UP mode, we call local_timer_interrupt() to do profiling
|
||||
* and process accounting.
|
||||
*
|
||||
* SMP is not supported yet.
|
||||
*/
|
||||
local_timer_interrupt(irq, dev_id);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return IRQ_NONE;
|
||||
}
|
@ -16,26 +16,8 @@
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/tlb.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
static void dump_code(unsigned long pc)
|
||||
{
|
||||
char *p = (char *)pc;
|
||||
char val;
|
||||
int i;
|
||||
|
||||
|
||||
printk(KERN_DEBUG "Code:");
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (__get_user(val, p + i))
|
||||
break;
|
||||
printk(" %02x", val);
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
#endif
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_KPROBES
|
||||
ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
|
||||
@ -68,17 +50,19 @@ static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
|
||||
}
|
||||
#endif
|
||||
|
||||
int exception_trace = 1;
|
||||
|
||||
/*
|
||||
* This routine handles page faults. It determines the address and the
|
||||
* problem, and then passes it off to one of the appropriate routines.
|
||||
*
|
||||
* ecr is the Exception Cause Register. Possible values are:
|
||||
* 5: Page not found (instruction access)
|
||||
* 6: Protection fault (instruction access)
|
||||
* 12: Page not found (read access)
|
||||
* 13: Page not found (write access)
|
||||
* 14: Protection fault (read access)
|
||||
* 15: Protection fault (write access)
|
||||
* 15: Protection fault (read access)
|
||||
* 16: Protection fault (write access)
|
||||
* 20: Page not found (instruction access)
|
||||
* 24: Page not found (read access)
|
||||
* 28: Page not found (write access)
|
||||
*/
|
||||
asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
|
||||
{
|
||||
@ -88,7 +72,9 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
|
||||
const struct exception_table_entry *fixup;
|
||||
unsigned long address;
|
||||
unsigned long page;
|
||||
int writeaccess = 0;
|
||||
int writeaccess;
|
||||
long signr;
|
||||
int code;
|
||||
|
||||
if (notify_page_fault(DIE_PAGE_FAULT, regs,
|
||||
ecr, SIGSEGV) == NOTIFY_STOP)
|
||||
@ -99,6 +85,9 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
|
||||
tsk = current;
|
||||
mm = tsk->mm;
|
||||
|
||||
signr = SIGSEGV;
|
||||
code = SEGV_MAPERR;
|
||||
|
||||
/*
|
||||
* If we're in an interrupt or have no user context, we must
|
||||
* not take the fault...
|
||||
@ -125,7 +114,9 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
|
||||
* can handle it...
|
||||
*/
|
||||
good_area:
|
||||
//pr_debug("good area: vm_flags = 0x%lx\n", vma->vm_flags);
|
||||
code = SEGV_ACCERR;
|
||||
writeaccess = 0;
|
||||
|
||||
switch (ecr) {
|
||||
case ECR_PROTECTION_X:
|
||||
case ECR_TLB_MISS_X:
|
||||
@ -176,46 +167,24 @@ survive:
|
||||
* map. Fix it, but check if it's kernel or user first...
|
||||
*/
|
||||
bad_area:
|
||||
pr_debug("Bad area [%s:%u]: addr %08lx, ecr %lu\n",
|
||||
tsk->comm, tsk->pid, address, ecr);
|
||||
|
||||
up_read(&mm->mmap_sem);
|
||||
|
||||
if (user_mode(regs)) {
|
||||
/* Hmm...we have to pass address and ecr somehow... */
|
||||
/* tsk->thread.address = address;
|
||||
tsk->thread.error_code = ecr; */
|
||||
#ifdef DEBUG
|
||||
show_regs(regs);
|
||||
dump_code(regs->pc);
|
||||
|
||||
page = sysreg_read(PTBR);
|
||||
printk("ptbr = %08lx", page);
|
||||
if (page) {
|
||||
page = ((unsigned long *)page)[address >> 22];
|
||||
printk(" pgd = %08lx", page);
|
||||
if (page & _PAGE_PRESENT) {
|
||||
page &= PAGE_MASK;
|
||||
address &= 0x003ff000;
|
||||
page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT];
|
||||
printk(" pte = %08lx\n", page);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
pr_debug("Sending SIGSEGV to PID %d...\n",
|
||||
tsk->pid);
|
||||
force_sig(SIGSEGV, tsk);
|
||||
if (exception_trace)
|
||||
printk("%s%s[%d]: segfault at %08lx pc %08lx "
|
||||
"sp %08lx ecr %lu\n",
|
||||
is_init(tsk) ? KERN_EMERG : KERN_INFO,
|
||||
tsk->comm, tsk->pid, address, regs->pc,
|
||||
regs->sp, ecr);
|
||||
_exception(SIGSEGV, regs, code, address);
|
||||
return;
|
||||
}
|
||||
|
||||
no_context:
|
||||
pr_debug("No context\n");
|
||||
|
||||
/* Are we prepared to handle this kernel fault? */
|
||||
fixup = search_exception_tables(regs->pc);
|
||||
if (fixup) {
|
||||
regs->pc = fixup->fixup;
|
||||
pr_debug("Found fixup at %08lx\n", fixup->fixup);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -230,7 +199,6 @@ no_context:
|
||||
printk(KERN_ALERT
|
||||
"Unable to handle kernel paging request");
|
||||
printk(" at virtual address %08lx\n", address);
|
||||
printk(KERN_ALERT "pc = %08lx\n", regs->pc);
|
||||
|
||||
page = sysreg_read(PTBR);
|
||||
printk(KERN_ALERT "ptbr = %08lx", page);
|
||||
@ -241,20 +209,20 @@ no_context:
|
||||
page &= PAGE_MASK;
|
||||
address &= 0x003ff000;
|
||||
page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT];
|
||||
printk(" pte = %08lx\n", page);
|
||||
printk(" pte = %08lx", page);
|
||||
}
|
||||
}
|
||||
die("\nOops", regs, ecr);
|
||||
do_exit(SIGKILL);
|
||||
printk("\n");
|
||||
die("Kernel access of bad area", regs, signr);
|
||||
return;
|
||||
|
||||
/*
|
||||
* We ran out of memory, or some other thing happened to us
|
||||
* that made us unable to handle the page fault gracefully.
|
||||
*/
|
||||
out_of_memory:
|
||||
printk("Out of memory\n");
|
||||
up_read(&mm->mmap_sem);
|
||||
if (current->pid == 1) {
|
||||
if (is_init(current)) {
|
||||
yield();
|
||||
down_read(&mm->mmap_sem);
|
||||
goto survive;
|
||||
@ -267,21 +235,20 @@ out_of_memory:
|
||||
do_sigbus:
|
||||
up_read(&mm->mmap_sem);
|
||||
|
||||
/*
|
||||
* Send a sigbus, regardless of whether we were in kernel or
|
||||
* user mode.
|
||||
*/
|
||||
/* address, error_code, trap_no, ... */
|
||||
#ifdef DEBUG
|
||||
show_regs(regs);
|
||||
dump_code(regs->pc);
|
||||
#endif
|
||||
pr_debug("Sending SIGBUS to PID %d...\n", tsk->pid);
|
||||
force_sig(SIGBUS, tsk);
|
||||
|
||||
/* Kernel mode? Handle exceptions or die */
|
||||
signr = SIGBUS;
|
||||
code = BUS_ADRERR;
|
||||
if (!user_mode(regs))
|
||||
goto no_context;
|
||||
|
||||
if (exception_trace)
|
||||
printk("%s%s[%d]: bus error at %08lx pc %08lx "
|
||||
"sp %08lx ecr %lu\n",
|
||||
is_init(tsk) ? KERN_EMERG : KERN_INFO,
|
||||
tsk->comm, tsk->pid, address, regs->pc,
|
||||
regs->sp, ecr);
|
||||
|
||||
_exception(SIGBUS, regs, BUS_ADRERR, address);
|
||||
}
|
||||
|
||||
asmlinkage void do_bus_error(unsigned long addr, int write_access,
|
||||
@ -292,8 +259,7 @@ asmlinkage void do_bus_error(unsigned long addr, int write_access,
|
||||
addr, write_access ? "write" : "read");
|
||||
printk(KERN_INFO "DTLB dump:\n");
|
||||
dump_dtlb();
|
||||
die("Bus Error", regs, write_access);
|
||||
do_exit(SIGKILL);
|
||||
die("Bus Error", regs, SIGKILL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10,11 +10,9 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/pfn.h>
|
||||
#include <linux/nodemask.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
@ -78,242 +76,6 @@ void show_mem(void)
|
||||
printk ("%d pages swap cached\n", cached);
|
||||
}
|
||||
|
||||
static void __init print_memory_map(const char *what,
|
||||
struct tag_mem_range *mem)
|
||||
{
|
||||
printk ("%s:\n", what);
|
||||
for (; mem; mem = mem->next) {
|
||||
printk (" %08lx - %08lx\n",
|
||||
(unsigned long)mem->addr,
|
||||
(unsigned long)(mem->addr + mem->size));
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_LOWMEM HIGHMEM_START
|
||||
#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM)
|
||||
|
||||
/*
|
||||
* Sort a list of memory regions in-place by ascending address.
|
||||
*
|
||||
* We're using bubble sort because we only have singly linked lists
|
||||
* with few elements.
|
||||
*/
|
||||
static void __init sort_mem_list(struct tag_mem_range **pmem)
|
||||
{
|
||||
int done;
|
||||
struct tag_mem_range **a, **b;
|
||||
|
||||
if (!*pmem)
|
||||
return;
|
||||
|
||||
do {
|
||||
done = 1;
|
||||
a = pmem, b = &(*pmem)->next;
|
||||
while (*b) {
|
||||
if ((*a)->addr > (*b)->addr) {
|
||||
struct tag_mem_range *tmp;
|
||||
tmp = (*b)->next;
|
||||
(*b)->next = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
done = 0;
|
||||
}
|
||||
a = &(*a)->next;
|
||||
b = &(*a)->next;
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a free memory region large enough for storing the
|
||||
* bootmem bitmap.
|
||||
*/
|
||||
static unsigned long __init
|
||||
find_bootmap_pfn(const struct tag_mem_range *mem)
|
||||
{
|
||||
unsigned long bootmap_pages, bootmap_len;
|
||||
unsigned long node_pages = PFN_UP(mem->size);
|
||||
unsigned long bootmap_addr = mem->addr;
|
||||
struct tag_mem_range *reserved = mem_reserved;
|
||||
struct tag_mem_range *ramdisk = mem_ramdisk;
|
||||
unsigned long kern_start = virt_to_phys(_stext);
|
||||
unsigned long kern_end = virt_to_phys(_end);
|
||||
|
||||
bootmap_pages = bootmem_bootmap_pages(node_pages);
|
||||
bootmap_len = bootmap_pages << PAGE_SHIFT;
|
||||
|
||||
/*
|
||||
* Find a large enough region without reserved pages for
|
||||
* storing the bootmem bitmap. We can take advantage of the
|
||||
* fact that all lists have been sorted.
|
||||
*
|
||||
* We have to check explicitly reserved regions as well as the
|
||||
* kernel image and any RAMDISK images...
|
||||
*
|
||||
* Oh, and we have to make sure we don't overwrite the taglist
|
||||
* since we're going to use it until the bootmem allocator is
|
||||
* fully up and running.
|
||||
*/
|
||||
while (1) {
|
||||
if ((bootmap_addr < kern_end) &&
|
||||
((bootmap_addr + bootmap_len) > kern_start))
|
||||
bootmap_addr = kern_end;
|
||||
|
||||
while (reserved &&
|
||||
(bootmap_addr >= (reserved->addr + reserved->size)))
|
||||
reserved = reserved->next;
|
||||
|
||||
if (reserved &&
|
||||
((bootmap_addr + bootmap_len) >= reserved->addr)) {
|
||||
bootmap_addr = reserved->addr + reserved->size;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (ramdisk &&
|
||||
(bootmap_addr >= (ramdisk->addr + ramdisk->size)))
|
||||
ramdisk = ramdisk->next;
|
||||
|
||||
if (!ramdisk ||
|
||||
((bootmap_addr + bootmap_len) < ramdisk->addr))
|
||||
break;
|
||||
|
||||
bootmap_addr = ramdisk->addr + ramdisk->size;
|
||||
}
|
||||
|
||||
if ((PFN_UP(bootmap_addr) + bootmap_len) >= (mem->addr + mem->size))
|
||||
return ~0UL;
|
||||
|
||||
return PFN_UP(bootmap_addr);
|
||||
}
|
||||
|
||||
void __init setup_bootmem(void)
|
||||
{
|
||||
unsigned bootmap_size;
|
||||
unsigned long first_pfn, bootmap_pfn, pages;
|
||||
unsigned long max_pfn, max_low_pfn;
|
||||
unsigned long kern_start = virt_to_phys(_stext);
|
||||
unsigned long kern_end = virt_to_phys(_end);
|
||||
unsigned node = 0;
|
||||
struct tag_mem_range *bank, *res;
|
||||
|
||||
sort_mem_list(&mem_phys);
|
||||
sort_mem_list(&mem_reserved);
|
||||
|
||||
print_memory_map("Physical memory", mem_phys);
|
||||
print_memory_map("Reserved memory", mem_reserved);
|
||||
|
||||
nodes_clear(node_online_map);
|
||||
|
||||
if (mem_ramdisk) {
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
initrd_start = (unsigned long)__va(mem_ramdisk->addr);
|
||||
initrd_end = initrd_start + mem_ramdisk->size;
|
||||
|
||||
print_memory_map("RAMDISK images", mem_ramdisk);
|
||||
if (mem_ramdisk->next)
|
||||
printk(KERN_WARNING
|
||||
"Warning: Only the first RAMDISK image "
|
||||
"will be used\n");
|
||||
sort_mem_list(&mem_ramdisk);
|
||||
#else
|
||||
printk(KERN_WARNING "RAM disk image present, but "
|
||||
"no initrd support in kernel!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mem_phys->next)
|
||||
printk(KERN_WARNING "Only using first memory bank\n");
|
||||
|
||||
for (bank = mem_phys; bank; bank = NULL) {
|
||||
first_pfn = PFN_UP(bank->addr);
|
||||
max_low_pfn = max_pfn = PFN_DOWN(bank->addr + bank->size);
|
||||
bootmap_pfn = find_bootmap_pfn(bank);
|
||||
if (bootmap_pfn > max_pfn)
|
||||
panic("No space for bootmem bitmap!\n");
|
||||
|
||||
if (max_low_pfn > MAX_LOWMEM_PFN) {
|
||||
max_low_pfn = MAX_LOWMEM_PFN;
|
||||
#ifndef CONFIG_HIGHMEM
|
||||
/*
|
||||
* Lowmem is memory that can be addressed
|
||||
* directly through P1/P2
|
||||
*/
|
||||
printk(KERN_WARNING
|
||||
"Node %u: Only %ld MiB of memory will be used.\n",
|
||||
node, MAX_LOWMEM >> 20);
|
||||
printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
|
||||
#else
|
||||
#error HIGHMEM is not supported by AVR32 yet
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the boot-time allocator with low memory only. */
|
||||
bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn,
|
||||
first_pfn, max_low_pfn);
|
||||
|
||||
printk("Node %u: bdata = %p, bdata->node_bootmem_map = %p\n",
|
||||
node, NODE_DATA(node)->bdata,
|
||||
NODE_DATA(node)->bdata->node_bootmem_map);
|
||||
|
||||
/*
|
||||
* Register fully available RAM pages with the bootmem
|
||||
* allocator.
|
||||
*/
|
||||
pages = max_low_pfn - first_pfn;
|
||||
free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn),
|
||||
PFN_PHYS(pages));
|
||||
|
||||
/*
|
||||
* Reserve space for the kernel image (if present in
|
||||
* this node)...
|
||||
*/
|
||||
if ((kern_start >= PFN_PHYS(first_pfn)) &&
|
||||
(kern_start < PFN_PHYS(max_pfn))) {
|
||||
printk("Node %u: Kernel image %08lx - %08lx\n",
|
||||
node, kern_start, kern_end);
|
||||
reserve_bootmem_node(NODE_DATA(node), kern_start,
|
||||
kern_end - kern_start);
|
||||
}
|
||||
|
||||
/* ...the bootmem bitmap... */
|
||||
reserve_bootmem_node(NODE_DATA(node),
|
||||
PFN_PHYS(bootmap_pfn),
|
||||
bootmap_size);
|
||||
|
||||
/* ...any RAMDISK images... */
|
||||
for (res = mem_ramdisk; res; res = res->next) {
|
||||
if (res->addr > PFN_PHYS(max_pfn))
|
||||
break;
|
||||
|
||||
if (res->addr >= PFN_PHYS(first_pfn)) {
|
||||
printk("Node %u: RAMDISK %08lx - %08lx\n",
|
||||
node,
|
||||
(unsigned long)res->addr,
|
||||
(unsigned long)(res->addr + res->size));
|
||||
reserve_bootmem_node(NODE_DATA(node),
|
||||
res->addr, res->size);
|
||||
}
|
||||
}
|
||||
|
||||
/* ...and any other reserved regions. */
|
||||
for (res = mem_reserved; res; res = res->next) {
|
||||
if (res->addr > PFN_PHYS(max_pfn))
|
||||
break;
|
||||
|
||||
if (res->addr >= PFN_PHYS(first_pfn)) {
|
||||
printk("Node %u: Reserved %08lx - %08lx\n",
|
||||
node,
|
||||
(unsigned long)res->addr,
|
||||
(unsigned long)(res->addr + res->size));
|
||||
reserve_bootmem_node(NODE_DATA(node),
|
||||
res->addr, res->size);
|
||||
}
|
||||
}
|
||||
|
||||
node_set_online(node);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* paging_init() sets up the page tables
|
||||
*
|
||||
|
@ -100,7 +100,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
if ((err = pcibios_enable_resources(dev, mask)) < 0)
|
||||
return err;
|
||||
|
||||
return pcibios_enable_irq(dev);
|
||||
if (!dev->msi_enabled)
|
||||
pcibios_enable_irq(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcibios_assign_resources(void)
|
||||
|
@ -466,6 +466,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
|
||||
if ((err = pcibios_enable_resources(dev, mask)) < 0)
|
||||
return err;
|
||||
pcibios_enable_irq(dev);
|
||||
if (!dev->msi_enabled)
|
||||
pcibios_enable_irq(dev);
|
||||
return 0;
|
||||
}
|
||||
|
@ -571,6 +571,16 @@ setr1: lodsw
|
||||
jmp _m_s
|
||||
|
||||
check_vesa:
|
||||
#ifdef CONFIG_FIRMWARE_EDID
|
||||
leaw modelist+1024, %di
|
||||
movw $0x4f00, %ax
|
||||
int $0x10
|
||||
cmpw $0x004f, %ax
|
||||
jnz setbad
|
||||
|
||||
movw 4(%di), %ax
|
||||
movw %ax, vbe_version
|
||||
#endif
|
||||
leaw modelist+1024, %di
|
||||
subb $VIDEO_FIRST_VESA>>8, %bh
|
||||
movw %bx, %cx # Get mode information structure
|
||||
@ -1945,6 +1955,9 @@ store_edid:
|
||||
rep
|
||||
stosl
|
||||
|
||||
cmpw $0x0200, vbe_version # only do EDID on >= VBE2.0
|
||||
jl no_edid
|
||||
|
||||
pushw %es # save ES
|
||||
xorw %di, %di # Report Capability
|
||||
pushw %di
|
||||
@ -1987,6 +2000,7 @@ do_restore: .byte 0 # Screen contents altered during mode change
|
||||
svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes
|
||||
graphic_mode: .byte 0 # Graphic mode with a linear frame buffer
|
||||
dac_size: .byte 6 # DAC bit depth
|
||||
vbe_version: .word 0 # VBE bios version
|
||||
|
||||
# Status messages
|
||||
keymsg: .ascii "Press <RETURN> to see video modes available, "
|
||||
|
@ -692,7 +692,6 @@ CONFIG_SATA_SIL=y
|
||||
CONFIG_SATA_VIA=y
|
||||
# CONFIG_SATA_VITESSE is not set
|
||||
# CONFIG_SATA_INIC162X is not set
|
||||
CONFIG_SATA_INTEL_COMBINED=y
|
||||
CONFIG_SATA_ACPI=y
|
||||
# CONFIG_PATA_ALI is not set
|
||||
# CONFIG_PATA_AMD is not set
|
||||
|
@ -23,10 +23,13 @@ static int __init nvidia_hpet_check(struct acpi_table_header *header)
|
||||
static int __init check_bridge(int vendor, int device)
|
||||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
static int warned;
|
||||
/* According to Nvidia all timer overrides are bogus unless HPET
|
||||
is enabled. */
|
||||
if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
|
||||
if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
|
||||
if (!warned && acpi_table_parse(ACPI_SIG_HPET,
|
||||
nvidia_hpet_check)) {
|
||||
warned = 1;
|
||||
acpi_skip_timer_override = 1;
|
||||
printk(KERN_INFO "Nvidia board "
|
||||
"detected. Ignoring ACPI "
|
||||
|
@ -5,15 +5,9 @@
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
static int no_replacement = 0;
|
||||
static int smp_alt_once = 0;
|
||||
static int debug_alternative = 0;
|
||||
|
||||
static int __init noreplacement_setup(char *s)
|
||||
{
|
||||
no_replacement = 1;
|
||||
return 1;
|
||||
}
|
||||
static int __init bootonly(char *str)
|
||||
{
|
||||
smp_alt_once = 1;
|
||||
@ -25,7 +19,6 @@ static int __init debug_alt(char *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("noreplacement", noreplacement_setup);
|
||||
__setup("smp-alt-boot", bootonly);
|
||||
__setup("debug-alternative", debug_alt);
|
||||
|
||||
@ -252,9 +245,6 @@ void alternatives_smp_module_add(struct module *mod, char *name,
|
||||
struct smp_alt_module *smp;
|
||||
unsigned long flags;
|
||||
|
||||
if (no_replacement)
|
||||
return;
|
||||
|
||||
if (smp_alt_once) {
|
||||
if (boot_cpu_has(X86_FEATURE_UP))
|
||||
alternatives_smp_unlock(locks, locks_end,
|
||||
@ -289,7 +279,7 @@ void alternatives_smp_module_del(struct module *mod)
|
||||
struct smp_alt_module *item;
|
||||
unsigned long flags;
|
||||
|
||||
if (no_replacement || smp_alt_once)
|
||||
if (smp_alt_once)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&smp_alt, flags);
|
||||
@ -320,7 +310,7 @@ void alternatives_smp_switch(int smp)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (no_replacement || smp_alt_once)
|
||||
if (smp_alt_once)
|
||||
return;
|
||||
BUG_ON(!smp && (num_online_cpus() > 1));
|
||||
|
||||
@ -386,13 +376,6 @@ extern struct paravirt_patch __start_parainstructions[],
|
||||
void __init alternative_instructions(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
if (no_replacement) {
|
||||
printk(KERN_INFO "(SMP-)alternatives turned off\n");
|
||||
free_init_pages("SMP alternatives",
|
||||
(unsigned long)__smp_alt_begin,
|
||||
(unsigned long)__smp_alt_end);
|
||||
return;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
apply_alternatives(__alt_instructions, __alt_instructions_end);
|
||||
|
@ -271,32 +271,6 @@ static void __devinit setup_APIC_timer(void)
|
||||
clockevents_register_device(levt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect systems with known broken BIOS implementations
|
||||
*/
|
||||
static int __init lapic_check_broken_bios(struct dmi_system_id *d)
|
||||
{
|
||||
printk(KERN_NOTICE "%s detected: disabling lapic timer.\n",
|
||||
d->ident);
|
||||
local_apic_timer_disabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dmi_system_id __initdata broken_bios_dmi_table[] = {
|
||||
{
|
||||
/*
|
||||
* BIOS exports only C1 state, but uses deeper power
|
||||
* modes behind the kernels back.
|
||||
*/
|
||||
.callback = lapic_check_broken_bios,
|
||||
.ident = "HP nx6325",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* In this functions we calibrate APIC bus clocks to the external timer.
|
||||
*
|
||||
@ -372,12 +346,12 @@ void __init setup_boot_APIC_clock(void)
|
||||
long delta, deltapm;
|
||||
int pm_referenced = 0;
|
||||
|
||||
/* Detect know broken systems */
|
||||
dmi_check_system(broken_bios_dmi_table);
|
||||
if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN))
|
||||
local_apic_timer_disabled = 1;
|
||||
|
||||
/*
|
||||
* The local apic timer can be disabled via the kernel
|
||||
* commandline or from the dmi quirk above. Register the lapic
|
||||
* commandline or from the test above. Register the lapic
|
||||
* timer as a dummy clock event source on SMP systems, so the
|
||||
* broadcast mechanism is used. On UP systems simply ignore it.
|
||||
*/
|
||||
|
@ -22,6 +22,37 @@
|
||||
extern void vide(void);
|
||||
__asm__(".align 4\nvide: ret");
|
||||
|
||||
#define ENABLE_C1E_MASK 0x18000000
|
||||
#define CPUID_PROCESSOR_SIGNATURE 1
|
||||
#define CPUID_XFAM 0x0ff00000
|
||||
#define CPUID_XFAM_K8 0x00000000
|
||||
#define CPUID_XFAM_10H 0x00100000
|
||||
#define CPUID_XFAM_11H 0x00200000
|
||||
#define CPUID_XMOD 0x000f0000
|
||||
#define CPUID_XMOD_REV_F 0x00040000
|
||||
|
||||
/* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
|
||||
static __cpuinit int amd_apic_timer_broken(void)
|
||||
{
|
||||
u32 lo, hi;
|
||||
u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
|
||||
switch (eax & CPUID_XFAM) {
|
||||
case CPUID_XFAM_K8:
|
||||
if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F)
|
||||
break;
|
||||
case CPUID_XFAM_10H:
|
||||
case CPUID_XFAM_11H:
|
||||
rdmsr(MSR_K8_ENABLE_C1E, lo, hi);
|
||||
if (lo & ENABLE_C1E_MASK)
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
/* err on the side of caution */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __cpuinit init_amd(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 l, h;
|
||||
@ -241,6 +272,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
|
||||
|
||||
if (cpuid_eax(0x80000000) >= 0x80000006)
|
||||
num_cache_leaves = 3;
|
||||
|
||||
if (amd_apic_timer_broken())
|
||||
set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability);
|
||||
}
|
||||
|
||||
static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user