Merge branch 'splice' of git://brick.kernel.dk/data/git/linux-2.6-block
* 'splice' of git://brick.kernel.dk/data/git/linux-2.6-block:
[PATCH] splice: fix problems with sys_tee()
diff --git a/CREDITS b/CREDITS
index 66b9e7a..29be6d1 100644
--- a/CREDITS
+++ b/CREDITS
@@ -528,11 +528,11 @@
S: United Kingdom
N: Luiz Fernando N. Capitulino
-E: lcapitulino@terra.com.br
-E: lcapitulino@prefeitura.sp.gov.br
-W: http://www.telecentros.sp.gov.br
-D: Little fixes and a lot of janitorial work
-S: E-GOV Telecentros SP
+E: lcapitulino@mandriva.com.br
+E: lcapitulino@gmail.com
+W: http://www.cpu.eti.br
+D: misc kernel hacking
+S: Mandriva
S: Brazil
N: Remy Card
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 4f41a60..318df44 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -687,8 +687,9 @@
+ spin_lock(&listmutex);
list_for_each_entry(p, head, lp) {
if (p->key == key) {
- list_del(&p->list);
+ - list_del(&p->list);
- write_unlock(&listmutex);
+ + list_del_rcu(&p->list);
+ spin_unlock(&listmutex);
+ synchronize_rcu();
kfree(p);
@@ -736,7 +737,7 @@
5 write_lock(&listmutex); 5 spin_lock(&listmutex);
6 list_for_each_entry(p, head, lp) { 6 list_for_each_entry(p, head, lp) {
7 if (p->key == key) { 7 if (p->key == key) {
- 8 list_del(&p->list); 8 list_del(&p->list);
+ 8 list_del(&p->list); 8 list_del_rcu(&p->list);
9 write_unlock(&listmutex); 9 spin_unlock(&listmutex);
10 synchronize_rcu();
10 kfree(p); 11 kfree(p);
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
index 8230098..a10bfb6 100644
--- a/Documentation/SubmitChecklist
+++ b/Documentation/SubmitChecklist
@@ -1,57 +1,63 @@
Linux Kernel patch sumbittal checklist
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Here are some basic things that developers should do if they
-want to see their kernel patch submittals accepted quicker.
+Here are some basic things that developers should do if they want to see their
+kernel patch submissions accepted more quickly.
-These are all above and beyond the documentation that is provided
-in Documentation/SubmittingPatches and elsewhere about submitting
-Linux kernel patches.
+These are all above and beyond the documentation that is provided in
+Documentation/SubmittingPatches and elsewhere regarding submitting Linux
+kernel patches.
-- Builds cleanly with applicable or modified CONFIG options =y, =m, and =n.
- No gcc warnings/errors, no linker warnings/errors.
+1: Builds cleanly with applicable or modified CONFIG options =y, =m, and
+ =n. No gcc warnings/errors, no linker warnings/errors.
-- Passes allnoconfig, allmodconfig
+2: Passes allnoconfig, allmodconfig
-- Builds on multiple CPU arch-es by using local cross-compile tools
- or something like PLM at OSDL.
+3: Builds on multiple CPU architectures by using local cross-compile tools
+ or something like PLM at OSDL.
-- ppc64 is a good architecture for cross-compilation checking because it
- tends to use `unsigned long' for 64-bit quantities.
+4: ppc64 is a good architecture for cross-compilation checking because it
+ tends to use `unsigned long' for 64-bit quantities.
-- Matches kernel coding style(!)
+5: Matches kernel coding style(!)
-- Any new or modified CONFIG options don't muck up the config menu.
+6: Any new or modified CONFIG options don't muck up the config menu.
-- All new Kconfig options have help text.
+7: All new Kconfig options have help text.
-- Has been carefully reviewed with respect to relevant Kconfig
- combinations. This is very hard to get right with testing --
- brainpower pays off here.
+8: Has been carefully reviewed with respect to relevant Kconfig
+ combinations. This is very hard to get right with testing -- brainpower
+ pays off here.
-- Check cleanly with sparse.
+9: Check cleanly with sparse.
-- Use 'make checkstack' and 'make namespacecheck' and fix any
- problems that they find. Note: checkstack does not point out
- problems explicitly, but any one function that uses more than
- 512 bytes on the stack is a candidate for change.
+10: Use 'make checkstack' and 'make namespacecheck' and fix any problems
+ that they find. Note: checkstack does not point out problems explicitly,
+ but any one function that uses more than 512 bytes on the stack is a
+ candidate for change.
-- Include kernel-doc to document global kernel APIs. (Not required
- for static functions, but OK there also.) Use 'make htmldocs'
- or 'make mandocs' to check the kernel-doc and fix any issues.
+11: Include kernel-doc to document global kernel APIs. (Not required for
+ static functions, but OK there also.) Use 'make htmldocs' or 'make
+ mandocs' to check the kernel-doc and fix any issues.
-- Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT,
- CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES,
- CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_SPINLOCK_SLEEP all simultaneously
- enabled.
+12: Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT,
+ CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES,
+ CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_SPINLOCK_SLEEP all simultaneously
+ enabled.
-- Has been build- and runtime tested with and without CONFIG_SMP and
- CONFIG_PREEMPT.
+13: Has been build- and runtime tested with and without CONFIG_SMP and
+ CONFIG_PREEMPT.
-- If the patch affects IO/Disk, etc: has been tested with and without
- CONFIG_LBD.
+14: If the patch affects IO/Disk, etc: has been tested with and without
+ CONFIG_LBD.
+15: All codepaths have been exercised with all lockdep features enabled.
-2006-APR-27
+16: All new /proc entries are documented under Documentation/
+
+17: All new kernel boot parameters are documented in
+ Documentation/kernel-parameters.txt.
+
+18: All new module parameters are documented with MODULE_PARM_DESC()
diff --git a/Documentation/drivers/edac/edac.txt b/Documentation/drivers/edac/edac.txt
index 70d96a6..7b3d969 100644
--- a/Documentation/drivers/edac/edac.txt
+++ b/Documentation/drivers/edac/edac.txt
@@ -35,15 +35,14 @@
to generate parity. Some vendors do not do this, and thus the parity bit
can "float" giving false positives.
-The PCI Parity EDAC device has the ability to "skip" known flaky
-cards during the parity scan. These are set by the parity "blacklist"
-interface in the sysfs for PCI Parity. (See the PCI section in the sysfs
-section below.) There is also a parity "whitelist" which is used as
-an explicit list of devices to scan, while the blacklist is a list
-of devices to skip.
+[There are patches in the kernel queue which will allow for storage of
+quirks of PCI devices reporting false parity positives. The 2.6.18
+kernel should have those patches included. When that becomes available,
+then EDAC will be patched to utilize that information to "skip" such
+devices.]
-EDAC will have future error detectors that will be added or integrated
-into EDAC in the following list:
+EDAC will have future error detectors that will be integrated with
+EDAC or added to it, in the following list:
MCE Machine Check Exception
MCA Machine Check Architecture
@@ -93,22 +92,24 @@
there currently reside 2 'edac' components:
mc memory controller(s) system
- pci PCI status system
+ pci PCI control and status system
============================================================================
Memory Controller (mc) Model
First a background on the memory controller's model abstracted in EDAC.
-Each mc device controls a set of DIMM memory modules. These modules are
+Each 'mc' device controls a set of DIMM memory modules. These modules are
laid out in a Chip-Select Row (csrowX) and Channel table (chX). There can
-be multiple csrows and two channels.
+be multiple csrows and multiple channels.
Memory controllers allow for several csrows, with 8 csrows being a typical value.
Yet, the actual number of csrows depends on the electrical "loading"
of a given motherboard, memory controller and DIMM characteristics.
Dual channels allows for 128 bit data transfers to the CPU from memory.
+Some newer chipsets allow for more than 2 channels, like Fully Buffered DIMMs
+(FB-DIMMs). The following example will assume 2 channels:
Channel 0 Channel 1
@@ -234,23 +235,15 @@
The time period, in milliseconds, for polling for error information.
Too small a value wastes resources. Too large a value might delay
necessary handling of errors and might loose valuable information for
- locating the error. 1000 milliseconds (once each second) is about
- right for most uses.
+ locating the error. 1000 milliseconds (once each second) is the current
+ default. Systems which require all the bandwidth they can get, may
+ increase this.
LOAD TIME: module/kernel parameter: poll_msec=[0|1]
RUN TIME: echo "1000" >/sys/devices/system/edac/mc/poll_msec
-Module Version read-only attribute file:
-
- 'mc_version'
-
- The EDAC CORE module's version and compile date are shown here to
- indicate what EDAC is running.
-
-
-
============================================================================
'mcX' DIRECTORIES
@@ -284,35 +277,6 @@
-DIMM capability attribute file:
-
- 'edac_capability'
-
- The EDAC (Error Detection and Correction) capabilities/modes of
- the memory controller hardware.
-
-
-DIMM Current Capability attribute file:
-
- 'edac_current_capability'
-
- The EDAC capabilities available with the hardware
- configuration. This may not be the same as "EDAC capability"
- if the correct memory is not used. If a memory controller is
- capable of EDAC, but DIMMs without check bits are in use, then
- Parity, SECDED, S4ECD4ED capabilities will not be available
- even though the memory controller might be capable of those
- modes with the proper memory loaded.
-
-
-Memory Type supported on this controller attribute file:
-
- 'supported_mem_type'
-
- This attribute file displays the memory type, usually
- buffered and unbuffered DIMMs.
-
-
Memory Controller name attribute file:
'mc_name'
@@ -321,16 +285,6 @@
that is being utilized.
-Memory Controller Module name attribute file:
-
- 'module_name'
-
- This attribute file displays the memory controller module name,
- version and date built. The name of the memory controller
- hardware - some drivers work with multiple controllers and
- this field shows which hardware is present.
-
-
Total memory managed by this memory controller attribute file:
'size_mb'
@@ -432,6 +386,9 @@
This attribute file will display what type of memory is currently
on this csrow. Normally, either buffered or unbuffered memory.
+ Examples:
+ Registered-DDR
+ Unbuffered-DDR
EDAC Mode of operation attribute file:
@@ -446,8 +403,13 @@
'dev_type'
- This attribute file will display what type of DIMM device is
- being utilized. Example: x4
+ This attribute file will display what type of DRAM device is
+ being utilized on this DIMM.
+ Examples:
+ x1
+ x2
+ x4
+ x8
Channel 0 CE Count attribute file:
@@ -522,10 +484,10 @@
If logging for UEs and CEs are enabled then system logs will have
error notices indicating errors that have been detected:
-MC0: CE page 0x283, offset 0xce0, grain 8, syndrome 0x6ec3, row 0,
+EDAC MC0: CE page 0x283, offset 0xce0, grain 8, syndrome 0x6ec3, row 0,
channel 1 "DIMM_B1": amd76x_edac
-MC0: CE page 0x1e5, offset 0xfb0, grain 8, syndrome 0xb741, row 0,
+EDAC MC0: CE page 0x1e5, offset 0xfb0, grain 8, syndrome 0xb741, row 0,
channel 1 "DIMM_B1": amd76x_edac
@@ -610,64 +572,4 @@
-PCI Device Whitelist:
-
- 'pci_parity_whitelist'
-
- This control file allows for an explicit list of PCI devices to be
- scanned for parity errors. Only devices found on this list will
- be examined. The list is a line of hexadecimal VENDOR and DEVICE
- ID tuples:
-
- 1022:7450,1434:16a6
-
- One or more can be inserted, separated by a comma.
-
- To write the above list doing the following as one command line:
-
- echo "1022:7450,1434:16a6"
- > /sys/devices/system/edac/pci/pci_parity_whitelist
-
-
-
- To display what the whitelist is, simply 'cat' the same file.
-
-
-PCI Device Blacklist:
-
- 'pci_parity_blacklist'
-
- This control file allows for a list of PCI devices to be
- skipped for scanning.
- The list is a line of hexadecimal VENDOR and DEVICE ID tuples:
-
- 1022:7450,1434:16a6
-
- One or more can be inserted, separated by a comma.
-
- To write the above list doing the following as one command line:
-
- echo "1022:7450,1434:16a6"
- > /sys/devices/system/edac/pci/pci_parity_blacklist
-
-
- To display what the whitelist currently contains,
- simply 'cat' the same file.
-
=======================================================================
-
-PCI Vendor and Devices IDs can be obtained with the lspci command. Using
-the -n option lspci will display the vendor and device IDs. The system
-administrator will have to determine which devices should be scanned or
-skipped.
-
-
-
-The two lists (white and black) are prioritized. blacklist is the lower
-priority and will NOT be utilized when a whitelist has been set.
-Turn OFF a whitelist by an empty echo command:
-
- echo > /sys/devices/system/edac/pci/pci_parity_whitelist
-
-and any previous blacklist will be utilized.
-
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 99f219a..ee28798 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -166,17 +166,6 @@
---------------------------
-What: remove EXPORT_SYMBOL(tasklist_lock)
-When: August 2006
-Files: kernel/fork.c
-Why: tasklist_lock protects the kernel internal task list. Modules have
- no business looking at it, and all instances in drivers have been due
- to use of too-lowlevel APIs. Having this symbol exported prevents
- moving to more scalable locking schemes for the task list.
-Who: Christoph Hellwig <hch@lst.de>
-
----------------------------
-
What: mount/umount uevents
When: February 2007
Why: These events are not correct, and do not properly let userspace know
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index d31efbb..247d7f6 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -142,8 +142,8 @@
--------------------------- file_system_type ---------------------------
prototypes:
- struct int (*get_sb) (struct file_system_type *, int,
- const char *, void *, struct vfsmount *);
+ int (*get_sb) (struct file_system_type *, int,
+ const char *, void *, struct vfsmount *);
void (*kill_sb) (struct super_block *);
locking rules:
may block BKL
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 9d3aed6..1cb7e8b 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -113,8 +113,8 @@
struct file_system_type {
const char *name;
int fs_flags;
- struct int (*get_sb) (struct file_system_type *, int,
- const char *, void *, struct vfsmount *);
+ int (*get_sb) (struct file_system_type *, int,
+ const char *, void *, struct vfsmount *);
void (*kill_sb) (struct super_block *);
struct module *owner;
struct file_system_type * next;
diff --git a/Documentation/nfsroot.txt b/Documentation/nfsroot.txt
index d56dc71..3cc953c 100644
--- a/Documentation/nfsroot.txt
+++ b/Documentation/nfsroot.txt
@@ -4,15 +4,16 @@
Written 1996 by Gero Kuhlmann <gero@gkminix.han.de>
Updated 1997 by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
Updated 2006 by Nico Schottelius <nico-kernel-nfsroot@schottelius.org>
+Updated 2006 by Horms <horms@verge.net.au>
-If you want to use a diskless system, as an X-terminal or printer
-server for example, you have to put your root filesystem onto a
-non-disk device. This can either be a ramdisk (see initrd.txt in
-this directory for further information) or a filesystem mounted
-via NFS. The following text describes on how to use NFS for the
-root filesystem. For the rest of this text 'client' means the
+In order to use a diskless system, such as an X-terminal or printer server
+for example, it is necessary for the root filesystem to be present on a
+non-disk device. This may be an initramfs (see Documentation/filesystems/
+ramfs-rootfs-initramfs.txt), a ramdisk (see Documenation/initrd.txt) or a
+filesystem mounted via NFS. The following text describes on how to use NFS
+for the root filesystem. For the rest of this text 'client' means the
diskless system, and 'server' means the NFS server.
@@ -21,11 +22,13 @@
1.) Enabling nfsroot capabilities
-----------------------------
-In order to use nfsroot you have to select support for NFS during
-kernel configuration. Note that NFS cannot be loaded as a module
-in this case. The configuration script will then ask you whether
-you want to use nfsroot, and if yes what kind of auto configuration
-system you want to use. Selecting both BOOTP and RARP is safe.
+In order to use nfsroot, NFS client support needs to be selected as
+built-in during configuration. Once this has been selected, the nfsroot
+option will become available, which should also be selected.
+
+In the networking options, kernel level autoconfiguration can be selected,
+along with the types of autoconfiguration to support. Selecting all of
+DHCP, BOOTP and RARP is safe.
@@ -33,11 +36,10 @@
2.) Kernel command line
-------------------
-When the kernel has been loaded by a boot loader (either by loadlin,
-LILO or a network boot program) it has to be told what root fs device
-to use, and where to find the server and the name of the directory
-on the server to mount as root. This can be established by a couple
-of kernel command line parameters:
+When the kernel has been loaded by a boot loader (see below) it needs to be
+told what root fs device to use. And in the case of nfsroot, where to find
+both the server and the name of the directory on the server to mount as root.
+This can be established using the following kernel command line parameters:
root=/dev/nfs
@@ -49,23 +51,21 @@
nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
- If the `nfsroot' parameter is NOT given on the command line, the default
- "/tftpboot/%s" will be used.
+ If the `nfsroot' parameter is NOT given on the command line,
+ the default "/tftpboot/%s" will be used.
- <server-ip> Specifies the IP address of the NFS server. If this field
- is not given, the default address as determined by the
- `ip' variable (see below) is used. One use of this
- parameter is for example to allow using different servers
- for RARP and NFS. Usually you can leave this blank.
+ <server-ip> Specifies the IP address of the NFS server.
+ The default address is determined by the `ip' parameter
+ (see below). This parameter allows the use of different
+ servers for IP autoconfiguration and NFS.
- <root-dir> Name of the directory on the server to mount as root. If
- there is a "%s" token in the string, the token will be
- replaced by the ASCII-representation of the client's IP
- address.
+ <root-dir> Name of the directory on the server to mount as root.
+ If there is a "%s" token in the string, it will be
+ replaced by the ASCII-representation of the client's
+ IP address.
<nfs-options> Standard NFS options. All options are separated by commas.
- If the options field is not given, the following defaults
- will be used:
+ The following defaults are used:
port = as given by server portmap daemon
rsize = 1024
wsize = 1024
@@ -81,129 +81,174 @@
ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>
This parameter tells the kernel how to configure IP addresses of devices
- and also how to set up the IP routing table. It was originally called `nfsaddrs',
- but now the boot-time IP configuration works independently of NFS, so it
- was renamed to `ip' and the old name remained as an alias for compatibility
- reasons.
+ and also how to set up the IP routing table. It was originally called
+ `nfsaddrs', but now the boot-time IP configuration works independently of
+ NFS, so it was renamed to `ip' and the old name remained as an alias for
+ compatibility reasons.
If this parameter is missing from the kernel command line, all fields are
assumed to be empty, and the defaults mentioned below apply. In general
- this means that the kernel tries to configure everything using both
- RARP and BOOTP (depending on what has been enabled during kernel confi-
- guration, and if both what protocol answer got in first).
-
- <client-ip> IP address of the client. If empty, the address will either
- be determined by RARP or BOOTP. What protocol is used de-
- pends on what has been enabled during kernel configuration
- and on the <autoconf> parameter. If this parameter is not
- empty, neither RARP nor BOOTP will be used.
-
- <server-ip> IP address of the NFS server. If RARP is used to determine
- the client address and this parameter is NOT empty only
- replies from the specified server are accepted. To use
- different RARP and NFS server, specify your RARP server
- here (or leave it blank), and specify your NFS server in
- the `nfsroot' parameter (see above). If this entry is blank
- the address of the server is used which answered the RARP
- or BOOTP request.
-
- <gw-ip> IP address of a gateway if the server is on a different
- subnet. If this entry is empty no gateway is used and the
- server is assumed to be on the local network, unless a
- value has been received by BOOTP.
-
- <netmask> Netmask for local network interface. If this is empty,
- the netmask is derived from the client IP address assuming
- classful addressing, unless overridden in BOOTP reply.
-
- <hostname> Name of the client. If empty, the client IP address is
- used in ASCII notation, or the value received by BOOTP.
-
- <device> Name of network device to use. If this is empty, all
- devices are used for RARP and BOOTP requests, and the
- first one we receive a reply on is configured. If you have
- only one device, you can safely leave this blank.
-
- <autoconf> Method to use for autoconfiguration. If this is either
- 'rarp' or 'bootp', the specified protocol is used.
- If the value is 'both' or empty, both protocols are used
- so far as they have been enabled during kernel configura-
- tion. 'off' means no autoconfiguration.
+ this means that the kernel tries to configure everything using
+ autoconfiguration.
The <autoconf> parameter can appear alone as the value to the `ip'
parameter (without all the ':' characters before) in which case auto-
configuration is used.
+ <client-ip> IP address of the client.
+
+ Default: Determined using autoconfiguration.
+
+ <server-ip> IP address of the NFS server. If RARP is used to determine
+ the client address and this parameter is NOT empty only
+ replies from the specified server are accepted.
+
+ Only required for for NFS root. That is autoconfiguration
+ will not be triggered if it is missing and NFS root is not
+ in operation.
+
+ Default: Determined using autoconfiguration.
+ The address of the autoconfiguration server is used.
+
+ <gw-ip> IP address of a gateway if the server is on a different subnet.
+
+ Default: Determined using autoconfiguration.
+
+ <netmask> Netmask for local network interface. If unspecified
+ the netmask is derived from the client IP address assuming
+ classful addressing.
+
+ Default: Determined using autoconfiguration.
+
+ <hostname> Name of the client. May be supplied by autoconfiguration,
+ but its absence will not trigger autoconfiguration.
+
+ Default: Client IP address is used in ASCII notation.
+
+ <device> Name of network device to use.
+
+ Default: If the host only has one device, it is used.
+ Otherwise the device is determined using
+ autoconfiguration. This is done by sending
+ autoconfiguration requests out of all devices,
+ and using the device that received the first reply.
+
+ <autoconf> Method to use for autoconfiguration. In the case of options
+ which specify multiple autoconfiguration protocols,
+ requests are sent using all protocols, and the first one
+ to reply is used.
+
+ Only autoconfiguration protocols that have been compiled
+ into the kernel will be used, regardless of the value of
+ this option.
+
+ off or none: don't use autoconfiguration (default)
+ on or any: use any protocol available in the kernel
+ dhcp: use DHCP
+ bootp: use BOOTP
+ rarp: use RARP
+ both: use both BOOTP and RARP but not DHCP
+ (old option kept for backwards compatibility)
+
+ Default: any
-3.) Kernel loader
- -------------
-To get the kernel into memory different approaches can be used. They
-depend on what facilities are available:
+3.) Boot Loader
+ ----------
+
+To get the kernel into memory different approaches can be used.
+They depend on various facilities being available:
-3.1) Writing the kernel onto a floppy using dd:
- As always you can just write the kernel onto a floppy using dd,
- but then it's not possible to use kernel command lines at all.
- To substitute the 'root=' parameter, create a dummy device on any
- linux system with major number 0 and minor number 255 using mknod:
+3.1) Booting from a floppy using syslinux
- mknod /dev/boot255 c 0 255
+ When building kernels, an easy way to create a boot floppy that uses
+ syslinux is to use the zdisk or bzdisk make targets which use
+ and bzimage images respectively. Both targets accept the
+ FDARGS parameter which can be used to set the kernel command line.
- Then copy the kernel zImage file onto a floppy using dd:
+ e.g.
+ make bzdisk FDARGS="root=/dev/nfs"
- dd if=/usr/src/linux/arch/i386/boot/zImage of=/dev/fd0
+ Note that the user running this command will need to have
+ access to the floppy drive device, /dev/fd0
- And finally use rdev to set the root device:
+ For more information on syslinux, including how to create bootdisks
+ for prebuilt kernels, see http://syslinux.zytor.com/
- rdev /dev/fd0 /dev/boot255
+ N.B: Previously it was possible to write a kernel directly to
+ a floppy using dd, configure the boot device using rdev, and
+ boot using the resulting floppy. Linux no longer supports this
+ method of booting.
- You can then remove the dummy device /dev/boot255 again. There
- is no real device available for it.
- The other two kernel command line parameters cannot be substi-
- tuted with rdev. Therefore, using this method the kernel will
- by default use RARP and/or BOOTP, and if it gets an answer via
- RARP will mount the directory /tftpboot/<client-ip>/ as its
- root. If it got a BOOTP answer the directory name in that answer
- is used.
+3.2) Booting from a cdrom using isolinux
+
+ When building kernels, an easy way to create a bootable cdrom that
+ uses isolinux is to use the isoimage target which uses a bzimage
+ image. Like zdisk and bzdisk, this target accepts the FDARGS
+ parameter which can be used to set the kernel command line.
+
+ e.g.
+ make isoimage FDARGS="root=/dev/nfs"
+
+ The resulting iso image will be arch/<ARCH>/boot/image.iso
+ This can be written to a cdrom using a variety of tools including
+ cdrecord.
+
+ e.g.
+ cdrecord dev=ATAPI:1,0,0 arch/i386/boot/image.iso
+
+ For more information on isolinux, including how to create bootdisks
+ for prebuilt kernels, see http://syslinux.zytor.com/
3.2) Using LILO
- When using LILO you can specify all necessary command line
- parameters with the 'append=' command in the LILO configuration
- file. However, to use the 'root=' command you also need to
- set up a dummy device as described in 3.1 above. For how to use
- LILO and its 'append=' command please refer to the LILO
- documentation.
+ When using LILO all the necessary command line parameters may be
+ specified using the 'append=' directive in the LILO configuration
+ file.
+
+ However, to use the 'root=' directive you also need to create
+ a dummy root device, which may be removed after LILO is run.
+
+ mknod /dev/boot255 c 0 255
+
+ For information on configuring LILO, please refer to its documentation.
3.3) Using GRUB
- When you use GRUB, you simply append the parameters after the kernel
- specification: "kernel <kernel> <parameters>" (without the quotes).
+ When using GRUB, kernel parameter are simply appended after the kernel
+ specification: kernel <kernel> <parameters>
3.4) Using loadlin
- When you want to boot Linux from a DOS command prompt without
- having a local hard disk to mount as root, you can use loadlin.
- I was told that it works, but haven't used it myself yet. In
- general you should be able to create a kernel command line simi-
- lar to how LILO is doing it. Please refer to the loadlin docu-
- mentation for further information.
+ loadlin may be used to boot Linux from a DOS command prompt without
+ requiring a local hard disk to mount as root. This has not been
+ thoroughly tested by the authors of this document, but in general
+ it should be possible configure the kernel command line similarly
+ to the configuration of LILO.
+
+ Please refer to the loadlin documentation for further information.
3.5) Using a boot ROM
- This is probably the most elegant way of booting a diskless
- client. With a boot ROM the kernel gets loaded using the TFTP
- protocol. As far as I know, no commercial boot ROMs yet
- support booting Linux over the network, but there are two
- free implementations of a boot ROM available on sunsite.unc.edu
- and its mirrors. They are called 'netboot-nfs' and 'etherboot'.
- Both contain everything you need to boot a diskless Linux client.
+ This is probably the most elegant way of booting a diskless client.
+ With a boot ROM the kernel is loaded using the TFTP protocol. The
+ authors of this document are not aware of any no commercial boot
+ ROMs that support booting Linux over the network. However, there
+ are two free implementations of a boot ROM, netboot-nfs and
+ etherboot, both of which are available on sunsite.unc.edu, and both
+ of which contain everything you need to boot a diskless Linux client.
3.6) Using pxelinux
- Using pxelinux you specify the kernel you built with
+ Pxelinux may be used to boot linux using the PXE boot loader
+ which is present on many modern network cards.
+
+ When using pxelinux, the kernel image is specified using
"kernel <relative-path-below /tftpboot>". The nfsroot parameters
are passed to the kernel by adding them to the "append" line.
- You may perhaps also want to fine tune the console output,
- see Documentation/serial-console.txt for serial console help.
+ It is common to use serial console in conjunction with pxeliunx,
+ see Documentation/serial-console.txt for more information.
+
+ For more information on isolinux, including how to create bootdisks
+ for prebuilt kernels, see http://syslinux.zytor.com/
diff --git a/MAINTAINERS b/MAINTAINERS
index 196a31c..645a9f8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -601,6 +601,15 @@
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
S: Maintained
+CALGARY x86-64 IOMMU
+P: Muli Ben-Yehuda
+M: muli@il.ibm.com
+P: Jon D. Mason
+M: jdmason@us.ibm.com
+L: linux-kernel@vger.kernel.org
+L: discuss@x86-64.org
+S: Maintained
+
COMMON INTERNET FILE SYSTEM (CIFS)
P: Steve French
M: sfrench@samba.org
@@ -2666,6 +2675,11 @@
L: netdev@vger.kernel.org
S: Maintained
+SOEKRIS NET48XX LED SUPPORT
+P: Chris Boot
+M: bootc@bootc.net
+S: Maintained
+
SPARC (sparc32):
P: William L. Irwin
M: wli@holomorphy.com
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 4256437..f042cc42 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -14,6 +14,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/pci.h>
+#include <linux/screen_info.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <linux/delay.h>
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 41ebf51..b3a8a29 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -25,6 +25,7 @@
#include <linux/time.h>
#include <linux/major.h>
#include <linux/stat.h>
+#include <linux/vt.h>
#include <linux/mman.h>
#include <linux/elfcore.h>
#include <linux/reboot.h>
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 254c507..2cb9c43 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -19,7 +19,7 @@
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/delay.h>
#include <linux/config.h> /* CONFIG_ALPHA_LCA etc */
#include <linux/mc146818rtc.h>
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
index cd85ef7..a654014 100644
--- a/arch/alpha/kernel/sys_sio.c
+++ b/arch/alpha/kernel/sys_sio.c
@@ -16,7 +16,7 @@
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <asm/compiler.h>
#include <asm/ptrace.h>
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ed1c4d6..0a722e7 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -17,7 +17,7 @@
#include <linux/console.h>
#include <linux/bootmem.h>
#include <linux/seq_file.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/init.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
diff --git a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c
index 843c29f..e7eb070 100644
--- a/arch/arm26/kernel/setup.c
+++ b/arch/arm26/kernel/setup.c
@@ -17,7 +17,7 @@
#include <linux/console.h>
#include <linux/bootmem.h>
#include <linux/seq_file.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/init.h>
#include <linux/root_dev.h>
diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c
index 0375820..6e1f191 100644
--- a/arch/cris/arch-v10/drivers/eeprom.c
+++ b/arch/cris/arch-v10/drivers/eeprom.c
@@ -450,9 +450,9 @@
static int eeprom_open(struct inode * inode, struct file * file)
{
- if(MINOR(inode->i_rdev) != EEPROM_MINOR_NR)
+ if(iminor(inode) != EEPROM_MINOR_NR)
return -ENXIO;
- if(MAJOR(inode->i_rdev) != EEPROM_MAJOR_NR)
+ if(imajor(inode) != EEPROM_MAJOR_NR)
return -ENXIO;
if( eeprom.size > 0 )
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c
index 48fd801..fcba663 100644
--- a/arch/cris/arch-v10/drivers/gpio.c
+++ b/arch/cris/arch-v10/drivers/gpio.c
@@ -435,7 +435,7 @@
gpio_open(struct inode *inode, struct file *filp)
{
struct gpio_private *priv;
- int p = MINOR(inode->i_rdev);
+ int p = iminor(inode);
if (p > GPIO_MINOR_LAST)
return -EINVAL;
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index c59ee28..ba096eb 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -2302,7 +2302,7 @@
static int cryptocop_open(struct inode *inode, struct file *filp)
{
- int p = MINOR(inode->i_rdev);
+ int p = iminor(inode);
if (p != CRYPTOCOP_MINOR) return -EINVAL;
diff --git a/arch/cris/arch-v32/drivers/gpio.c b/arch/cris/arch-v32/drivers/gpio.c
index 00e9167..c3f876b 100644
--- a/arch/cris/arch-v32/drivers/gpio.c
+++ b/arch/cris/arch-v32/drivers/gpio.c
@@ -418,7 +418,7 @@
gpio_open(struct inode *inode, struct file *filp)
{
struct gpio_private *priv;
- int p = MINOR(inode->i_rdev);
+ int p = iminor(inode);
if (p > GPIO_MINOR_LAST)
return -EINVAL;
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index ffc6d25..2fc7d75 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -324,14 +324,12 @@
int
pcf8563_open(struct inode *inode, struct file *filp)
{
- MOD_INC_USE_COUNT;
return 0;
}
int
pcf8563_release(struct inode *inode, struct file *filp)
{
- MOD_DEC_USE_COUNT;
return 0;
}
diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c
index 7c29957..e067806 100644
--- a/arch/cris/arch-v32/drivers/sync_serial.c
+++ b/arch/cris/arch-v32/drivers/sync_serial.c
@@ -340,7 +340,7 @@
static int sync_serial_open(struct inode *inode, struct file *file)
{
- int dev = MINOR(inode->i_rdev);
+ int dev = iminor(inode);
sync_port* port;
reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
@@ -486,7 +486,7 @@
static int sync_serial_release(struct inode *inode, struct file *file)
{
- int dev = MINOR(inode->i_rdev);
+ int dev = iminor(inode);
sync_port* port;
if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
@@ -504,7 +504,7 @@
static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
{
- int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+ int dev = iminor(file->f_dentry->d_inode);
unsigned int mask = 0;
sync_port* port;
DEBUGPOLL( static unsigned int prev_mask = 0; );
@@ -531,7 +531,7 @@
unsigned int cmd, unsigned long arg)
{
int return_val = 0;
- int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+ int dev = iminor(file->f_dentry->d_inode);
sync_port* port;
reg_sser_rw_tr_cfg tr_cfg;
reg_sser_rw_rec_cfg rec_cfg;
@@ -789,7 +789,7 @@
static ssize_t sync_serial_write(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
- int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+ int dev = iminor(file->f_dentry->d_inode);
DECLARE_WAITQUEUE(wait, current);
sync_port *port;
unsigned long c, c1;
@@ -919,7 +919,7 @@
static ssize_t sync_serial_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
- int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+ int dev = iminor(file->f_dentry->d_inode);
int avail;
sync_port *port;
unsigned char* start;
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 6d941fb..7af3d5d 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -15,7 +15,7 @@
#include <linux/bootmem.h>
#include <asm/pgtable.h>
#include <linux/seq_file.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/utsname.h>
#include <linux/pfn.h>
diff --git a/arch/frv/kernel/asm-offsets.c b/arch/frv/kernel/asm-offsets.c
index 9e26311..fbb19fc 100644
--- a/arch/frv/kernel/asm-offsets.c
+++ b/arch/frv/kernel/asm-offsets.c
@@ -1 +1,115 @@
-/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed
+ * to extract and format the required data.
+ */
+
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/personality.h>
+#include <asm/registers.h>
+#include <asm/ucontext.h>
+#include <asm/processor.h>
+#include <asm/thread_info.h>
+#include <asm/gdb-stub.h>
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define DEF_PTREG(sym, reg) \
+ asm volatile("\n->" #sym " %0 offsetof(struct pt_regs, " #reg ")" \
+ : : "i" (offsetof(struct pt_regs, reg)))
+
+#define DEF_IREG(sym, reg) \
+ asm volatile("\n->" #sym " %0 offsetof(struct user_context, " #reg ")" \
+ : : "i" (offsetof(struct user_context, reg)))
+
+#define DEF_FREG(sym, reg) \
+ asm volatile("\n->" #sym " %0 offsetof(struct user_context, " #reg ")" \
+ : : "i" (offsetof(struct user_context, reg)))
+
+#define DEF_0REG(sym, reg) \
+ asm volatile("\n->" #sym " %0 offsetof(struct frv_frame0, " #reg ")" \
+ : : "i" (offsetof(struct frv_frame0, reg)))
+
+#define BLANK() asm volatile("\n->" : : )
+
+#define OFFSET(sym, str, mem) \
+ DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+ /* offsets into the thread_info structure */
+ OFFSET(TI_TASK, thread_info, task);
+ OFFSET(TI_EXEC_DOMAIN, thread_info, exec_domain);
+ OFFSET(TI_FLAGS, thread_info, flags);
+ OFFSET(TI_STATUS, thread_info, status);
+ OFFSET(TI_CPU, thread_info, cpu);
+ OFFSET(TI_PREEMPT_COUNT, thread_info, preempt_count);
+ OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
+ OFFSET(TI_RESTART_BLOCK, thread_info, restart_block);
+ BLANK();
+
+ /* offsets into register file storage */
+ DEF_PTREG(REG_PSR, psr);
+ DEF_PTREG(REG_ISR, isr);
+ DEF_PTREG(REG_CCR, ccr);
+ DEF_PTREG(REG_CCCR, cccr);
+ DEF_PTREG(REG_LR, lr);
+ DEF_PTREG(REG_LCR, lcr);
+ DEF_PTREG(REG_PC, pc);
+ DEF_PTREG(REG__STATUS, __status);
+ DEF_PTREG(REG_SYSCALLNO, syscallno);
+ DEF_PTREG(REG_ORIG_GR8, orig_gr8);
+ DEF_PTREG(REG_GNER0, gner0);
+ DEF_PTREG(REG_GNER1, gner1);
+ DEF_PTREG(REG_IACC0, iacc0);
+ DEF_PTREG(REG_TBR, tbr);
+ DEF_PTREG(REG_GR0, tbr);
+ DEFINE(REG__END, sizeof(struct pt_regs));
+ BLANK();
+
+ DEF_0REG(REG_DCR, debug.dcr);
+ DEF_0REG(REG_IBAR0, debug.ibar[0]);
+ DEF_0REG(REG_DBAR0, debug.dbar[0]);
+ DEF_0REG(REG_DBDR00, debug.dbdr[0][0]);
+ DEF_0REG(REG_DBMR00, debug.dbmr[0][0]);
+ BLANK();
+
+ DEF_IREG(__INT_GR0, i.gr[0]);
+ DEF_FREG(__USER_FPMEDIA, f);
+ DEF_FREG(__FPMEDIA_FR0, f.fr[0]);
+ DEF_FREG(__FPMEDIA_FNER0, f.fner[0]);
+ DEF_FREG(__FPMEDIA_MSR0, f.msr[0]);
+ DEF_FREG(__FPMEDIA_ACC0, f.acc[0]);
+ DEF_FREG(__FPMEDIA_ACCG0, f.accg[0]);
+ DEF_FREG(__FPMEDIA_FSR0, f.fsr[0]);
+ BLANK();
+
+ DEFINE(NR_PT_REGS, sizeof(struct pt_regs) / 4);
+ DEFINE(NR_USER_INT_REGS, sizeof(struct user_int_regs) / 4);
+ DEFINE(NR_USER_FPMEDIA_REGS, sizeof(struct user_fpmedia_regs) / 4);
+ DEFINE(NR_USER_CONTEXT, sizeof(struct user_context) / 4);
+ DEFINE(FRV_FRAME0_SIZE, sizeof(struct frv_frame0));
+ BLANK();
+
+ /* offsets into thread_struct */
+ OFFSET(__THREAD_FRAME, thread_struct, frame);
+ OFFSET(__THREAD_CURR, thread_struct, curr);
+ OFFSET(__THREAD_SP, thread_struct, sp);
+ OFFSET(__THREAD_FP, thread_struct, fp);
+ OFFSET(__THREAD_LR, thread_struct, lr);
+ OFFSET(__THREAD_PC, thread_struct, pc);
+ OFFSET(__THREAD_GR16, thread_struct, gr[0]);
+ OFFSET(__THREAD_SCHED_LR, thread_struct, sched_lr);
+ OFFSET(__THREAD_FRAME0, thread_struct, frame0);
+ OFFSET(__THREAD_USER, thread_struct, user);
+ BLANK();
+
+ /* offsets into frv_debug_status */
+ OFFSET(DEBUG_BPSR, frv_debug_status, bpsr);
+ OFFSET(DEBUG_DCR, frv_debug_status, dcr);
+ OFFSET(DEBUG_BRR, frv_debug_status, brr);
+ OFFSET(DEBUG_NMAR, frv_debug_status, nmar);
+ BLANK();
+}
diff --git a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S
index ea161f0..dac4a5f 100644
--- a/arch/frv/kernel/break.S
+++ b/arch/frv/kernel/break.S
@@ -9,11 +9,11 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/sys.h>
#include <linux/linkage.h>
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/ptrace.h>
+#include <asm/thread_info.h>
#include <asm/spr-regs.h>
#include <asm/errno.h>
@@ -23,13 +23,11 @@
#
.section .bss.stack
.globl __break_user_context
- .balign 8192
+ .balign THREAD_SIZE
__break_stack:
- .space (8192 - (USER_CONTEXT_SIZE + REG__DEBUG_XTRA)) & ~7
-__break_stack_tos:
- .space REG__DEBUG_XTRA
-__break_user_context:
- .space USER_CONTEXT_SIZE
+ .space THREAD_SIZE - FRV_FRAME0_SIZE
+__break_frame_0:
+ .space FRV_FRAME0_SIZE
#
# miscellaneous variables
@@ -74,8 +72,8 @@
#endif
LEDS 0x1001,gr31
- sethi.p %hi(__break_user_context),gr31
- setlo %lo(__break_user_context),gr31
+ sethi.p %hi(__break_frame_0),gr31
+ setlo %lo(__break_frame_0),gr31
stdi gr2,@(gr31,#REG_GR(2))
movsg ccr,gr3
@@ -585,8 +583,8 @@
# set up the kernel stack pointer
sti sp,@(gr31,#REG_SP)
- sethi.p %hi(__break_stack_tos),sp
- setlo %lo(__break_stack_tos),sp
+ sethi.p %hi(__break_frame_0),sp
+ setlo %lo(__break_frame_0),sp
# finish building the exception frame
stdi gr4 ,@(gr31,#REG_GR(4))
@@ -651,9 +649,12 @@
movsg nmar,gr5
movsg dcr,gr6
- stdi gr4 ,@(gr31,#REG_BRR)
- sti gr19,@(gr31,#REG_BPSR)
- sti.p gr6 ,@(gr31,#REG_DCR)
+ sethi.p %hi(__debug_status),gr7
+ setlo %lo(__debug_status),gr7
+
+ stdi gr4 ,@(gr7,#DEBUG_BRR)
+ sti gr19,@(gr7,#DEBUG_BPSR)
+ sti.p gr6 ,@(gr7,#DEBUG_DCR)
# trap exceptions during break handling and disable h/w breakpoints/watchpoints
sethi %hi(DCR_EBE),gr5
@@ -698,7 +699,10 @@
lddi @(gr31,#REG_PSR) ,gr22
ldi @(gr31,#REG_PC) ,gr21
ldi @(gr31,#REG_TBR) ,gr20
- ldi.p @(gr31,#REG_DCR) ,gr6
+
+ sethi.p %hi(__debug_status),gr6
+ setlo %lo(__debug_status),gr6
+ ldi.p @(gr6,#DEBUG_DCR) ,gr6
andi gr22,#PSR_S,gr19 /* rebuild BPSR */
andi.p gr22,#PSR_ET,gr5
diff --git a/arch/frv/kernel/debug-stub.c b/arch/frv/kernel/debug-stub.c
index 4761cc4..2f6c60c 100644
--- a/arch/frv/kernel/debug-stub.c
+++ b/arch/frv/kernel/debug-stub.c
@@ -39,10 +39,9 @@
gdbstub_do_rx(); \
} while(!FLOWCTL_QUERY(LINE))
-static void __init debug_stub_init(void);
+struct frv_debug_status __debug_status;
-extern asmlinkage void __break_hijack_kernel_event(void);
-extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
+static void __init debug_stub_init(void);
/*****************************************************************************/
/*
@@ -67,7 +66,7 @@
__set_HSR(0, hsr0 & ~HSR0_ETMD);
/* disable single stepping */
- __debug_regs->dcr &= ~DCR_SE;
+ __debug_status.dcr &= ~DCR_SE;
/* kernel mode can propose an exception be handled in debug mode by jumping to a special
* location */
@@ -76,8 +75,8 @@
* the top kernel context */
*__debug_frame = *__frame;
__frame = __debug_frame->next_frame;
- __debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
- __debug_regs->brr |= BRR_EB;
+ __debug_status.brr = (__debug_frame->tbr & TBR_TT) << 12;
+ __debug_status.brr |= BRR_EB;
}
if (__debug_frame->pc == (unsigned long) __debug_bug_trap + 4) {
@@ -124,7 +123,7 @@
__debug_frame->pc = (unsigned long) start_kernel;
/* enable the debug events we want to trap */
- __debug_regs->dcr = DCR_EBE;
+ __debug_status.dcr = DCR_EBE;
#ifdef CONFIG_GDBSTUB
gdbstub_init();
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 2a1ff1f..940ac30 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -27,7 +27,6 @@
*
*/
-#include <linux/sys.h>
#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/setup.h>
diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c
index 508601f..9550f37 100644
--- a/arch/frv/kernel/gdb-stub.c
+++ b/arch/frv/kernel/gdb-stub.c
@@ -124,6 +124,7 @@
#include <linux/slab.h>
#include <linux/nmi.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/gdb-stub.h>
@@ -136,7 +137,6 @@
extern void gdbstub_console_write(struct console *co, const char *p, unsigned n);
extern volatile uint32_t __break_error_detect[3]; /* ESFR1, ESR15, EAR15 */
-extern struct user_context __break_user_context;
struct __debug_amr {
unsigned long L, P;
@@ -926,6 +926,7 @@
if (!(__debug_regs->dcr & DCR_IBE0)) {
//gdbstub_printk("set h/w break 0: %08lx\n", addr);
__debug_regs->dcr |= DCR_IBE0;
+ __debug_regs->ibar[0] = addr;
asm volatile("movgs %0,ibar0" : : "r"(addr));
return 0;
}
@@ -933,6 +934,7 @@
if (!(__debug_regs->dcr & DCR_IBE1)) {
//gdbstub_printk("set h/w break 1: %08lx\n", addr);
__debug_regs->dcr |= DCR_IBE1;
+ __debug_regs->ibar[1] = addr;
asm volatile("movgs %0,ibar1" : : "r"(addr));
return 0;
}
@@ -940,6 +942,7 @@
if (!(__debug_regs->dcr & DCR_IBE2)) {
//gdbstub_printk("set h/w break 2: %08lx\n", addr);
__debug_regs->dcr |= DCR_IBE2;
+ __debug_regs->ibar[2] = addr;
asm volatile("movgs %0,ibar2" : : "r"(addr));
return 0;
}
@@ -947,6 +950,7 @@
if (!(__debug_regs->dcr & DCR_IBE3)) {
//gdbstub_printk("set h/w break 3: %08lx\n", addr);
__debug_regs->dcr |= DCR_IBE3;
+ __debug_regs->ibar[3] = addr;
asm volatile("movgs %0,ibar3" : : "r"(addr));
return 0;
}
@@ -971,7 +975,14 @@
if (!(__debug_regs->dcr & (DCR_DRBE0|DCR_DWBE0))) {
//gdbstub_printk("set h/w watchpoint 0 type %ld: %08lx\n", type, addr);
tmp = type==2 ? DCR_DWBE0 : type==3 ? DCR_DRBE0 : DCR_DRBE0|DCR_DWBE0;
+
__debug_regs->dcr |= tmp;
+ __debug_regs->dbar[0] = addr;
+ __debug_regs->dbmr[0][0] = dbmr.mask0;
+ __debug_regs->dbmr[0][1] = dbmr.mask1;
+ __debug_regs->dbdr[0][0] = 0;
+ __debug_regs->dbdr[0][1] = 0;
+
asm volatile(" movgs %0,dbar0 \n"
" movgs %1,dbmr00 \n"
" movgs %2,dbmr01 \n"
@@ -984,7 +995,14 @@
if (!(__debug_regs->dcr & (DCR_DRBE1|DCR_DWBE1))) {
//gdbstub_printk("set h/w watchpoint 1 type %ld: %08lx\n", type, addr);
tmp = type==2 ? DCR_DWBE1 : type==3 ? DCR_DRBE1 : DCR_DRBE1|DCR_DWBE1;
+
__debug_regs->dcr |= tmp;
+ __debug_regs->dbar[1] = addr;
+ __debug_regs->dbmr[1][0] = dbmr.mask0;
+ __debug_regs->dbmr[1][1] = dbmr.mask1;
+ __debug_regs->dbdr[1][0] = 0;
+ __debug_regs->dbdr[1][1] = 0;
+
asm volatile(" movgs %0,dbar1 \n"
" movgs %1,dbmr10 \n"
" movgs %2,dbmr11 \n"
@@ -1047,6 +1065,7 @@
if (__debug_regs->dcr & DCR_IBE0 && __get_ibar(0) == addr) {
//gdbstub_printk("clear h/w break 0: %08lx\n", addr);
__debug_regs->dcr &= ~DCR_IBE0;
+ __debug_regs->ibar[0] = 0;
asm volatile("movgs gr0,ibar0");
return 0;
}
@@ -1054,6 +1073,7 @@
if (__debug_regs->dcr & DCR_IBE1 && __get_ibar(1) == addr) {
//gdbstub_printk("clear h/w break 1: %08lx\n", addr);
__debug_regs->dcr &= ~DCR_IBE1;
+ __debug_regs->ibar[1] = 0;
asm volatile("movgs gr0,ibar1");
return 0;
}
@@ -1061,6 +1081,7 @@
if (__debug_regs->dcr & DCR_IBE2 && __get_ibar(2) == addr) {
//gdbstub_printk("clear h/w break 2: %08lx\n", addr);
__debug_regs->dcr &= ~DCR_IBE2;
+ __debug_regs->ibar[2] = 0;
asm volatile("movgs gr0,ibar2");
return 0;
}
@@ -1068,6 +1089,7 @@
if (__debug_regs->dcr & DCR_IBE3 && __get_ibar(3) == addr) {
//gdbstub_printk("clear h/w break 3: %08lx\n", addr);
__debug_regs->dcr &= ~DCR_IBE3;
+ __debug_regs->ibar[3] = 0;
asm volatile("movgs gr0,ibar3");
return 0;
}
@@ -1104,6 +1126,12 @@
//gdbstub_printk("clear h/w watchpoint 0 type %ld: %08lx\n", type, addr);
__debug_regs->dcr &= ~(DCR_DRBE0|DCR_DWBE0);
+ __debug_regs->dbar[0] = 0;
+ __debug_regs->dbmr[0][0] = 0;
+ __debug_regs->dbmr[0][1] = 0;
+ __debug_regs->dbdr[0][0] = 0;
+ __debug_regs->dbdr[0][1] = 0;
+
asm volatile(" movgs gr0,dbar0 \n"
" movgs gr0,dbmr00 \n"
" movgs gr0,dbmr01 \n"
@@ -1123,6 +1151,12 @@
//gdbstub_printk("clear h/w watchpoint 1 type %ld: %08lx\n", type, addr);
__debug_regs->dcr &= ~(DCR_DRBE1|DCR_DWBE1);
+ __debug_regs->dbar[1] = 0;
+ __debug_regs->dbmr[1][0] = 0;
+ __debug_regs->dbmr[1][1] = 0;
+ __debug_regs->dbdr[1][0] = 0;
+ __debug_regs->dbdr[1][1] = 0;
+
asm volatile(" movgs gr0,dbar1 \n"
" movgs gr0,dbmr10 \n"
" movgs gr0,dbmr11 \n"
@@ -1163,7 +1197,7 @@
*/
static void __attribute__((unused)) gdbstub_show_regs(void)
{
- uint32_t *reg;
+ unsigned long *reg;
int loop;
gdbstub_printk("\n");
@@ -1172,11 +1206,11 @@
__debug_frame,
__debug_frame->psr & PSR_S ? "kernel" : "user");
- reg = (uint32_t *) __debug_frame;
- for (loop = 0; loop < REG__END; loop++) {
- printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+ reg = (unsigned long *) __debug_frame;
+ for (loop = 0; loop < NR_PT_REGS; loop++) {
+ printk("%s %08lx", regnames[loop + 0], reg[loop + 0]);
- if (loop == REG__END - 1 || loop % 5 == 4)
+ if (loop == NR_PT_REGS - 1 || loop % 5 == 4)
printk("\n");
else
printk(" | ");
@@ -1191,13 +1225,8 @@
*/
static void __attribute__((unused)) gdbstub_dump_debugregs(void)
{
- unsigned long x;
-
- x = __debug_regs->dcr;
- gdbstub_printk("DCR %08lx ", x);
-
- x = __debug_regs->brr;
- gdbstub_printk("BRR %08lx\n", x);
+ gdbstub_printk("DCR %08lx ", __debug_status.dcr);
+ gdbstub_printk("BRR %08lx\n", __debug_status.brr);
gdbstub_printk("IBAR0 %08lx ", __get_ibar(0));
gdbstub_printk("IBAR1 %08lx ", __get_ibar(1));
@@ -1360,7 +1389,7 @@
#endif
}
- save_user_regs(&__break_user_context);
+ save_user_regs(&__debug_frame0->uc);
#if 0
gdbstub_printk("--> gdbstub() %08x %p %08x %08x\n",
@@ -1389,8 +1418,8 @@
__debug_frame->psr &= ~PSR_S;
if (__debug_frame->psr & PSR_PS)
__debug_frame->psr |= PSR_S;
- __debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
- __debug_regs->brr |= BRR_EB;
+ __debug_status.brr = (__debug_frame->tbr & TBR_TT) << 12;
+ __debug_status.brr |= BRR_EB;
sigval = SIGINT;
}
@@ -1404,15 +1433,15 @@
__debug_frame->psr &= ~PSR_S;
if (__debug_frame->psr & PSR_PS)
__debug_frame->psr |= PSR_S;
- __debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
- __debug_regs->brr |= BRR_EB;
+ __debug_status.brr = (__debug_frame->tbr & TBR_TT) << 12;
+ __debug_status.brr |= BRR_EB;
sigval = SIGXCPU;
}
LEDS(0x5002);
/* after a BREAK insn, the PC lands on the far side of it */
- if (__debug_regs->brr & BRR_SB)
+ if (__debug_status.brr & BRR_SB)
gdbstub_check_breakpoint();
LEDS(0x5003);
@@ -1431,7 +1460,7 @@
}
if (!sigval)
- sigval = gdbstub_compute_signal(__debug_regs->brr);
+ sigval = gdbstub_compute_signal(__debug_status.brr);
LEDS(0x5004);
@@ -1441,7 +1470,7 @@
if (sigval != SIGINT && sigval != SIGTRAP && sigval != SIGILL) {
static const char title[] = "Break ";
static const char crlf[] = "\r\n";
- unsigned long brr = __debug_regs->brr;
+ unsigned long brr = __debug_status.brr;
char hx;
ptr = output_buffer;
@@ -1565,28 +1594,24 @@
ptr = mem2hex(&zero, ptr, 4, 0);
for (loop = 1; loop <= 27; loop++)
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),
- ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[loop], ptr, 4, 0);
temp = (unsigned long) __frame;
ptr = mem2hex(&temp, ptr, 4, 0);
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(29), ptr, 4, 0);
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(30), ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[29], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[30], ptr, 4, 0);
#ifdef CONFIG_MMU
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(31), ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[31], ptr, 4, 0);
#else
temp = (unsigned long) __debug_frame;
ptr = mem2hex(&temp, ptr, 4, 0);
#endif
for (loop = 32; loop <= 63; loop++)
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),
- ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[loop], ptr, 4, 0);
/* deal with FR0-FR63 */
for (loop = 0; loop <= 63; loop++)
- ptr = mem2hex((unsigned long *)&__break_user_context +
- __FPMEDIA_FR(loop),
- ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fr[loop], ptr, 4, 0);
/* deal with special registers */
ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0);
@@ -1597,7 +1622,7 @@
ptr = mem2hex(&zero, ptr, 4, 0);
ptr = mem2hex(&zero, ptr, 4, 0);
ptr = mem2hex(&__debug_frame->tbr, ptr, 4, 0);
- ptr = mem2hex(&__debug_regs->brr , ptr, 4, 0);
+ ptr = mem2hex(&__debug_status.brr , ptr, 4, 0);
asm volatile("movsg dbar0,%0" : "=r"(dbar));
ptr = mem2hex(&dbar, ptr, 4, 0);
@@ -1622,21 +1647,21 @@
ptr = mem2hex(&__debug_frame->iacc0, ptr, 8, 0);
- ptr = mem2hex(&__break_user_context.f.fsr[0], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fsr[0], ptr, 4, 0);
for (loop = 0; loop <= 7; loop++)
- ptr = mem2hex(&__break_user_context.f.acc[loop], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.acc[loop], ptr, 4, 0);
- ptr = mem2hex(&__break_user_context.f.accg, ptr, 8, 0);
+ ptr = mem2hex(&__debug_user_context->f.accg, ptr, 8, 0);
for (loop = 0; loop <= 1; loop++)
- ptr = mem2hex(&__break_user_context.f.msr[loop], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.msr[loop], ptr, 4, 0);
ptr = mem2hex(&__debug_frame->gner0, ptr, 4, 0);
ptr = mem2hex(&__debug_frame->gner1, ptr, 4, 0);
- ptr = mem2hex(&__break_user_context.f.fner[0], ptr, 4, 0);
- ptr = mem2hex(&__break_user_context.f.fner[1], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fner[0], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fner[1], ptr, 4, 0);
break;
@@ -1648,8 +1673,7 @@
ptr = hex2mem(ptr, &temp, 4);
for (loop = 1; loop <= 27; loop++)
- ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),
- 4);
+ ptr = hex2mem(ptr, &__debug_user_context->i.gr[loop], 4);
ptr = hex2mem(ptr, &temp, 4);
__frame = (struct pt_regs *) temp;
@@ -1662,14 +1686,11 @@
#endif
for (loop = 32; loop <= 63; loop++)
- ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),
- 4);
+ ptr = hex2mem(ptr, &__debug_user_context->i.gr[loop], 4);
/* deal with FR0-FR63 */
for (loop = 0; loop <= 63; loop++)
- ptr = mem2hex((unsigned long *)&__break_user_context +
- __FPMEDIA_FR(loop),
- ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fr[loop], ptr, 4, 0);
/* deal with special registers */
ptr = hex2mem(ptr, &__debug_frame->pc, 4);
@@ -1694,21 +1715,21 @@
ptr = hex2mem(ptr, &__debug_frame->iacc0, 8);
- ptr = hex2mem(ptr, &__break_user_context.f.fsr[0], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.fsr[0], 4);
for (loop = 0; loop <= 7; loop++)
- ptr = hex2mem(ptr, &__break_user_context.f.acc[loop], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.acc[loop], 4);
- ptr = hex2mem(ptr, &__break_user_context.f.accg, 8);
+ ptr = hex2mem(ptr, &__debug_user_context->f.accg, 8);
for (loop = 0; loop <= 1; loop++)
- ptr = hex2mem(ptr, &__break_user_context.f.msr[loop], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.msr[loop], 4);
ptr = hex2mem(ptr, &__debug_frame->gner0, 4);
ptr = hex2mem(ptr, &__debug_frame->gner1, 4);
- ptr = hex2mem(ptr, &__break_user_context.f.fner[0], 4);
- ptr = hex2mem(ptr, &__break_user_context.f.fner[1], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.fner[0], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.fner[1], 4);
gdbstub_strcpy(output_buffer,"OK");
break;
@@ -1769,52 +1790,52 @@
case GDB_REG_GR(0):
break;
case GDB_REG_GR(1) ... GDB_REG_GR(63):
- __break_user_context.i.gr[addr - GDB_REG_GR(0)] = temp;
+ __debug_user_context->i.gr[addr - GDB_REG_GR(0)] = temp;
break;
case GDB_REG_FR(0) ... GDB_REG_FR(63):
- __break_user_context.f.fr[addr - GDB_REG_FR(0)] = temp;
+ __debug_user_context->f.fr[addr - GDB_REG_FR(0)] = temp;
break;
case GDB_REG_PC:
- __break_user_context.i.pc = temp;
+ __debug_user_context->i.pc = temp;
break;
case GDB_REG_PSR:
- __break_user_context.i.psr = temp;
+ __debug_user_context->i.psr = temp;
break;
case GDB_REG_CCR:
- __break_user_context.i.ccr = temp;
+ __debug_user_context->i.ccr = temp;
break;
case GDB_REG_CCCR:
- __break_user_context.i.cccr = temp;
+ __debug_user_context->i.cccr = temp;
break;
case GDB_REG_BRR:
- __debug_regs->brr = temp;
+ __debug_status.brr = temp;
break;
case GDB_REG_LR:
- __break_user_context.i.lr = temp;
+ __debug_user_context->i.lr = temp;
break;
case GDB_REG_LCR:
- __break_user_context.i.lcr = temp;
+ __debug_user_context->i.lcr = temp;
break;
case GDB_REG_FSR0:
- __break_user_context.f.fsr[0] = temp;
+ __debug_user_context->f.fsr[0] = temp;
break;
case GDB_REG_ACC(0) ... GDB_REG_ACC(7):
- __break_user_context.f.acc[addr - GDB_REG_ACC(0)] = temp;
+ __debug_user_context->f.acc[addr - GDB_REG_ACC(0)] = temp;
break;
case GDB_REG_ACCG(0):
- *(uint32_t *) &__break_user_context.f.accg[0] = temp;
+ *(uint32_t *) &__debug_user_context->f.accg[0] = temp;
break;
case GDB_REG_ACCG(4):
- *(uint32_t *) &__break_user_context.f.accg[4] = temp;
+ *(uint32_t *) &__debug_user_context->f.accg[4] = temp;
break;
case GDB_REG_MSR(0) ... GDB_REG_MSR(1):
- __break_user_context.f.msr[addr - GDB_REG_MSR(0)] = temp;
+ __debug_user_context->f.msr[addr - GDB_REG_MSR(0)] = temp;
break;
case GDB_REG_GNER(0) ... GDB_REG_GNER(1):
- __break_user_context.i.gner[addr - GDB_REG_GNER(0)] = temp;
+ __debug_user_context->i.gner[addr - GDB_REG_GNER(0)] = temp;
break;
case GDB_REG_FNER(0) ... GDB_REG_FNER(1):
- __break_user_context.f.fner[addr - GDB_REG_FNER(0)] = temp;
+ __debug_user_context->f.fner[addr - GDB_REG_FNER(0)] = temp;
break;
default:
temp2 = 0;
@@ -1850,6 +1871,7 @@
/* step to next instruction */
case 's':
__debug_regs->dcr |= DCR_SE;
+ __debug_status.dcr |= DCR_SE;
goto done;
/* set baud rate (bBB) */
@@ -1934,7 +1956,7 @@
}
done:
- restore_user_regs(&__break_user_context);
+ restore_user_regs(&__debug_frame0->uc);
//gdbstub_dump_debugregs();
//gdbstub_printk("<-- gdbstub() %08x\n", __debug_frame->pc);
@@ -1966,7 +1988,6 @@
#endif
gdbstub_printk("%s", gdbstub_banner);
- gdbstub_printk("DCR: %x\n", __debug_regs->dcr);
gdbstub_io_init();
diff --git a/arch/frv/kernel/head.S b/arch/frv/kernel/head.S
index 47c990a..fecf751 100644
--- a/arch/frv/kernel/head.S
+++ b/arch/frv/kernel/head.S
@@ -11,6 +11,7 @@
#include <linux/threads.h>
#include <linux/linkage.h>
+#include <asm/thread_info.h>
#include <asm/ptrace.h>
#include <asm/page.h>
#include <asm/spr-regs.h>
diff --git a/arch/frv/kernel/local.h b/arch/frv/kernel/local.h
index e947176..76606d1 100644
--- a/arch/frv/kernel/local.h
+++ b/arch/frv/kernel/local.h
@@ -51,6 +51,9 @@
/* time.c */
extern void time_divisor_init(void);
+/* cmode.S */
+extern asmlinkage void frv_change_cmode(int);
+
#endif /* __ASSEMBLY__ */
#endif /* _FRV_LOCAL_H */
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index e65a9f1..c1d9fc8 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -26,11 +26,6 @@
#include "local.h"
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
-extern void frv_change_cmode(int);
-
/*
* Debug macros
*/
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index eeeb1e2..515a5ce 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -10,6 +10,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -25,6 +26,7 @@
#include <linux/reboot.h>
#include <linux/interrupt.h>
+#include <asm/asm-offsets.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/setup.h>
@@ -38,6 +40,9 @@
#include <asm/pgalloc.h>
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
struct task_struct *alloc_task_struct(void)
{
struct task_struct *p = kmalloc(THREAD_SIZE, GFP_KERNEL);
@@ -203,7 +208,7 @@
regs0 = __kernel_frame0_ptr;
childregs0 = (struct pt_regs *)
- (task_stack_page(p) + THREAD_SIZE - USER_CONTEXT_SIZE);
+ (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
childregs = childregs0;
/* set up the userspace frame (the only place that the USP is stored) */
@@ -367,3 +372,11 @@
return 1;
}
+
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
+{
+ memcpy(fpregs,
+ ¤t->thread.user->f,
+ sizeof(current->thread.user->f));
+ return 1;
+}
diff --git a/arch/frv/kernel/switch_to.S b/arch/frv/kernel/switch_to.S
index 9e5a583..b5275fa 100644
--- a/arch/frv/kernel/switch_to.S
+++ b/arch/frv/kernel/switch_to.S
@@ -11,6 +11,7 @@
# 2 of the License, or (at your option) any later version.
#
###############################################################################
+
#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/processor.h>
@@ -30,7 +31,7 @@
# address of frame 0 (userspace) on current kernel stack
.globl __kernel_frame0_ptr
__kernel_frame0_ptr:
- .long init_thread_union + THREAD_SIZE - USER_CONTEXT_SIZE
+ .long init_thread_union + THREAD_SIZE - FRV_FRAME0_SIZE
# address of current task
.globl __kernel_current_task
diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c
index 98ce362..2e6098c 100644
--- a/arch/frv/kernel/traps.c
+++ b/arch/frv/kernel/traps.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <asm/asm-offsets.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/system.h>
@@ -279,20 +280,20 @@
void show_regs(struct pt_regs *regs)
{
- uint32_t *reg;
+ unsigned long *reg;
int loop;
printk("\n");
- printk("Frame: @%08x [%s]\n",
- (uint32_t) regs,
+ printk("Frame: @%08lx [%s]\n",
+ (unsigned long) regs,
regs->psr & PSR_S ? "kernel" : "user");
- reg = (uint32_t *) regs;
- for (loop = 0; loop < REG__END; loop++) {
- printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+ reg = (unsigned long *) regs;
+ for (loop = 0; loop < NR_PT_REGS; loop++) {
+ printk("%s %08lx", regnames[loop + 0], reg[loop + 0]);
- if (loop == REG__END - 1 || loop % 5 == 4)
+ if (loop == NR_PT_REGS - 1 || loop % 5 == 4)
printk("\n");
else
printk(" | ");
@@ -328,7 +329,7 @@
*/
static void show_backtrace_regs(struct pt_regs *frame)
{
- uint32_t *reg;
+ unsigned long *reg;
int loop;
/* print the registers for this frame */
@@ -336,11 +337,11 @@
frame->psr & PSR_S ? "Kernel Mode" : "User Mode",
frame);
- reg = (uint32_t *) frame;
- for (loop = 0; loop < REG__END; loop++) {
- printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+ reg = (unsigned long *) frame;
+ for (loop = 0; loop < NR_PT_REGS; loop++) {
+ printk("%s %08lx", regnames[loop + 0], reg[loop + 0]);
- if (loop == REG__END - 1 || loop % 5 == 4)
+ if (loop == NR_PT_REGS - 1 || loop % 5 == 4)
printk("\n");
else
printk(" | ");
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index fb98e90..f7279d7 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -406,7 +406,9 @@
ioport_resource.end = (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff;
ioport_resource.end += ioport_resource.start;
- printk("PCI IO window: %08lx-%08lx\n", ioport_resource.start, ioport_resource.end);
+ printk("PCI IO window: %08llx-%08llx\n",
+ (unsigned long long) ioport_resource.start,
+ (unsigned long long) ioport_resource.end);
iomem_resource.start = (__reg_MB86943_sl_pci_mem_base << 9) & 0xfffffc00;
@@ -416,8 +418,11 @@
iomem_resource.end = (__reg_MB86943_sl_pci_mem_range << 9) | 0x3ff;
iomem_resource.end += iomem_resource.start;
- printk("PCI MEM window: %08lx-%08lx\n", iomem_resource.start, iomem_resource.end);
- printk("PCI DMA memory: %08lx-%08lx\n", dma_coherent_mem_start, dma_coherent_mem_end);
+ printk("PCI MEM window: %08llx-%08llx\n",
+ (unsigned long long) iomem_resource.start,
+ (unsigned long long) iomem_resource.end);
+ printk("PCI DMA memory: %08lx-%08lx\n",
+ dma_coherent_mem_start, dma_coherent_mem_end);
if (!pci_probe)
return -ENXIO;
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 1629c3a..89ebb7a 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -197,7 +197,7 @@
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
CONFIG_SOFTWARE_SUSPEND=y
-CONFIG_PM_STD_PARTITION="/dev/hda2"
+CONFIG_PM_STD_PARTITION=""
#
# ACPI (Advanced Configuration and Power Interface) Support
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 08c00d2..7864395 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -26,7 +26,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/ioport.h>
#include <linux/acpi.h>
#include <linux/apm_bios.h>
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 316421a..8705c0f 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -206,15 +206,16 @@
unsigned long get_cmos_time(void)
{
unsigned long retval;
+ unsigned long flags;
- spin_lock(&rtc_lock);
+ spin_lock_irqsave(&rtc_lock, flags);
if (efi_enabled)
retval = efi_get_time();
else
retval = mach_get_cmos_time();
- spin_unlock(&rtc_lock);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return retval;
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 2bf8b55..5cfd4f42 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -100,13 +100,13 @@
vmalloc_sync_all();
return atomic_notifier_chain_register(&i386die_chain, nb);
}
-EXPORT_SYMBOL(register_die_notifier);
+EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
int unregister_die_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(&i386die_chain, nb);
}
-EXPORT_SYMBOL(unregister_die_notifier);
+EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
{
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index fa8a37b..c8c1df8 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -13,6 +13,7 @@
#include <linux/oprofile.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
+#include <linux/moduleparam.h>
#include <asm/nmi.h>
#include <asm/msr.h>
#include <asm/apic.h>
@@ -296,12 +297,14 @@
return 0;
}
+static int p4force;
+module_param(p4force, int, 0);
static int __init p4_init(char ** cpu_type)
{
__u8 cpu_model = boot_cpu_data.x86_model;
- if (cpu_model > 4)
+ if (!p4force && (cpu_model > 6 || cpu_model == 5))
return 0;
#ifndef CONFIG_SMP
diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
index 5ab12b8..9196b33 100644
--- a/arch/ia64/dig/setup.c
+++ b/arch/ia64/dig/setup.c
@@ -14,7 +14,7 @@
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/string.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/console.h>
#include <linux/timex.h>
#include <linux/sched.h>
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index b13c055..e4bfa9d 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -759,7 +759,7 @@
}
int
-valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long size)
+valid_mmap_phys_addr_range (unsigned long pfn, unsigned long size)
{
/*
* MMIO regions are often missing from the EFI memory map.
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 6a33f41..7ad0d9c 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -35,7 +35,7 @@
#include <linux/seq_file.h>
#include <linux/string.h>
#include <linux/threads.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/dmi.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 276512f..60b45e7 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -650,7 +650,7 @@
* Avoid attribute aliasing. See Documentation/ia64/aliasing.txt
* for more details.
*/
- if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, size))
+ if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
return -EINVAL;
prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
vma->vm_page_prot);
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index dd6bcf4..c119e8b 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -12,7 +12,7 @@
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/string.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/console.h>
#include <linux/timex.h>
#include <linux/sched.h>
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index 0a6c6e6..3f35ab3 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -21,7 +21,7 @@
#include <linux/root_dev.h>
#include <linux/seq_file.h>
#include <linux/timex.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/cpu.h>
#include <linux/nodemask.h>
#include <linux/pfn.h>
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 10d3644..ab12c8f 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -999,8 +999,6 @@
return 1;
}
-#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-
/* An ELF note in memory. */
struct memelfnote
{
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 5edd8d4..8c2b596 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -24,7 +24,7 @@
#include <linux/user.h>
#include <linux/utsname.h>
#include <linux/a.out.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/bootmem.h>
#include <linux/initrd.h>
#include <linux/major.h>
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index bc4ac6f..7a54195 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -19,7 +19,7 @@
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/pci.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#ifdef CONFIG_MTD
#include <linux/mtd/partitions.h>
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index a9a6dbc..2996e33 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -27,7 +27,7 @@
#include <linux/blkdev.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/initrd.h>
#include <asm/irq.h>
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index 870486d..e5646b0 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -18,7 +18,7 @@
#include <linux/pci.h>
#include <linux/console.h>
#include <linux/fb.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#ifdef CONFIG_ARC
#include <asm/arc/types.h>
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index ce78f41..aab0576 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -89,6 +89,8 @@
}
#if defined(CONFIG_PDC_CONSOLE)
+#include <linux/vt_kern.h>
+
static struct tty_driver * pdc_console_device (struct console *c, int *index)
{
extern struct tty_driver console_driver;
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 97ddc02..68e5ab0 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -323,7 +323,7 @@
unsigned long irq_flags, const char * devname,
void *dev_id)
{
- unsigned int irq = irq_create_mapping(NULL, ist, 0);
+ unsigned int irq = irq_create_mapping(NULL, ist);
if (irq == NO_IRQ)
return -EINVAL;
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 8cf9878..01bdae3 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -391,15 +391,14 @@
irq_map[i].host = host;
smp_wmb();
- /* Clear some flags */
- get_irq_desc(i)->status
- &= ~(IRQ_NOREQUEST | IRQ_LEVEL);
+ /* Clear norequest flags */
+ get_irq_desc(i)->status &= ~IRQ_NOREQUEST;
/* Legacy flags are left to default at this point,
* one can then use irq_create_mapping() to
* explicitely change them
*/
- ops->map(host, i, i, 0);
+ ops->map(host, i, i);
}
break;
case IRQ_HOST_MAP_LINEAR:
@@ -457,13 +456,11 @@
}
unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq,
- unsigned int flags)
+ irq_hw_number_t hwirq)
{
unsigned int virq, hint;
- pr_debug("irq: irq_create_mapping(0x%p, 0x%lx, 0x%x)\n",
- host, hwirq, flags);
+ pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
/* Look for default host if nececssary */
if (host == NULL)
@@ -482,7 +479,6 @@
virq = irq_find_mapping(host, hwirq);
if (virq != IRQ_NONE) {
pr_debug("irq: -> existing mapping on virq %d\n", virq);
- host->ops->map(host, virq, hwirq, flags);
return virq;
}
@@ -504,18 +500,18 @@
}
pr_debug("irq: -> obtained virq %d\n", virq);
- /* Clear some flags */
- get_irq_desc(virq)->status &= ~(IRQ_NOREQUEST | IRQ_LEVEL);
+ /* Clear IRQ_NOREQUEST flag */
+ get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
/* map it */
- if (host->ops->map(host, virq, hwirq, flags)) {
+ smp_wmb();
+ irq_map[virq].hwirq = hwirq;
+ smp_mb();
+ if (host->ops->map(host, virq, hwirq)) {
pr_debug("irq: -> mapping failed, freeing\n");
irq_free_virt(virq, 1);
return NO_IRQ;
}
- smp_wmb();
- irq_map[virq].hwirq = hwirq;
- smp_mb();
return virq;
}
EXPORT_SYMBOL_GPL(irq_create_mapping);
@@ -525,25 +521,38 @@
{
struct irq_host *host;
irq_hw_number_t hwirq;
- unsigned int flags = IRQ_TYPE_NONE;
+ unsigned int type = IRQ_TYPE_NONE;
+ unsigned int virq;
if (controller == NULL)
host = irq_default_host;
else
host = irq_find_host(controller);
- if (host == NULL)
+ if (host == NULL) {
+ printk(KERN_WARNING "irq: no irq host found for %s !\n",
+ controller->full_name);
return NO_IRQ;
+ }
/* If host has no translation, then we assume interrupt line */
if (host->ops->xlate == NULL)
hwirq = intspec[0];
else {
if (host->ops->xlate(host, controller, intspec, intsize,
- &hwirq, &flags))
+ &hwirq, &type))
return NO_IRQ;
}
- return irq_create_mapping(host, hwirq, flags);
+ /* Create mapping */
+ virq = irq_create_mapping(host, hwirq);
+ if (virq == NO_IRQ)
+ return virq;
+
+ /* Set type if specified and different than the current one */
+ if (type != IRQ_TYPE_NONE &&
+ type != (get_irq_desc(virq)->status & IRQF_TRIGGER_MASK))
+ set_irq_type(virq, type);
+ return virq;
}
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 898dae8a..09b1e1b 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/bootmem.h>
+#include <linux/irq.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -18,7 +19,6 @@
#include <asm/sections.h>
#include <asm/pci-bridge.h>
#include <asm/byteorder.h>
-#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/machdep.h>
@@ -1420,15 +1420,37 @@
DBG("Try to map irq for %s...\n", pci_name(pci_dev));
+ /* Try to get a mapping from the device-tree */
if (of_irq_map_pci(pci_dev, &oirq)) {
- DBG(" -> failed !\n");
- return -1;
+ u8 line, pin;
+
+ /* If that fails, lets fallback to what is in the config
+ * space and map that through the default controller. We
+ * also set the type to level low since that's what PCI
+ * interrupts are. If your platform does differently, then
+ * either provide a proper interrupt tree or don't use this
+ * function.
+ */
+ if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
+ return -1;
+ if (pin == 0)
+ return -1;
+ if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
+ line == 0xff) {
+ return -1;
+ }
+ DBG(" -> no map ! Using irq line %d from PCI config\n", line);
+
+ virq = irq_create_mapping(NULL, line);
+ if (virq != NO_IRQ)
+ set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+ } else {
+ DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
+ oirq.size, oirq.specifier[0], oirq.controller->full_name);
+
+ virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ oirq.size);
}
-
- DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
- oirq.size, oirq.specifier[0], oirq.controller->full_name);
-
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size);
if(virq == NO_IRQ) {
DBG(" -> failed to map !\n");
return -1;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index efc0b55..2fce773 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -21,13 +21,13 @@
#include <linux/mm.h>
#include <linux/list.h>
#include <linux/syscalls.h>
+#include <linux/irq.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/byteorder.h>
-#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/ppc-pci.h>
@@ -1289,15 +1289,37 @@
DBG("Try to map irq for %s...\n", pci_name(pci_dev));
+ /* Try to get a mapping from the device-tree */
if (of_irq_map_pci(pci_dev, &oirq)) {
- DBG(" -> failed !\n");
- return -1;
+ u8 line, pin;
+
+ /* If that fails, lets fallback to what is in the config
+ * space and map that through the default controller. We
+ * also set the type to level low since that's what PCI
+ * interrupts are. If your platform does differently, then
+ * either provide a proper interrupt tree or don't use this
+ * function.
+ */
+ if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
+ return -1;
+ if (pin == 0)
+ return -1;
+ if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
+ line == 0xff) {
+ return -1;
+ }
+ DBG(" -> no map ! Using irq line %d from PCI config\n", line);
+
+ virq = irq_create_mapping(NULL, line);
+ if (virq != NO_IRQ)
+ set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+ } else {
+ DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
+ oirq.size, oirq.specifier[0], oirq.controller->full_name);
+
+ virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ oirq.size);
}
-
- DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
- oirq.size, oirq.specifier[0], oirq.controller->full_name);
-
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size);
if(virq == NO_IRQ) {
DBG(" -> failed to map !\n");
return -1;
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index e3b80f7..f6a05f0 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -5,7 +5,7 @@
#include <linux/elfcore.h>
#include <linux/string.h>
#include <linux/interrupt.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/vt_kern.h>
#include <linux/nvram.h>
#include <linux/console.h>
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 21009b1..6a7e997c 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -881,7 +881,7 @@
intsize = *tmp;
/* Check index */
- if (index * intsize >= intlen)
+ if ((index + 1) * intsize > intlen)
return -EINVAL;
/* Get new specifier and map it */
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index c6d7b98..499c386 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -26,7 +26,7 @@
#include <linux/ioport.h>
#include <linux/console.h>
#include <linux/utsname.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/root_dev.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 9d5da78..d7bbb61 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -159,7 +159,7 @@
if (iic_hosts[node] == NULL)
continue;
virq = irq_create_mapping(iic_hosts[node],
- iic_ipi_to_irq(ipi), 0);
+ iic_ipi_to_irq(ipi));
if (virq == NO_IRQ) {
printk(KERN_ERR
"iic: failed to map IPI %s on node %d\n",
@@ -197,7 +197,7 @@
}
static int iic_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
if (hw < IIC_IRQ_IPI0)
set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index ae7ef88..15217bb 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -85,9 +85,6 @@
struct spider_pic *pic = spider_virq_to_pic(virq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
- /* We use no locking as we should be covered by the descriptor lock
- * for access to invidual source configuration registers
- */
out_be32(cfg, in_be32(cfg) | 0x30000000u);
}
@@ -96,9 +93,6 @@
struct spider_pic *pic = spider_virq_to_pic(virq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
- /* We use no locking as we should be covered by the descriptor lock
- * for access to invidual source configuration registers
- */
out_be32(cfg, in_be32(cfg) & ~0x30000000u);
}
@@ -120,26 +114,14 @@
out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf));
}
-static struct irq_chip spider_pic = {
- .typename = " SPIDER ",
- .unmask = spider_unmask_irq,
- .mask = spider_mask_irq,
- .ack = spider_ack_irq,
-};
-
-static int spider_host_match(struct irq_host *h, struct device_node *node)
+static int spider_set_irq_type(unsigned int virq, unsigned int type)
{
- struct spider_pic *pic = h->host_data;
- return node == pic->of_node;
-}
-
-static int spider_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
-{
- unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
- struct spider_pic *pic = h->host_data;
+ unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
+ struct spider_pic *pic = spider_virq_to_pic(virq);
+ unsigned int hw = irq_map[virq].hwirq;
void __iomem *cfg = spider_get_irq_config(pic, hw);
- int level = 0;
+ struct irq_desc *desc = get_irq_desc(virq);
+ u32 old_mask;
u32 ic;
/* Note that only level high is supported for most interrupts */
@@ -157,29 +139,57 @@
break;
case IRQ_TYPE_LEVEL_LOW:
ic = 0x0;
- level = 1;
break;
case IRQ_TYPE_LEVEL_HIGH:
case IRQ_TYPE_NONE:
ic = 0x1;
- level = 1;
break;
default:
return -EINVAL;
}
+ /* Update irq_desc */
+ desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+ desc->status |= type & IRQ_TYPE_SENSE_MASK;
+ if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+ desc->status |= IRQ_LEVEL;
+
/* Configure the source. One gross hack that was there before and
* that I've kept around is the priority to the BE which I set to
* be the same as the interrupt source number. I don't know wether
* that's supposed to make any kind of sense however, we'll have to
* decide that, but for now, I'm not changing the behaviour.
*/
- out_be32(cfg, (ic << 24) | (0x7 << 16) | (pic->node_id << 4) | 0xe);
+ old_mask = in_be32(cfg) & 0x30000000u;
+ out_be32(cfg, old_mask | (ic << 24) | (0x7 << 16) |
+ (pic->node_id << 4) | 0xe);
out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff));
- if (level)
- get_irq_desc(virq)->status |= IRQ_LEVEL;
+ return 0;
+}
+
+static struct irq_chip spider_pic = {
+ .typename = " SPIDER ",
+ .unmask = spider_unmask_irq,
+ .mask = spider_mask_irq,
+ .ack = spider_ack_irq,
+ .set_type = spider_set_irq_type,
+};
+
+static int spider_host_match(struct irq_host *h, struct device_node *node)
+{
+ struct spider_pic *pic = h->host_data;
+ return node == pic->of_node;
+}
+
+static int spider_host_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq);
+
+ /* Set default irq type */
+ set_irq_type(virq, IRQ_TYPE_NONE);
+
return 0;
}
@@ -283,7 +293,7 @@
if (iic_host == NULL)
return NO_IRQ;
/* Manufacture an IIC interrupt number of class 2 */
- virq = irq_create_mapping(iic_host, 0x20 | unit, 0);
+ virq = irq_create_mapping(iic_host, 0x20 | unit);
if (virq == NO_IRQ)
printk(KERN_ERR "spider_pic: failed to map cascade !");
return virq;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 5d2313a..d06042d 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -583,9 +583,9 @@
spu->isrc = isrc = tmp[0];
/* Now map interrupts of all 3 classes */
- spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc, 0);
- spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc, 0);
- spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc, 0);
+ spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc);
+ spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc);
+ spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc);
/* Right now, we only fail if class 2 failed */
return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 2275e64..e324468 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -300,7 +300,7 @@
realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3)
+ function;
- return irq_create_mapping(NULL, realirq, IRQ_TYPE_NONE);
+ return irq_create_mapping(NULL, realirq);
}
#endif /* CONFIG_PCI */
@@ -341,7 +341,7 @@
}
static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
set_irq_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
index 69f65e2..74eed6b 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -15,6 +15,15 @@
#define OLD_BACKLIGHT_MAX 15
+static void pmac_backlight_key_worker(void *data);
+static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL);
+
+/* Although this variable is used in interrupt context, it makes no sense to
+ * protect it. No user is able to produce enough key events per second and
+ * notice the errors that might happen.
+ */
+static int pmac_backlight_key_queued;
+
/* Protect the pmac_backlight variable */
DEFINE_MUTEX(pmac_backlight_mutex);
@@ -71,7 +80,7 @@
return level;
}
-static void pmac_backlight_key(int direction)
+static void pmac_backlight_key_worker(void *data)
{
mutex_lock(&pmac_backlight_mutex);
if (pmac_backlight) {
@@ -82,7 +91,8 @@
props = pmac_backlight->props;
brightness = props->brightness +
- ((direction?-1:1) * (props->max_brightness / 15));
+ ((pmac_backlight_key_queued?-1:1) *
+ (props->max_brightness / 15));
if (brightness < 0)
brightness = 0;
@@ -97,14 +107,13 @@
mutex_unlock(&pmac_backlight_mutex);
}
-void pmac_backlight_key_up()
+void pmac_backlight_key(int direction)
{
- pmac_backlight_key(0);
-}
-
-void pmac_backlight_key_down()
-{
- pmac_backlight_key(1);
+ /* we can receive multiple interrupts here, but the scheduled work
+ * will run only once, with the last value
+ */
+ pmac_backlight_key_queued = direction;
+ schedule_work(&pmac_backlight_key_work);
}
int pmac_backlight_set_legacy_brightness(int brightness)
@@ -157,3 +166,7 @@
return result;
}
+
+EXPORT_SYMBOL_GPL(pmac_backlight);
+EXPORT_SYMBOL_GPL(pmac_backlight_mutex);
+EXPORT_SYMBOL_GPL(pmac_has_backlight_type);
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 556b349..205d044 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/irq.h>
#include <asm/sections.h>
#include <asm/io.h>
@@ -24,10 +25,7 @@
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/grackle.h>
-#ifdef CONFIG_PPC64
-//#include <asm/iommu.h>
#include <asm/ppc-pci.h>
-#endif
#undef DEBUG
@@ -46,7 +44,6 @@
static struct pci_controller *u3_agp;
static struct pci_controller *u4_pcie;
static struct pci_controller *u3_ht;
-#define has_second_ohare 0
#else
static int has_second_ohare;
#endif /* CONFIG_PPC64 */
@@ -993,6 +990,7 @@
/* Read interrupt from the device-tree */
pci_read_irq_line(dev);
+#ifdef CONFIG_PPC32
/* Fixup interrupt for the modem/ethernet combo controller.
* on machines with a second ohare chip.
* The number in the device tree (27) is bogus (correct for
@@ -1002,8 +1000,11 @@
*/
if (has_second_ohare &&
dev->vendor == PCI_VENDOR_ID_DEC &&
- dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS)
- dev->irq = irq_create_mapping(NULL, 60, 0);
+ dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
+ dev->irq = irq_create_mapping(NULL, 60);
+ set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+ }
+#endif /* CONFIG_PPC32 */
}
}
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 3d328bc..060789e 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -291,7 +291,7 @@
}
static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
struct irq_desc *desc = get_irq_desc(virq);
int level;
@@ -318,6 +318,7 @@
unsigned int *out_flags)
{
+ *out_flags = IRQ_TYPE_NONE;
*out_hwirq = *intspec;
return 0;
}
@@ -434,7 +435,7 @@
printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
#ifdef CONFIG_XMON
- setup_irq(irq_create_mapping(NULL, 20, 0), &xmon_action);
+ setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
#endif
}
#endif /* CONFIG_PPC32 */
@@ -579,9 +580,10 @@
flags |= OF_IMAP_OLDWORLD_MAC;
if (get_property(of_chosen, "linux,bootx", NULL) != NULL)
flags |= OF_IMAP_NO_PHANDLE;
- of_irq_map_init(flags);
#endif /* CONFIG_PPC_32 */
+ of_irq_map_init(flags);
+
/* We first try to detect Apple's new Core99 chipset, since mac-io
* is quite different on those machines and contains an IBM MPIC2.
*/
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 9df783088..c7ffde1 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -93,8 +93,7 @@
for (i = 0; i < opicplen; i++) {
if (count > 15)
break;
- virqs[count] = irq_create_mapping(NULL, *(opicprop++),
- IRQ_TYPE_NONE);
+ virqs[count] = irq_create_mapping(NULL, *(opicprop++));
if (virqs[count] == NO_IRQ)
printk(KERN_ERR "Unable to allocate interrupt "
"number for %s\n", np->full_name);
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 716972a..2d0da6f 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -502,16 +502,9 @@
}
static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
- unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
-
- pr_debug("xics: map_direct virq %d, hwirq 0x%lx, flags: 0x%x\n",
- virq, hw, flags);
-
- if (sense && sense != IRQ_TYPE_LEVEL_LOW)
- printk(KERN_WARNING "xics: using unsupported sense 0x%x"
- " for irq %d (h: 0x%lx)\n", flags, virq, hw);
+ pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
get_irq_desc(virq)->status |= IRQ_LEVEL;
set_irq_chip_and_handler(virq, &xics_pic_direct, handle_fasteoi_irq);
@@ -519,16 +512,9 @@
}
static int xics_host_map_lpar(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
- unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
-
- pr_debug("xics: map_lpar virq %d, hwirq 0x%lx, flags: 0x%x\n",
- virq, hw, flags);
-
- if (sense && sense != IRQ_TYPE_LEVEL_LOW)
- printk(KERN_WARNING "xics: using unsupported sense 0x%x"
- " for irq %d (h: 0x%lx)\n", flags, virq, hw);
+ pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
get_irq_desc(virq)->status |= IRQ_LEVEL;
set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq);
@@ -757,7 +743,7 @@
{
unsigned int ipi;
- ipi = irq_create_mapping(xics_host, XICS_IPI, 0);
+ ipi = irq_create_mapping(xics_host, XICS_IPI);
BUG_ON(ipi == NO_IRQ);
/*
@@ -783,6 +769,14 @@
xics_set_cpu_priority(cpu, 0);
/*
+ * Clear IPI
+ */
+ if (firmware_has_feature(FW_FEATURE_LPAR))
+ lpar_qirr_info(cpu, 0xff);
+ else
+ direct_qirr_info(cpu, 0xff);
+
+ /*
* we need to EOI the IPI if we got here from kexec down IPI
*
* probably need to check all the other interrupts too
@@ -795,7 +789,7 @@
return;
desc = get_irq_desc(ipi);
if (desc->chip && desc->chip->eoi)
- desc->chip->eoi(XICS_IPI);
+ desc->chip->eoi(ipi);
/*
* Some machines need to have at least one cpu in the GIQ,
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 72c73a6..9855820 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -169,7 +169,7 @@
}
static int i8259_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw);
@@ -177,7 +177,7 @@
if (hw == 2)
get_irq_desc(virq)->status |= IRQ_NOREQUEST;
- /* We use the level stuff only for now, we might want to
+ /* We use the level handler only for now, we might want to
* be more cautious here but that works for now
*/
get_irq_desc(virq)->status |= IRQ_LEVEL;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 9ceceba..6e0281a 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -204,7 +204,7 @@
if (fixup->base == NULL)
return;
- DBG("startup_ht_interrupt(%u, %u) index: %d\n",
+ DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n",
source, irqflags, fixup->index);
spin_lock_irqsave(&mpic->fixup_lock, flags);
/* Enable and configure */
@@ -227,7 +227,7 @@
if (fixup->base == NULL)
return;
- DBG("shutdown_ht_interrupt(%u, %u)\n", source, irqflags);
+ DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags);
/* Disable */
spin_lock_irqsave(&mpic->fixup_lock, flags);
@@ -337,6 +337,17 @@
}
}
+#else /* CONFIG_MPIC_BROKEN_U3 */
+
+static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
+{
+ return 0;
+}
+
+static void __init mpic_scan_ht_pics(struct mpic *mpic)
+{
+}
+
#endif /* CONFIG_MPIC_BROKEN_U3 */
@@ -405,11 +416,9 @@
unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
- unsigned long flags;
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
- spin_lock_irqsave(&mpic_lock, flags);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
~MPIC_VECPRI_MASK);
@@ -420,7 +429,6 @@
break;
}
} while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
- spin_unlock_irqrestore(&mpic_lock, flags);
}
static void mpic_mask_irq(unsigned int irq)
@@ -428,11 +436,9 @@
unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
- unsigned long flags;
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
- spin_lock_irqsave(&mpic_lock, flags);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
MPIC_VECPRI_MASK);
@@ -444,7 +450,6 @@
break;
}
} while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
- spin_unlock_irqrestore(&mpic_lock, flags);
}
static void mpic_end_irq(unsigned int irq)
@@ -512,8 +517,7 @@
mpic_ht_end_irq(mpic, src);
mpic_eoi(mpic);
}
-
-#endif /* CONFIG_MPIC_BROKEN_U3 */
+#endif /* !CONFIG_MPIC_BROKEN_U3 */
#ifdef CONFIG_SMP
@@ -560,47 +564,74 @@
mpic_physmask(cpus_addr(tmp)[0]));
}
-static unsigned int mpic_flags_to_vecpri(unsigned int flags, int *level)
+static unsigned int mpic_type_to_vecpri(unsigned int type)
{
- unsigned int vecpri;
-
/* Now convert sense value */
- switch(flags & IRQ_TYPE_SENSE_MASK) {
+ switch(type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
- vecpri = MPIC_VECPRI_SENSE_EDGE |
- MPIC_VECPRI_POLARITY_POSITIVE;
- *level = 0;
- break;
+ return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE;
case IRQ_TYPE_EDGE_FALLING:
- vecpri = MPIC_VECPRI_SENSE_EDGE |
- MPIC_VECPRI_POLARITY_NEGATIVE;
- *level = 0;
- break;
+ case IRQ_TYPE_EDGE_BOTH:
+ return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE;
case IRQ_TYPE_LEVEL_HIGH:
- vecpri = MPIC_VECPRI_SENSE_LEVEL |
- MPIC_VECPRI_POLARITY_POSITIVE;
- *level = 1;
- break;
+ return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE;
case IRQ_TYPE_LEVEL_LOW:
default:
- vecpri = MPIC_VECPRI_SENSE_LEVEL |
- MPIC_VECPRI_POLARITY_NEGATIVE;
- *level = 1;
+ return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE;
}
- return vecpri;
+}
+
+static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
+{
+ struct mpic *mpic = mpic_from_irq(virq);
+ unsigned int src = mpic_irq_to_hw(virq);
+ struct irq_desc *desc = get_irq_desc(virq);
+ unsigned int vecpri, vold, vnew;
+
+ DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
+ mpic, virq, src, flow_type);
+
+ if (src >= mpic->irq_count)
+ return -EINVAL;
+
+ if (flow_type == IRQ_TYPE_NONE)
+ if (mpic->senses && src < mpic->senses_count)
+ flow_type = mpic->senses[src];
+ if (flow_type == IRQ_TYPE_NONE)
+ flow_type = IRQ_TYPE_LEVEL_LOW;
+
+ desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+ desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
+ if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+ desc->status |= IRQ_LEVEL;
+
+ if (mpic_is_ht_interrupt(mpic, src))
+ vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
+ MPIC_VECPRI_SENSE_EDGE;
+ else
+ vecpri = mpic_type_to_vecpri(flow_type);
+
+ vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
+ vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK);
+ vnew |= vecpri;
+ if (vold != vnew)
+ mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew);
+
+ return 0;
}
static struct irq_chip mpic_irq_chip = {
- .mask = mpic_mask_irq,
- .unmask = mpic_unmask_irq,
- .eoi = mpic_end_irq,
+ .mask = mpic_mask_irq,
+ .unmask = mpic_unmask_irq,
+ .eoi = mpic_end_irq,
+ .set_type = mpic_set_irq_type,
};
#ifdef CONFIG_SMP
static struct irq_chip mpic_ipi_chip = {
- .mask = mpic_mask_ipi,
- .unmask = mpic_unmask_ipi,
- .eoi = mpic_end_ipi,
+ .mask = mpic_mask_ipi,
+ .unmask = mpic_unmask_ipi,
+ .eoi = mpic_end_ipi,
};
#endif /* CONFIG_SMP */
@@ -611,6 +642,7 @@
.mask = mpic_mask_irq,
.unmask = mpic_unmask_ht_irq,
.eoi = mpic_end_ht_irq,
+ .set_type = mpic_set_irq_type,
};
#endif /* CONFIG_MPIC_BROKEN_U3 */
@@ -624,26 +656,21 @@
}
static int mpic_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
- struct irq_desc *desc = get_irq_desc(virq);
- struct irq_chip *chip;
struct mpic *mpic = h->host_data;
- u32 v, vecpri = MPIC_VECPRI_SENSE_LEVEL |
- MPIC_VECPRI_POLARITY_NEGATIVE;
- int level;
- unsigned long iflags;
+ struct irq_chip *chip;
- pr_debug("mpic: map virq %d, hwirq 0x%lx, flags: 0x%x\n",
- virq, hw, flags);
+ DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw);
if (hw == MPIC_VEC_SPURRIOUS)
return -EINVAL;
+
#ifdef CONFIG_SMP
else if (hw >= MPIC_VEC_IPI_0) {
WARN_ON(!(mpic->flags & MPIC_PRIMARY));
- pr_debug("mpic: mapping as IPI\n");
+ DBG("mpic: mapping as IPI\n");
set_irq_chip_data(virq, mpic);
set_irq_chip_and_handler(virq, &mpic->hc_ipi,
handle_percpu_irq);
@@ -654,44 +681,23 @@
if (hw >= mpic->irq_count)
return -EINVAL;
- /* If no sense provided, check default sense array */
- if (((flags & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_NONE) &&
- mpic->senses && hw < mpic->senses_count)
- flags |= mpic->senses[hw];
-
- vecpri = mpic_flags_to_vecpri(flags, &level);
- if (level)
- desc->status |= IRQ_LEVEL;
+ /* Default chip */
chip = &mpic->hc_irq;
#ifdef CONFIG_MPIC_BROKEN_U3
/* Check for HT interrupts, override vecpri */
- if (mpic_is_ht_interrupt(mpic, hw)) {
- vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
- MPIC_VECPRI_POLARITY_MASK);
- vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
+ if (mpic_is_ht_interrupt(mpic, hw))
chip = &mpic->hc_ht_irq;
- }
-#endif
+#endif /* CONFIG_MPIC_BROKEN_U3 */
- /* Reconfigure irq. We must preserve the mask bit as we can be called
- * while the interrupt is still active (This may change in the future
- * but for now, it is the case).
- */
- spin_lock_irqsave(&mpic_lock, iflags);
- v = mpic_irq_read(hw, MPIC_IRQ_VECTOR_PRI);
- vecpri = (v &
- ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK)) |
- vecpri;
- if (vecpri != v)
- mpic_irq_write(hw, MPIC_IRQ_VECTOR_PRI, vecpri);
- spin_unlock_irqrestore(&mpic_lock, iflags);
-
- pr_debug("mpic: mapping as IRQ, vecpri = 0x%08x (was 0x%08x)\n",
- vecpri, v);
+ DBG("mpic: mapping to irq chip @%p\n", chip);
set_irq_chip_data(virq, mpic);
set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq);
+
+ /* Set default irq type */
+ set_irq_type(virq, IRQ_TYPE_NONE);
+
return 0;
}
@@ -708,11 +714,28 @@
};
*out_hwirq = intspec[0];
- if (intsize > 1 && intspec[1] < 4)
- *out_flags = map_mpic_senses[intspec[1]];
- else
+ if (intsize > 1) {
+ u32 mask = 0x3;
+
+ /* Apple invented a new race of encoding on machines with
+ * an HT APIC. They encode, among others, the index within
+ * the HT APIC. We don't care about it here since thankfully,
+ * it appears that they have the APIC already properly
+ * configured, and thus our current fixup code that reads the
+ * APIC config works fine. However, we still need to mask out
+ * bits in the specifier to make sure we only get bit 0 which
+ * is the level/edge bit (the only sense bit exposed by Apple),
+ * as their bit 1 means something else.
+ */
+ if (machine_is(powermac))
+ mask = 0x1;
+ *out_flags = map_mpic_senses[intspec[1] & mask];
+ } else
*out_flags = IRQ_TYPE_NONE;
+ DBG("mpic: xlate (%d cells: 0x%08x 0x%08x) to line 0x%lx sense 0x%x\n",
+ intsize, intspec[0], intspec[1], *out_hwirq, *out_flags);
+
return 0;
}
@@ -906,41 +929,16 @@
if (mpic->irq_count == 0)
mpic->irq_count = mpic->num_sources;
-#ifdef CONFIG_MPIC_BROKEN_U3
/* Do the HT PIC fixups on U3 broken mpic */
DBG("MPIC flags: %x\n", mpic->flags);
if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY))
mpic_scan_ht_pics(mpic);
-#endif /* CONFIG_MPIC_BROKEN_U3 */
for (i = 0; i < mpic->num_sources; i++) {
/* start with vector = source number, and masked */
- u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT);
- int level = 1;
+ u32 vecpri = MPIC_VECPRI_MASK | i |
+ (8 << MPIC_VECPRI_PRIORITY_SHIFT);
- /* do senses munging */
- if (mpic->senses && i < mpic->senses_count)
- vecpri |= mpic_flags_to_vecpri(mpic->senses[i],
- &level);
- else
- vecpri |= MPIC_VECPRI_SENSE_LEVEL;
-
- /* deal with broken U3 */
- if (mpic->flags & MPIC_BROKEN_U3) {
-#ifdef CONFIG_MPIC_BROKEN_U3
- if (mpic_is_ht_interrupt(mpic, i)) {
- vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
- MPIC_VECPRI_POLARITY_MASK);
- vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
- }
-#else
- printk(KERN_ERR "mpic: BROKEN_U3 set, but CONFIG doesn't match\n");
-#endif
- }
-
- DBG("setup source %d, vecpri: %08x, level: %d\n", i, vecpri,
- (level != 0));
-
/* init hw */
mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
mpic_irq_write(i, MPIC_IRQ_DESTINATION,
@@ -1154,7 +1152,7 @@
for (i = 0; i < 4; i++) {
unsigned int vipi = irq_create_mapping(mpic->irqhost,
- MPIC_VEC_IPI_0 + i, 0);
+ MPIC_VEC_IPI_0 + i);
if (vipi == NO_IRQ) {
printk(KERN_ERR "Failed to map IPI %d\n", i);
break;
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 50c1b47..d173540 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -5,7 +5,7 @@
#include <linux/elfcore.h>
#include <linux/string.h>
#include <linux/interrupt.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/vt_kern.h>
#include <linux/nvram.h>
#include <linux/console.h>
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index faf2940..a74f46d 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -11,7 +11,7 @@
#include <linux/delay.h>
#include <linux/initrd.h>
#include <linux/ide.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/bootmem.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index 6436bef..1cb75a1 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -23,7 +23,7 @@
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/major.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 224fbff..ae071a1 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -118,13 +118,6 @@
depends on COMPAT && SYSVIPC
default y
-config BINFMT_ELF32
- tristate "Kernel support for 31 bit ELF binaries"
- depends on COMPAT
- help
- This allows you to run 32-bit Linux/ELF binaries on your zSeries
- in 64 bit mode. Everybody wants this; say Y.
-
comment "Code generation options"
choice
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index eabf00a..86601a9 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -17,8 +17,8 @@
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \
- compat_wrapper.o compat_exec_domain.o
-obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
+ compat_wrapper.o compat_exec_domain.o \
+ binfmt_elf32.o
obj-$(CONFIG_VIRT_TIMER) += vtime.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 9af22116..e75189c 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -10,7 +10,7 @@
* This file handles the architecture-dependent parts of initialization
*/
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/initrd.h>
diff --git a/arch/sh64/kernel/setup.c b/arch/sh64/kernel/setup.c
index 0359fa6..ffb310e 100644
--- a/arch/sh64/kernel/setup.c
+++ b/arch/sh64/kernel/setup.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c
index 6efdfa2..4b2df72 100644
--- a/arch/sh64/kernel/sh_ksyms.c
+++ b/arch/sh64/kernel/sh_ksyms.c
@@ -18,7 +18,7 @@
#include <linux/in6.h>
#include <linux/interrupt.h>
#include <linux/smp_lock.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <asm/semaphore.h>
#include <asm/processor.h>
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 8606ef4..35488d6 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -17,7 +17,7 @@
#include <asm/smp.h>
#include <linux/user.h>
#include <linux/a.out.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index a7a111d..8a36ba8 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -334,7 +334,7 @@
default y
config BINFMT_ELF32
- tristate "Kernel support for 32-bit ELF binaries"
+ bool "Kernel support for 32-bit ELF binaries"
depends on SPARC32_COMPAT
help
This allows you to run 32-bit Linux/ELF binaries on your Ultra.
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index a731404..9582874 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -16,7 +16,7 @@
#include <asm/smp.h>
#include <linux/user.h>
#include <linux/a.out.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug
index bab51d6..09c1aca 100644
--- a/arch/um/Kconfig.debug
+++ b/arch/um/Kconfig.debug
@@ -47,13 +47,4 @@
If you're involved in UML kernel development and want to use gcov,
say Y. If you're unsure, say N.
-config SYSCALL_DEBUG
- bool "Enable system call debugging"
- depends on DEBUG_INFO
- help
- This adds some system debugging to UML, including keeping a ring buffer
- with recent system calls and some global and per-task statistics.
-
- If unsure, say N
-
endmenu
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 402a74d..780cc0a 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -526,4 +526,3 @@
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_GPROF is not set
# CONFIG_GCOV is not set
-# CONFIG_SYSCALL_DEBUG is not set
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 4b109fe..9bfd405 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -18,7 +18,12 @@
#include "umid.h"
static struct mconsole_command commands[] = {
- { "version", mconsole_version, MCONSOLE_INTR },
+ /* With uts namespaces, uts information becomes process-specific, so
+ * we need a process context. If we try handling this in interrupt
+ * context, we may hit an exiting process without a valid uts
+ * namespace.
+ */
+ { "version", mconsole_version, MCONSOLE_PROC },
{ "halt", mconsole_halt, MCONSOLE_PROC },
{ "reboot", mconsole_reboot, MCONSOLE_PROC },
{ "config", mconsole_config, MCONSOLE_PROC },
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 0a7786e..107c5e4 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -22,13 +22,14 @@
{
int tap_addr[4];
- if(gate_addr == NULL) return(0);
+ if(gate_addr == NULL)
+ return 0;
if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
&tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
printk("Invalid tap IP address - '%s'\n", gate_addr);
- return(-EINVAL);
+ return -EINVAL;
}
- return(0);
+ return 0;
}
void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
@@ -94,25 +95,25 @@
n = os_read_file(fd, buf, len);
if(n == -EAGAIN)
- return(0);
+ return 0;
else if(n == 0)
- return(-ENOTCONN);
- return(n);
+ return -ENOTCONN;
+ return n;
}
int net_recvfrom(int fd, void *buf, int len)
{
int n;
- while(((n = recvfrom(fd, buf, len, 0, NULL, NULL)) < 0) &&
- (errno == EINTR)) ;
-
+ CATCH_EINTR(n = recvfrom(fd, buf, len, 0, NULL, NULL));
if(n < 0){
- if(errno == EAGAIN) return(0);
- return(-errno);
+ if(errno == EAGAIN)
+ return 0;
+ return -errno;
}
- else if(n == 0) return(-ENOTCONN);
- return(n);
+ else if(n == 0)
+ return -ENOTCONN;
+ return n;
}
int net_write(int fd, void *buf, int len)
@@ -122,37 +123,41 @@
n = os_write_file(fd, buf, len);
if(n == -EAGAIN)
- return(0);
+ return 0;
else if(n == 0)
- return(-ENOTCONN);
- return(n);
+ return -ENOTCONN;
+ return n;
}
int net_send(int fd, void *buf, int len)
{
int n;
- while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
+ CATCH_EINTR(n = send(fd, buf, len, 0));
if(n < 0){
- if(errno == EAGAIN) return(0);
- return(-errno);
+ if(errno == EAGAIN)
+ return 0;
+ return -errno;
}
- else if(n == 0) return(-ENOTCONN);
- return(n);
+ else if(n == 0)
+ return -ENOTCONN;
+ return n;
}
int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
{
int n;
- while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
- sock_len)) < 0) && (errno == EINTR)) ;
+ CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
+ sock_len));
if(n < 0){
- if(errno == EAGAIN) return(0);
- return(-errno);
+ if(errno == EAGAIN)
+ return 0;
+ return -errno;
}
- else if(n == 0) return(-ENOTCONN);
- return(n);
+ else if(n == 0)
+ return -ENOTCONN;
+ return n;
}
struct change_pre_exec_data {
@@ -176,7 +181,7 @@
err = os_pipe(fds, 1, 0);
if(err < 0){
printk("change_tramp - pipe failed, err = %d\n", -err);
- return(err);
+ return err;
}
pe_data.close_me = fds[0];
pe_data.stdout = fds[1];
@@ -190,7 +195,7 @@
if (pid > 0)
CATCH_EINTR(err = waitpid(pid, NULL, 0));
- return(pid);
+ return pid;
}
static void change(char *dev, char *what, unsigned char *addr,
@@ -241,26 +246,15 @@
va_start(ap, str);
while((arg = va_arg(ap, char **)) != NULL){
if(*str == '\0')
- return(NULL);
+ return NULL;
end = strchr(str, ',');
if(end != str)
*arg = str;
if(end == NULL)
- return(NULL);
+ return NULL;
*end++ = '\0';
str = end;
}
va_end(ap);
- return(str);
+ return str;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index 94c9265..9f70edf 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -25,17 +25,17 @@
if(*str != ':'){
printk("tty_init : channel type 'tty' must specify "
"a device\n");
- return(NULL);
+ return NULL;
}
str++;
data = um_kmalloc(sizeof(*data));
if(data == NULL)
- return(NULL);
+ return NULL;
*data = ((struct tty_chan) { .dev = str,
.raw = opts->raw });
-
- return(data);
+
+ return data;
}
static int tty_open(int input, int output, int primary, void *d,
@@ -45,19 +45,21 @@
int fd, err;
fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
- if(fd < 0) return(fd);
+ if(fd < 0)
+ return fd;
+
if(data->raw){
CATCH_EINTR(err = tcgetattr(fd, &data->tt));
if(err)
- return(err);
+ return err;
err = raw(fd);
if(err)
- return(err);
+ return err;
}
*dev_out = data->dev;
- return(fd);
+ return fd;
}
struct chan_ops tty_ops = {
@@ -72,14 +74,3 @@
.free = generic_free,
.winch = 0,
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 602d728..3408531 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -627,7 +627,6 @@
{
struct gendisk *disk;
- int err;
disk = alloc_disk(1 << UBD_SHIFT);
if(disk == NULL)
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index 69a93c8..15d311b 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -6,6 +6,8 @@
#ifndef __IRQ_USER_H__
#define __IRQ_USER_H__
+#include "uml-config.h"
+
struct irq_fd {
struct irq_fd *next;
void *id;
@@ -26,9 +28,10 @@
extern void reactivate_fd(int fd, int irqnum);
extern void deactivate_fd(int fd, int irqnum);
extern int deactivate_all_fds(void);
-extern void forward_interrupts(int pid);
extern int activate_ipi(int fd, int pid);
-extern unsigned long irq_lock(void);
-extern void irq_unlock(unsigned long flags);
+
+#ifdef CONFIG_MODE_TT
+extern void forward_interrupts(int pid);
+#endif
#endif
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 310980b..b98bdd8 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -72,10 +72,8 @@
extern void *syscall_sp(void *t);
extern void syscall_trace(union uml_pt_regs *regs, int entryexit);
extern int hz(void);
-extern void uml_idle_timer(void);
extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
extern int external_pid(void *t);
-extern void boot_timer_handler(int sig);
extern void interrupt_end(void);
extern void initial_thread_cb(void (*proc)(void *), void *arg);
extern int debugger_signal(int status, int pid);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index f88856c..b6c5249 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -199,7 +199,7 @@
extern int os_getpgrp(void);
extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
-extern void init_new_thread_signals(int altstack);
+extern void init_new_thread_signals(void);
extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
extern int os_map_memory(void *virt, int fd, unsigned long long off,
@@ -318,7 +318,6 @@
/* irq.c */
extern int os_waiting_for_events(struct irq_fd *active_fds);
-extern int os_isatty(int fd);
extern int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds);
extern void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2);
@@ -330,9 +329,8 @@
extern void init_irq_signals(int on_sigstack);
/* sigio.c */
-extern void write_sigio_workaround(void);
-extern int add_sigio_fd(int fd, int read);
extern int ignore_sigio_fd(int fd);
+extern void maybe_sigio_broken(int fd, int read);
/* skas/trap */
extern void sig_handler_common_skas(int sig, void *sc_ptr);
diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h
index 63c5873..9cd9c6e 100644
--- a/arch/um/include/skas/mode_kern_skas.h
+++ b/arch/um/include/skas/mode_kern_skas.h
@@ -29,8 +29,7 @@
extern void force_flush_all_skas(void);
extern long execute_syscall_skas(void *r);
extern void before_mem_skas(unsigned long unused);
-extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
- unsigned long *task_size_out);
+extern unsigned long set_task_sizes_skas(unsigned long *task_size_out);
extern int start_uml_skas(void);
extern int external_pid_skas(struct task_struct *task);
extern int thread_pid_skas(struct task_struct *task);
diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h
index efa0012..a4fc630 100644
--- a/arch/um/include/tt/mode_kern_tt.h
+++ b/arch/um/include/tt/mode_kern_tt.h
@@ -30,8 +30,7 @@
extern void force_flush_all_tt(void);
extern long execute_syscall_tt(void *r);
extern void before_mem_tt(unsigned long brk_start);
-extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
- unsigned long *task_size_out);
+extern unsigned long set_task_sizes_tt(unsigned long *task_size_out);
extern int start_uml_tt(void);
extern int external_pid_tt(struct task_struct *task);
extern int thread_pid_tt(struct task_struct *task);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index fe08971..a2d9306 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -6,16 +6,14 @@
extra-y := vmlinux.lds
clean-files :=
-obj-y = config.o exec_kern.o exitcode.o \
- init_task.o irq.o ksyms.o mem.o physmem.o \
- process_kern.o ptrace.o reboot.o resource.o sigio_kern.o \
- signal_kern.o smp.o syscall_kern.o sysrq.o \
- time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o
+obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \
+ physmem.o process_kern.o ptrace.o reboot.o resource.o sigio.o \
+ signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \
+ um_arch.o umid.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
obj-$(CONFIG_GPROF) += gprof_syms.o
obj-$(CONFIG_GCOV) += gmon_syms.o
-obj-$(CONFIG_SYSCALL_DEBUG) += syscall.o
obj-$(CONFIG_MODE_TT) += tt/
obj-$(CONFIG_MODE_SKAS) += skas/
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec.c
similarity index 87%
rename from arch/um/kernel/exec_kern.c
rename to arch/um/kernel/exec.c
index c0cb627..fc38a6d 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -31,18 +31,27 @@
CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
}
+#ifdef CONFIG_TTY_LOG
+extern void log_exec(char **argv, void *tty);
+#endif
+
static long execve1(char *file, char __user * __user *argv,
char __user *__user *env)
{
long error;
#ifdef CONFIG_TTY_LOG
- log_exec(argv, current->tty);
+ task_lock(current);
+ log_exec(argv, current->signal->tty);
+ task_unlock(current);
#endif
error = do_execve(file, argv, env, ¤t->thread.regs);
if (error == 0){
task_lock(current);
current->ptrace &= ~PT_DTRACE;
+#ifdef SUBARCH_EXECVE1
+ SUBARCH_EXECVE1(¤t->thread.regs.regs);
+#endif
task_unlock(current);
set_cmdline(current_cmd());
}
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index bfd0bdc..589c69a 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -110,18 +110,7 @@
free_irqs();
}
-static void maybe_sigio_broken(int fd, int type)
-{
- if (os_isatty(fd)) {
- if ((type == IRQ_WRITE) && !pty_output_sigio) {
- write_sigio_workaround();
- add_sigio_fd(fd, 0);
- } else if ((type == IRQ_READ) && !pty_close_sigio) {
- write_sigio_workaround();
- add_sigio_fd(fd, 1);
- }
- }
-}
+static DEFINE_SPINLOCK(irq_lock);
int activate_fd(int irq, int fd, int type, void *dev_id)
{
@@ -166,7 +155,7 @@
* this is called only from process context, and can be locked with
* a semaphore.
*/
- flags = irq_lock();
+ spin_lock_irqsave(&irq_lock, flags);
for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
printk("Registering fd %d twice\n", fd);
@@ -199,7 +188,7 @@
* so we will not be able to put new pollfd struct to pollfds
* then we free the buffer tmp_fds and try again.
*/
- irq_unlock(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
kfree(tmp_pfd);
tmp_pfd = NULL;
@@ -207,24 +196,24 @@
if (tmp_pfd == NULL)
goto out_kfree;
- flags = irq_lock();
+ spin_lock_irqsave(&irq_lock, flags);
}
/*-------------*/
*last_irq_ptr = new_fd;
last_irq_ptr = &new_fd->next;
- irq_unlock(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
/* This calls activate_fd, so it has to be outside the critical
* section.
*/
- maybe_sigio_broken(fd, type);
+ maybe_sigio_broken(fd, (type == IRQ_READ));
return(0);
out_unlock:
- irq_unlock(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
out_kfree:
kfree(new_fd);
out:
@@ -235,9 +224,9 @@
{
unsigned long flags;
- flags = irq_lock();
+ spin_lock_irqsave(&irq_lock, flags);
os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr);
- irq_unlock(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
}
struct irq_and_dev {
@@ -304,19 +293,19 @@
unsigned long flags;
int i;
- flags = irq_lock();
+ spin_lock_irqsave(&irq_lock, flags);
irq = find_irq_by_fd(fd, irqnum, &i);
if (irq == NULL) {
- irq_unlock(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
return;
}
os_set_pollfd(i, irq->fd);
- irq_unlock(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
/* This calls activate_fd, so it has to be outside the critical
* section.
*/
- maybe_sigio_broken(fd, irq->type);
+ maybe_sigio_broken(fd, (irq->type == IRQ_READ));
}
void deactivate_fd(int fd, int irqnum)
@@ -325,13 +314,13 @@
unsigned long flags;
int i;
- flags = irq_lock();
+ spin_lock_irqsave(&irq_lock, flags);
irq = find_irq_by_fd(fd, irqnum, &i);
if (irq == NULL)
goto out;
os_set_pollfd(i, -1);
out:
- irq_unlock(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
}
int deactivate_all_fds(void)
@@ -350,13 +339,14 @@
return 0;
}
+#ifdef CONFIG_MODE_TT
void forward_interrupts(int pid)
{
struct irq_fd *irq;
unsigned long flags;
int err;
- flags = irq_lock();
+ spin_lock_irqsave(&irq_lock, flags);
for (irq = active_fds; irq != NULL; irq = irq->next) {
err = os_set_owner(irq->fd, pid);
if (err < 0) {
@@ -369,8 +359,9 @@
irq->pid = pid;
}
- irq_unlock(flags);
+ spin_unlock_irqrestore(&irq_lock, flags);
}
+#endif
/*
* do_IRQ handles all normal device IRQ's (the special
@@ -403,21 +394,6 @@
EXPORT_SYMBOL(um_request_irq);
EXPORT_SYMBOL(reactivate_fd);
-static DEFINE_SPINLOCK(irq_spinlock);
-
-unsigned long irq_lock(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&irq_spinlock, flags);
- return flags;
-}
-
-void irq_unlock(unsigned long flags)
-{
- spin_unlock_irqrestore(&irq_spinlock, flags);
-}
-
/* hw_interrupt_type must define (startup || enable) &&
* (shutdown || disable) && end */
static void dummy(unsigned int irq)
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 432cf0b9..c97045d 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -88,12 +88,6 @@
EXPORT_SYMBOL(do_gettimeofday);
EXPORT_SYMBOL(do_settimeofday);
-/* This is here because UML expands lseek to sys_lseek, not to a system
- * call instruction.
- */
-EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(sys_wait4);
-
#ifdef CONFIG_SMP
/* required for SMP */
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 44e41a3..6128016 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -24,8 +24,6 @@
#include "init.h"
#include "kern_constants.h"
-extern char __binary_start;
-
/* Changed during early boot */
unsigned long *empty_zero_page = NULL;
unsigned long *empty_bad_page = NULL;
@@ -65,8 +63,6 @@
void mem_init(void)
{
- unsigned long start;
-
max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT;
/* clear the zero-page */
@@ -81,13 +77,6 @@
free_bootmem(__pa(brk_end), uml_reserved - brk_end);
uml_reserved = brk_end;
- /* Fill in any hole at the start of the binary */
- start = (unsigned long) &__binary_start & PAGE_MASK;
- if(uml_physmem != start){
- map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
- 1, 1, 0);
- }
-
/* this will put all low memory onto the freelists */
totalram_pages = free_all_bootmem();
totalhigh_pages = highmem >> PAGE_SHIFT;
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 166cb09..abafa64 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -317,7 +317,7 @@
}
}
-extern int __syscall_stub_start, __binary_start;
+extern int __syscall_stub_start;
void setup_physmem(unsigned long start, unsigned long reserve_end,
unsigned long len, unsigned long long highmem)
diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio.c
similarity index 68%
rename from arch/um/kernel/sigio_kern.c
rename to arch/um/kernel/sigio.c
index 51b6770..0ad755c 100644
--- a/arch/um/kernel/sigio_kern.c
+++ b/arch/um/kernel/sigio.c
@@ -31,7 +31,7 @@
int err;
err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
- IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "write sigio",
+ IRQF_DISABLED|IRQF_SAMPLE_RANDOM, "write sigio",
NULL);
if(err){
printk("write_sigio_irq : um_request_irq failed, err = %d\n",
@@ -53,17 +53,3 @@
{
spin_unlock(&sigio_spinlock);
}
-
-extern void sigio_cleanup(void);
-__uml_exitcall(sigio_cleanup);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal.c
similarity index 96%
rename from arch/um/kernel/signal_kern.c
rename to arch/um/kernel/signal.c
index da17b75..4aa9808 100644
--- a/arch/um/kernel/signal_kern.c
+++ b/arch/um/kernel/signal.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -36,7 +36,7 @@
/*
* OK, we're invoking a handler
- */
+ */
static int handle_signal(struct pt_regs *regs, unsigned long signr,
struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset)
@@ -88,7 +88,7 @@
force_sigsegv(signr, current);
} else {
spin_lock_irq(¤t->sighand->siglock);
- sigorsets(¤t->blocked, ¤t->blocked,
+ sigorsets(¤t->blocked, ¤t->blocked,
&ka->sa.sa_mask);
if(!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(¤t->blocked, signr);
@@ -136,7 +136,7 @@
PT_REGS_RESTART_SYSCALL(regs);
break;
case -ERESTART_RESTARTBLOCK:
- PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall;
+ PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall;
PT_REGS_RESTART_SYSCALL(regs);
break;
}
@@ -146,7 +146,7 @@
* you set a breakpoint on a system call instruction and singlestep
* from it, the tracing thread used to PTRACE_SINGLESTEP the process
* rather than PTRACE_SYSCALL it, allowing the system call to execute
- * on the host. The tracing thread will check this flag and
+ * on the host. The tracing thread will check this flag and
* PTRACE_SYSCALL if necessary.
*/
if(current->ptrace & PT_DTRACE)
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
index 88ab96c..27bbf54 100644
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -9,31 +9,19 @@
#include "mem_user.h"
#include "skas.h"
-unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
- unsigned long *task_size_out)
+unsigned long set_task_sizes_skas(unsigned long *task_size_out)
{
/* Round up to the nearest 4M */
- unsigned long top = ROUND_4M((unsigned long) &arg);
+ unsigned long host_task_size = ROUND_4M((unsigned long)
+ &host_task_size);
#ifdef CONFIG_HOST_TASK_SIZE
- *host_size_out = CONFIG_HOST_TASK_SIZE;
+ *host_size_out = ROUND_4M(CONFIG_HOST_TASK_SIZE);
*task_size_out = CONFIG_HOST_TASK_SIZE;
#else
- *host_size_out = top;
if (!skas_needs_stub)
- *task_size_out = top;
+ *task_size_out = host_task_size;
else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
#endif
- return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
+ return host_task_size;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 2135eaf..55caeec 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -177,7 +177,7 @@
if(proc_mm)
userspace_pid[0] = start_userspace(0);
- init_new_thread_signals(1);
+ init_new_thread_signals();
init_task.thread.request.u.thread.proc = start_kernel_proc;
init_task.thread.request.u.thread.arg = NULL;
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 51fb940..0ae4eea 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -18,11 +18,7 @@
struct pt_regs *regs = container_of(r, struct pt_regs, regs);
long result;
int syscall;
-#ifdef UML_CONFIG_SYSCALL_DEBUG
- int index;
- index = record_syscall_start(UPT_SYSCALL_NR(r));
-#endif
syscall_trace(r, 0);
current->thread.nsyscalls++;
@@ -44,7 +40,4 @@
REGS_SET_SYSCALL_RETURN(r->skas.regs, result);
syscall_trace(r, 1);
-#ifdef UML_CONFIG_SYSCALL_DEBUG
- record_syscall_end(index, result);
-#endif
}
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 1731d90..abf14aa 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -1,36 +1,166 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
* Licensed under the GPL
*/
+#include "linux/sched.h"
+#include "linux/file.h"
+#include "linux/smp_lock.h"
+#include "linux/mm.h"
+#include "linux/utsname.h"
+#include "linux/msg.h"
+#include "linux/shm.h"
+#include "linux/sys.h"
+#include "linux/syscalls.h"
+#include "linux/unistd.h"
+#include "linux/slab.h"
+#include "linux/utime.h"
+#include "asm/mman.h"
+#include "asm/uaccess.h"
#include "kern_util.h"
-#include "syscall.h"
-#include "os.h"
+#include "user_util.h"
+#include "sysdep/syscalls.h"
+#include "mode_kern.h"
+#include "choose-mode.h"
-struct {
- int syscall;
- int pid;
- long result;
- unsigned long long start;
- unsigned long long end;
-} syscall_record[1024];
+/* Unlocked, I don't care if this is a bit off */
+int nsyscalls = 0;
-int record_syscall_start(int syscall)
+long sys_fork(void)
{
- int max, index;
+ long ret;
- max = sizeof(syscall_record)/sizeof(syscall_record[0]);
- index = next_syscall_index(max);
-
- syscall_record[index].syscall = syscall;
- syscall_record[index].pid = current_pid();
- syscall_record[index].result = 0xdeadbeef;
- syscall_record[index].start = os_nsecs();
- return(index);
+ current->thread.forking = 1;
+ ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs),
+ ¤t->thread.regs, 0, NULL, NULL);
+ current->thread.forking = 0;
+ return(ret);
}
-void record_syscall_end(int index, long result)
+long sys_vfork(void)
{
- syscall_record[index].result = result;
- syscall_record[index].end = os_nsecs();
+ long ret;
+
+ current->thread.forking = 1;
+ ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
+ UPT_SP(¤t->thread.regs.regs),
+ ¤t->thread.regs, 0, NULL, NULL);
+ current->thread.forking = 0;
+ return(ret);
+}
+
+/* common code for old and new mmaps */
+long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ long error = -EBADF;
+ struct file * file = NULL;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ if (!(flags & MAP_ANONYMOUS)) {
+ file = fget(fd);
+ if (!file)
+ goto out;
+ }
+
+ down_write(¤t->mm->mmap_sem);
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ up_write(¤t->mm->mmap_sem);
+
+ if (file)
+ fput(file);
+ out:
+ return error;
+}
+
+long old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long offset)
+{
+ long err = -EINVAL;
+ if (offset & ~PAGE_MASK)
+ goto out;
+
+ err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+ out:
+ return err;
+}
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+long sys_pipe(unsigned long __user * fildes)
+{
+ int fd[2];
+ long error;
+
+ error = do_pipe(fd);
+ if (!error) {
+ if (copy_to_user(fildes, fd, sizeof(fd)))
+ error = -EFAULT;
+ }
+ return error;
+}
+
+
+long sys_uname(struct old_utsname __user * name)
+{
+ long err;
+ if (!name)
+ return -EFAULT;
+ down_read(&uts_sem);
+ err = copy_to_user(name, utsname(), sizeof (*name));
+ up_read(&uts_sem);
+ return err?-EFAULT:0;
+}
+
+long sys_olduname(struct oldold_utsname __user * name)
+{
+ long error;
+
+ if (!name)
+ return -EFAULT;
+ if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+ return -EFAULT;
+
+ down_read(&uts_sem);
+
+ error = __copy_to_user(&name->sysname, &utsname()->sysname,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release, &utsname()->release,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->release + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version, &utsname()->version,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->version + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine, &utsname()->machine,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->machine + __OLD_UTS_LEN);
+
+ up_read(&uts_sem);
+
+ error = error ? -EFAULT : 0;
+
+ return error;
+}
+
+DEFINE_SPINLOCK(syscall_lock);
+
+static int syscall_index = 0;
+
+int next_syscall_index(int limit)
+{
+ int ret;
+
+ spin_lock(&syscall_lock);
+ ret = syscall_index;
+ if(++syscall_index == limit)
+ syscall_index = 0;
+ spin_unlock(&syscall_lock);
+ return(ret);
}
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
deleted file mode 100644
index 37d3978..0000000
--- a/arch/um/kernel/syscall_kern.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#include "linux/sched.h"
-#include "linux/file.h"
-#include "linux/smp_lock.h"
-#include "linux/mm.h"
-#include "linux/utsname.h"
-#include "linux/msg.h"
-#include "linux/shm.h"
-#include "linux/sys.h"
-#include "linux/syscalls.h"
-#include "linux/unistd.h"
-#include "linux/slab.h"
-#include "linux/utime.h"
-#include "asm/mman.h"
-#include "asm/uaccess.h"
-#include "kern_util.h"
-#include "user_util.h"
-#include "sysdep/syscalls.h"
-#include "mode_kern.h"
-#include "choose-mode.h"
-
-/* Unlocked, I don't care if this is a bit off */
-int nsyscalls = 0;
-
-long sys_fork(void)
-{
- long ret;
-
- current->thread.forking = 1;
- ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs),
- ¤t->thread.regs, 0, NULL, NULL);
- current->thread.forking = 0;
- return(ret);
-}
-
-long sys_vfork(void)
-{
- long ret;
-
- current->thread.forking = 1;
- ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
- UPT_SP(¤t->thread.regs.regs),
- ¤t->thread.regs, 0, NULL, NULL);
- current->thread.forking = 0;
- return(ret);
-}
-
-/* common code for old and new mmaps */
-long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff)
-{
- long error = -EBADF;
- struct file * file = NULL;
-
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
- goto out;
- }
-
- down_write(¤t->mm->mmap_sem);
- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up_write(¤t->mm->mmap_sem);
-
- if (file)
- fput(file);
- out:
- return error;
-}
-
-long old_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long offset)
-{
- long err = -EINVAL;
- if (offset & ~PAGE_MASK)
- goto out;
-
- err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
- out:
- return err;
-}
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-long sys_pipe(unsigned long __user * fildes)
-{
- int fd[2];
- long error;
-
- error = do_pipe(fd);
- if (!error) {
- if (copy_to_user(fildes, fd, sizeof(fd)))
- error = -EFAULT;
- }
- return error;
-}
-
-
-long sys_uname(struct old_utsname __user * name)
-{
- long err;
- if (!name)
- return -EFAULT;
- down_read(&uts_sem);
- err=copy_to_user(name, &system_utsname, sizeof (*name));
- up_read(&uts_sem);
- return err?-EFAULT:0;
-}
-
-long sys_olduname(struct oldold_utsname __user * name)
-{
- long error;
-
- if (!name)
- return -EFAULT;
- if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
-
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,
- __OLD_UTS_LEN);
- error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
- __OLD_UTS_LEN);
- error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->release,&system_utsname.release,
- __OLD_UTS_LEN);
- error |= __put_user(0,name->release+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->version,&system_utsname.version,
- __OLD_UTS_LEN);
- error |= __put_user(0,name->version+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine,&system_utsname.machine,
- __OLD_UTS_LEN);
- error |= __put_user(0,name->machine+__OLD_UTS_LEN);
-
- up_read(&uts_sem);
-
- error = error ? -EFAULT : 0;
-
- return error;
-}
-
-DEFINE_SPINLOCK(syscall_lock);
-
-static int syscall_index = 0;
-
-int next_syscall_index(int limit)
-{
- int ret;
-
- spin_lock(&syscall_lock);
- ret = syscall_index;
- if(++syscall_index == limit)
- syscall_index = 0;
- spin_unlock(&syscall_lock);
- return(ret);
-}
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time.c
similarity index 84%
rename from arch/um/kernel/time_kern.c
rename to arch/um/kernel/time.c
index d7e044b..552ca1c 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time.c
@@ -38,7 +38,6 @@
/* Changed at early boot */
int timer_irq_inited = 0;
-static int first_tick;
static unsigned long long prev_nsecs;
#ifdef CONFIG_UML_REAL_TIME_CLOCK
static long long delta; /* Deviation per interval */
@@ -48,15 +47,8 @@
{
unsigned long long ticks = 0;
- if(!timer_irq_inited){
- /* This is to ensure that ticks don't pile up when
- * the timer handler is suspended */
- first_tick = 0;
- return;
- }
-
- if(first_tick){
#ifdef CONFIG_UML_REAL_TIME_CLOCK
+ if(prev_nsecs){
/* We've had 1 tick */
unsigned long long nsecs = os_nsecs();
@@ -69,44 +61,17 @@
ticks += (delta * HZ) / BILLION;
delta -= (ticks * BILLION) / HZ;
+ }
+ else prev_nsecs = os_nsecs();
#else
- ticks = 1;
+ ticks = 1;
#endif
- }
- else {
- prev_nsecs = os_nsecs();
- first_tick = 1;
- }
-
while(ticks > 0){
do_IRQ(TIMER_IRQ, regs);
ticks--;
}
}
-
-void time_init_kern(void)
-{
- long long nsecs;
-
- nsecs = os_nsecs();
- set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
- -nsecs % BILLION);
-}
-
-void do_boot_timer_handler(struct sigcontext * sc)
-{
- unsigned long flags;
- struct pt_regs regs;
-
- CHOOSE_MODE((void) (UPT_SC(®s.regs) = sc),
- (void) (regs.regs.skas.is_user = 0));
-
- write_seqlock_irqsave(&xtime_lock, flags);
- do_timer(®s);
- write_sequnlock_irqrestore(&xtime_lock, flags);
-}
-
static DEFINE_SPINLOCK(timer_spinlock);
static unsigned long long local_offset = 0;
@@ -142,6 +107,32 @@
return IRQ_HANDLED;
}
+static void register_timer(void)
+{
+ int err;
+
+ err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
+ if(err != 0)
+ printk(KERN_ERR "timer_init : request_irq failed - "
+ "errno = %d\n", -err);
+
+ timer_irq_inited = 1;
+
+ user_time_init();
+}
+
+extern void (*late_time_init)(void);
+
+void time_init(void)
+{
+ long long nsecs;
+
+ nsecs = os_nsecs();
+ set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
+ -nsecs % BILLION);
+ late_time_init = register_timer;
+}
+
void do_gettimeofday(struct timeval *tv)
{
unsigned long long nsecs = get_time();
@@ -189,18 +180,3 @@
if(current_thread->cpu == 0)
timer_irq(regs);
}
-
-int __init timer_init(void)
-{
- int err;
-
- user_time_init();
- err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
- if(err != 0)
- printk(KERN_ERR "timer_init : request_irq failed - "
- "errno = %d\n", -err);
- timer_irq_inited = 1;
- return(0);
-}
-
-arch_initcall(timer_init);
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap.c
similarity index 94%
rename from arch/um/kernel/trap_kern.c
rename to arch/um/kernel/trap.c
index 02f6d4d..ac70fa5 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap.c
@@ -35,7 +35,7 @@
#include "os.h"
/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
-int handle_page_fault(unsigned long address, unsigned long ip,
+int handle_page_fault(unsigned long address, unsigned long ip,
int is_write, int is_user, int *code_out)
{
struct mm_struct *mm = current->mm;
@@ -55,20 +55,20 @@
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
- if(!vma)
+ if(!vma)
goto out;
- else if(vma->vm_start <= address)
+ else if(vma->vm_start <= address)
goto good_area;
- else if(!(vma->vm_flags & VM_GROWSDOWN))
+ else if(!(vma->vm_flags & VM_GROWSDOWN))
goto out;
else if(is_user && !ARCH_IS_STACKGROW(address))
goto out;
- else if(expand_stack(vma, address))
+ else if(expand_stack(vma, address))
goto out;
good_area:
*code_out = SEGV_ACCERR;
- if(is_write && !(vma->vm_flags & VM_WRITE))
+ if(is_write && !(vma->vm_flags & VM_WRITE))
goto out;
/* Don't require VM_READ|VM_EXEC for write faults! */
@@ -184,14 +184,14 @@
else if(catcher != NULL){
current->thread.fault_addr = (void *) address;
do_longjmp(catcher, 1);
- }
+ }
else if(current->thread.fault_addr != NULL)
panic("fault_addr set but no fault catcher");
else if(!is_user && arch_fixup(ip, sc))
return(0);
- if(!is_user)
- panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
+ if(!is_user)
+ panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
address, ip);
if (err == -EACCES) {
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index 5c1e4cc..ad66df1 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -21,7 +21,7 @@
static int exec_tramp(void *sig_stack)
{
init_new_thread_stack(sig_stack, NULL);
- init_new_thread_signals(1);
+ init_new_thread_signals();
os_stop_process(os_getpid());
return(0);
}
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index bcb8796..84a23b1 100644
--- a/arch/um/kernel/tt/mem.c
+++ b/arch/um/kernel/tt/mem.c
@@ -24,22 +24,13 @@
#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
#define START (CONFIG_TOP_ADDR - SIZE)
-unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
- unsigned long *task_size_out)
+unsigned long set_task_sizes_tt(unsigned long *task_size_out)
{
- /* Round up to the nearest 4M */
- *host_size_out = ROUND_4M((unsigned long) &arg);
- *task_size_out = START;
- return(START);
-}
+ unsigned long host_task_size;
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+ /* Round up to the nearest 4M */
+ host_task_size = ROUND_4M((unsigned long) &host_task_size);
+ *task_size_out = START;
+
+ return host_task_size;
+}
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 8368c2d..1e86f0b 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -142,7 +142,7 @@
schedule_tail(current->thread.prev_sched);
current->thread.prev_sched = NULL;
- init_new_thread_signals(1);
+ init_new_thread_signals();
enable_timer();
free_page(current->thread.temp_stack);
set_cmdline("(kernel thread)");
diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
index 3fda9a0..293caa6 100644
--- a/arch/um/kernel/tt/syscall_kern.c
+++ b/arch/um/kernel/tt/syscall_kern.c
@@ -21,18 +21,11 @@
void *sc;
long result;
int syscall;
-#ifdef CONFIG_SYSCALL_DEBUG
- int index;
-#endif
+
sc = UPT_SC(®s->regs);
SC_START_SYSCALL(sc);
syscall = UPT_SYSCALL_NR(®s->regs);
-
-#ifdef CONFIG_SYSCALL_DEBUG
- index = record_syscall_start(syscall);
-#endif
-
syscall_trace(®s->regs, 0);
current->thread.nsyscalls++;
@@ -50,7 +43,4 @@
SC_SET_SYSCALL_RETURN(sc, result);
syscall_trace(®s->regs, 1);
-#ifdef CONFIG_SYSCALL_DEBUG
- record_syscall_end(index, result);
-#endif
}
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index 71daae2..9882342 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -188,10 +188,7 @@
int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
int proc_id = 0, n, err, old_tracing = 0, strace = 0;
int local_using_sysemu = 0;
-#ifdef UML_CONFIG_SYSCALL_DEBUG
- unsigned long eip = 0;
- int last_index;
-#endif
+
signal(SIGPIPE, SIG_IGN);
setup_tracer_winch();
tracing_pid = os_getpid();
@@ -282,23 +279,6 @@
else if(WIFSTOPPED(status)){
proc_id = pid_to_processor_id(pid);
sig = WSTOPSIG(status);
-#ifdef UML_CONFIG_SYSCALL_DEBUG
- if(signal_index[proc_id] == 1024){
- signal_index[proc_id] = 0;
- last_index = 1023;
- }
- else last_index = signal_index[proc_id] - 1;
- if(((sig == SIGPROF) || (sig == SIGVTALRM) ||
- (sig == SIGALRM)) &&
- (signal_record[proc_id][last_index].signal == sig)&&
- (signal_record[proc_id][last_index].pid == pid))
- signal_index[proc_id] = last_index;
- signal_record[proc_id][signal_index[proc_id]].pid = pid;
- gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
- eip = ptrace(PTRACE_PEEKUSR, pid, PT_IP_OFFSET, 0);
- signal_record[proc_id][signal_index[proc_id]].addr = eip;
- signal_record[proc_id][signal_index[proc_id]++].signal = sig;
-#endif
if(proc_id == -1){
sleeping_process_signal(pid, sig);
continue;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 37cfe77..7896cf9 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -330,6 +330,8 @@
#define MIN_VMALLOC (32 * 1024 * 1024)
+extern char __binary_start;
+
int linux_main(int argc, char **argv)
{
unsigned long avail, diff;
@@ -374,8 +376,9 @@
printf("UML running in %s mode\n", mode);
- uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
- &host_task_size, &task_size);
+ uml_start = (unsigned long) &__binary_start;
+ host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt,
+ set_task_sizes_skas, &task_size);
/*
* Setting up handlers to 'sig_info' struct
@@ -395,7 +398,7 @@
physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
}
- uml_physmem = uml_start;
+ uml_physmem = uml_start & PAGE_MASK;
/* Reserve up to 4M after the current brk */
uml_reserved = ROUND_4M(brk_start) + (1 << 22);
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index af11915..8eca47a 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -7,13 +7,16 @@
SECTIONS
{
- /*This must contain the right address - not quite the default ELF one.*/
+ /* This must contain the right address - not quite the default ELF one.*/
PROVIDE (__executable_start = START);
- . = START + SIZEOF_HEADERS;
+ /* Static binaries stick stuff here, like the sigreturn trampoline,
+ * invisibly to objdump. So, just make __binary_start equal to the very
+ * beginning of the executable, and if there are unmapped pages after this,
+ * they are forever unusable.
+ */
+ __binary_start = START;
- /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
- * is remapped.*/
- __binary_start = .;
+ . = START + SIZEOF_HEADERS;
#ifdef MODE_TT
.remap_data : { UNMAP_PATH (.data .bss) }
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 0925133..189fa67 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -18,6 +18,7 @@
#include "os.h"
#include "user.h"
#include "kern_util.h"
+#include "user_util.h"
static void copy_stat(struct uml_stat *dst, struct stat64 *src)
{
@@ -42,16 +43,13 @@
struct stat64 sbuf;
int err;
- do {
- err = fstat64(fd, &sbuf);
- } while((err < 0) && (errno == EINTR)) ;
-
+ CATCH_EINTR(err = fstat64(fd, &sbuf));
if(err < 0)
- return(-errno);
+ return -errno;
if(ubuf != NULL)
copy_stat(ubuf, &sbuf);
- return(err);
+ return err;
}
int os_stat_file(const char *file_name, struct uml_stat *ubuf)
@@ -64,11 +62,11 @@
} while((err < 0) && (errno == EINTR)) ;
if(err < 0)
- return(-errno);
+ return -errno;
if(ubuf != NULL)
copy_stat(ubuf, &sbuf);
- return(err);
+ return err;
}
int os_access(const char* file, int mode)
@@ -80,9 +78,9 @@
err = access(file, amode);
if(err < 0)
- return(-errno);
+ return -errno;
- return(0);
+ return 0;
}
void os_print_error(int error, const char* str)
@@ -99,9 +97,9 @@
err = ioctl(fd, cmd, arg);
if(err < 0)
- return(-errno);
+ return -errno;
- return(err);
+ return err;
}
int os_window_size(int fd, int *rows, int *cols)
@@ -109,12 +107,12 @@
struct winsize size;
if(ioctl(fd, TIOCGWINSZ, &size) < 0)
- return(-errno);
+ return -errno;
*rows = size.ws_row;
*cols = size.ws_col;
- return(0);
+ return 0;
}
int os_new_tty_pgrp(int fd, int pid)
@@ -125,16 +123,16 @@
if(tcsetpgrp(fd, pid) < 0)
return -errno;
- return(0);
+ return 0;
}
/* FIXME: ensure namebuf in os_get_if_name is big enough */
int os_get_ifname(int fd, char* namebuf)
{
if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
- return(-errno);
+ return -errno;
- return(0);
+ return 0;
}
int os_set_slip(int fd)
@@ -149,7 +147,7 @@
if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0)
return -errno;
- return(0);
+ return 0;
}
int os_set_owner(int fd, int pid)
@@ -158,10 +156,10 @@
int save_errno = errno;
if(fcntl(fd, F_GETOWN, 0) != pid)
- return(-save_errno);
+ return -save_errno;
}
- return(0);
+ return 0;
}
/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */
@@ -192,9 +190,9 @@
} while((err < 0) && (errno==EINTR)) ;
if(err < 0)
- return(-errno);
+ return -errno;
- return(0);
+ return 0;
}
int os_file_type(char *file)
@@ -204,15 +202,21 @@
err = os_stat_file(file, &buf);
if(err < 0)
- return(err);
+ return err;
- if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
- else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
- else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
- else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
- else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
- else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
- else return(OS_TYPE_FILE);
+ if(S_ISDIR(buf.ust_mode))
+ return OS_TYPE_DIR;
+ else if(S_ISLNK(buf.ust_mode))
+ return OS_TYPE_SYMLINK;
+ else if(S_ISCHR(buf.ust_mode))
+ return OS_TYPE_CHARDEV;
+ else if(S_ISBLK(buf.ust_mode))
+ return OS_TYPE_BLOCKDEV;
+ else if(S_ISFIFO(buf.ust_mode))
+ return OS_TYPE_FIFO;
+ else if(S_ISSOCK(buf.ust_mode))
+ return OS_TYPE_SOCK;
+ else return OS_TYPE_FILE;
}
int os_file_mode(char *file, struct openflags *mode_out)
@@ -302,8 +306,8 @@
actual = lseek64(fd, offset, SEEK_SET);
if(actual != offset)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
static int fault_buffer(void *start, int len,
@@ -314,13 +318,13 @@
for(i = 0; i < len; i += page){
if((*copy_proc)(start + i, &c, sizeof(c)))
- return(-EFAULT);
+ return -EFAULT;
}
if((len % page) != 0){
if((*copy_proc)(start + len - 1, &c, sizeof(c)))
- return(-EFAULT);
+ return -EFAULT;
}
- return(0);
+ return 0;
}
static int file_io(int fd, void *buf, int len,
@@ -334,26 +338,26 @@
if((n < 0) && (errno == EFAULT)){
err = fault_buffer(buf, len, copy_user_proc);
if(err)
- return(err);
+ return err;
n = (*io_proc)(fd, buf, len);
}
} while((n < 0) && (errno == EINTR));
if(n < 0)
- return(-errno);
- return(n);
+ return -errno;
+ return n;
}
int os_read_file(int fd, void *buf, int len)
{
- return(file_io(fd, buf, len, (int (*)(int, void *, int)) read,
- copy_from_user_proc));
+ return file_io(fd, buf, len, (int (*)(int, void *, int)) read,
+ copy_from_user_proc);
}
int os_write_file(int fd, const void *buf, int len)
{
- return(file_io(fd, (void *) buf, len,
- (int (*)(int, void *, int)) write, copy_to_user_proc));
+ return file_io(fd, (void *) buf, len,
+ (int (*)(int, void *, int)) write, copy_to_user_proc);
}
int os_file_size(char *file, unsigned long long *size_out)
@@ -398,11 +402,11 @@
err = os_stat_file(file, &buf);
if(err < 0){
printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
- return(err);
+ return err;
}
*modtime = buf.ust_mtime;
- return(0);
+ return 0;
}
int os_get_exec_close(int fd, int* close_on_exec)
@@ -455,7 +459,7 @@
if(err < 0)
goto error;
- return(0);
+ return 0;
error:
printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
@@ -486,12 +490,12 @@
(fcntl(fd, F_SETOWN, owner) < 0)){
err = -errno;
printk("os_set_fd_async : Failed to fcntl F_SETOWN "
- "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd,
+ "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd,
owner, errno);
return err;
}
- return(0);
+ return 0;
}
int os_clear_fd_async(int fd)
@@ -500,8 +504,8 @@
flags &= ~(O_ASYNC | O_NONBLOCK);
if(fcntl(fd, F_SETFL, flags) < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int os_set_fd_block(int fd, int blocking)
@@ -516,7 +520,7 @@
if(fcntl(fd, F_SETFL, flags) < 0)
return -errno;
- return(0);
+ return 0;
}
int os_accept_connection(int fd)
@@ -524,9 +528,9 @@
int new;
new = accept(fd, NULL, 0);
- if(new < 0)
- return(-errno);
- return(new);
+ if(new < 0)
+ return -errno;
+ return new;
}
#ifndef SHUT_RD
@@ -550,12 +554,12 @@
else if(w) what = SHUT_WR;
else {
printk("os_shutdown_socket : neither r or w was set\n");
- return(-EINVAL);
+ return -EINVAL;
}
err = shutdown(fd, what);
if(err < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int os_rcv_fd(int fd, int *helper_pid_out)
@@ -578,7 +582,7 @@
n = recvmsg(fd, &msg, 0);
if(n < 0)
- return(-errno);
+ return -errno;
else if(n != sizeof(iov.iov_len))
*helper_pid_out = -1;
@@ -586,16 +590,16 @@
cmsg = CMSG_FIRSTHDR(&msg);
if(cmsg == NULL){
printk("rcv_fd didn't receive anything, error = %d\n", errno);
- return(-1);
+ return -1;
}
- if((cmsg->cmsg_level != SOL_SOCKET) ||
+ if((cmsg->cmsg_level != SOL_SOCKET) ||
(cmsg->cmsg_type != SCM_RIGHTS)){
printk("rcv_fd didn't receive a descriptor\n");
- return(-1);
+ return -1;
}
new = ((int *) CMSG_DATA(cmsg))[0];
- return(new);
+ return new;
}
int os_create_unix_socket(char *file, int len, int close_on_exec)
@@ -623,7 +627,7 @@
if(err < 0)
return -errno;
- return(sock);
+ return sock;
}
void os_flush_stdout(void)
@@ -654,16 +658,5 @@
printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
err = save;
out:
- return(err);
+ return err;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index 3788d45..7555bf9 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -52,11 +52,6 @@
return n;
}
-int os_isatty(int fd)
-{
- return isatty(fd);
-}
-
int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds)
{
if (pollfds_num == pollfds_size) {
@@ -142,17 +137,14 @@
void init_irq_signals(int on_sigstack)
{
- __sighandler_t h;
int flags;
flags = on_sigstack ? SA_ONSTACK : 0;
- if (timer_irq_inited)
- h = (__sighandler_t)alarm_handler;
- else
- h = boot_timer_handler;
- set_handler(SIGVTALRM, h, flags | SA_RESTART,
- SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
+ set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
+ flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
+ set_handler(SIGALRM, (__sighandler_t) alarm_handler,
+ flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
signal(SIGWINCH, SIG_IGN);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 233be2f..b1cda81 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -250,25 +250,24 @@
if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
}
-void init_new_thread_signals(int altstack)
+void init_new_thread_signals(void)
{
- int flags = altstack ? SA_ONSTACK : 0;
-
- set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
+ set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
- set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags,
+ set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
- set_handler(SIGFPE, (__sighandler_t) sig_handler, flags,
+ set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
- set_handler(SIGILL, (__sighandler_t) sig_handler, flags,
+ set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
- set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
+ set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
set_handler(SIGUSR2, (__sighandler_t) sig_handler,
- flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
+ -1);
signal(SIGHUP, SIG_IGN);
- init_irq_signals(altstack);
+ init_irq_signals(1);
}
int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 00e9388..0ecac56 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -43,13 +43,13 @@
/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread
* synchronizes with it.
*/
-struct pollfds current_poll = {
+static struct pollfds current_poll = {
.poll = NULL,
.size = 0,
.used = 0
};
-struct pollfds next_poll = {
+static struct pollfds next_poll = {
.poll = NULL,
.size = 0,
.used = 0
@@ -156,7 +156,7 @@
set_signals(flags);
}
-int add_sigio_fd(int fd, int read)
+static int add_sigio_fd(int fd, int read)
{
int err = 0, i, n, events;
@@ -191,6 +191,13 @@
struct pollfd *p;
int err = 0, i, n = 0;
+ /* This is called from exitcalls elsewhere in UML - if
+ * sigio_cleanup has already run, then update_thread will hang
+ * or fail because the thread is no longer running.
+ */
+ if(write_sigio_pid == -1)
+ return -EIO;
+
sigio_lock();
for(i = 0; i < current_poll.used; i++){
if(current_poll.poll[i].fd == fd) break;
@@ -215,7 +222,7 @@
update_thread();
out:
sigio_unlock();
- return(err);
+ return err;
}
static struct pollfd *setup_initial_poll(int fd)
@@ -233,7 +240,7 @@
return p;
}
-void write_sigio_workaround(void)
+static void write_sigio_workaround(void)
{
unsigned long stack;
struct pollfd *p;
@@ -314,10 +321,24 @@
close(l_write_sigio_fds[1]);
}
-void sigio_cleanup(void)
+void maybe_sigio_broken(int fd, int read)
+{
+ if(!isatty(fd))
+ return;
+
+ if((read || pty_output_sigio) && (!read || pty_close_sigio))
+ return;
+
+ write_sigio_workaround();
+ add_sigio_fd(fd, read);
+}
+
+static void sigio_cleanup(void)
{
if(write_sigio_pid != -1){
os_kill_process(write_sigio_pid, 1);
write_sigio_pid = -1;
}
}
+
+__uml_exitcall(sigio_cleanup);
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index f11b312..60e4fae 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -106,29 +106,6 @@
set_signals(enabled);
}
-extern void do_boot_timer_handler(struct sigcontext * sc);
-
-void boot_timer_handler(ARCH_SIGHDLR_PARAM)
-{
- struct sigcontext *sc;
- int enabled;
-
- ARCH_GET_SIGCONTEXT(sc, sig);
-
- enabled = signals_enabled;
- if(!enabled){
- if(sig == SIGVTALRM)
- pending |= SIGVTALRM_MASK;
- else pending |= SIGALRM_MASK;
- return;
- }
-
- block_signals();
-
- do_boot_timer_handler(sc);
- set_signals(enabled);
-}
-
void set_sigstack(void *sig_stack, int size)
{
stack_t stack = ((stack_t) { .ss_flags = 0,
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index bd89c6b..bf35572 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -159,7 +159,7 @@
ptrace(PTRACE_TRACEME, 0, 0, 0);
- init_new_thread_signals(1);
+ init_new_thread_signals();
enable_timer();
if(!proc_mm){
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 280c4fb..4ae73c0 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -17,11 +17,6 @@
#include "kern_constants.h"
#include "os.h"
-/* XXX This really needs to be declared and initialized in a kernel file since
- * it's in <linux/time.h>
- */
-extern struct timespec wall_to_monotonic;
-
static void set_interval(int timer_type)
{
int usec = 1000000/hz();
@@ -71,6 +66,7 @@
errno);
}
+#ifdef UML_CONFIG_MODE_TT
void uml_idle_timer(void)
{
if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
@@ -80,14 +76,7 @@
SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
set_interval(ITIMER_REAL);
}
-
-void time_init(void)
-{
- if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
- panic("Couldn't set SIGVTALRM handler");
- set_interval(ITIMER_VIRTUAL);
- time_init_kern();
-}
+#endif
unsigned long long os_nsecs(void)
{
@@ -106,15 +95,7 @@
nanosleep(&ts, NULL);
}
-/* XXX This partly duplicates init_irq_signals */
-
void user_time_init(void)
{
- set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
- SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
- SIGALRM, SIGUSR2, -1);
- set_handler(SIGALRM, (__sighandler_t) alarm_handler,
- SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
- SIGVTALRM, SIGUSR2, -1);
set_interval(ITIMER_VIRTUAL);
}
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index e69d403..83d389b 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,11 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-git6
-# Sat Jun 24 00:52:28 2006
+# Linux kernel version: 2.6.17-git22
+# Tue Jul 4 14:24:40 2006
#
CONFIG_X86_64=y
CONFIG_64BIT=y
CONFIG_X86=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_MMU=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -17,6 +19,7 @@
CONFIG_GENERIC_IOMAP=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
@@ -52,10 +55,12 @@
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -136,10 +141,12 @@
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y
CONFIG_NR_CPUS=32
CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_IOMMU=y
@@ -186,6 +193,7 @@
# CONFIG_ACPI_VIDEO is not set
# CONFIG_ACPI_HOTKEY is not set
CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=y
@@ -200,7 +208,7 @@
CONFIG_ACPI_SYSTEM=y
CONFIG_X86_PM_TIMER=y
CONFIG_ACPI_CONTAINER=y
-CONFIG_ACPI_HOTPLUG_MEMORY=y
+# CONFIG_ACPI_SBS is not set
#
# CPU Frequency scaling
@@ -801,6 +809,7 @@
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -870,6 +879,9 @@
#
# CONFIG_USBPCWATCHDOG is not set
CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=y
+CONFIG_HW_RANDOM_AMD=y
+# CONFIG_HW_RANDOM_GEODE is not set
# CONFIG_NVRAM is not set
CONFIG_RTC=y
# CONFIG_DTLK is not set
@@ -886,6 +898,7 @@
# CONFIG_AGP_VIA is not set
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
+# CONFIG_PC8736x_GPIO is not set
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
CONFIG_HPET=y
@@ -1030,8 +1043,8 @@
#
# Graphics support
#
+# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB is not set
-CONFIG_VIDEO_SELECT=y
#
# Console display driver support
@@ -1039,6 +1052,7 @@
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=256
+CONFIG_VIDEO_SELECT=y
CONFIG_DUMMY_CONSOLE=y
#
@@ -1359,6 +1373,7 @@
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
+# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -1424,16 +1439,24 @@
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_FS=y
@@ -1445,6 +1468,8 @@
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_DEBUG_RODATA is not set
# CONFIG_IOMMU_DEBUG is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
#
# Security options
@@ -1468,3 +1493,4 @@
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index 926c474..a9dc0f3 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -182,7 +182,7 @@
#define user user32
#define __ASM_X86_64_ELF_H 1
-#define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
+#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)
//#include <asm/ia32.h>
#include <linux/elf.h>
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
index a590b7a..659c072 100644
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -202,17 +202,24 @@
{
int ret;
compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data);
+ siginfo_t ssi;
siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t));
if (request == PTRACE_SETSIGINFO) {
- ret = copy_siginfo_from_user32(si, si32);
+ memset(&ssi, 0, sizeof(siginfo_t));
+ ret = copy_siginfo_from_user32(&ssi, si32);
if (ret)
return ret;
+ if (copy_to_user(si, &ssi, sizeof(siginfo_t)))
+ return -EFAULT;
}
ret = sys_ptrace(request, pid, addr, (unsigned long)si);
if (ret)
return ret;
- if (request == PTRACE_GETSIGINFO)
- ret = copy_siginfo_to_user32(si32, si);
+ if (request == PTRACE_GETSIGINFO) {
+ if (copy_from_user(&ssi, si, sizeof(siginfo_t)))
+ return -EFAULT;
+ ret = copy_siginfo_to_user32(si32, &ssi);
+ }
return ret;
}
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index b8eee4c..e56c2ad 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -17,6 +17,7 @@
#include <linux/kexec.h>
#include <linux/module.h>
+#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/e820.h>
#include <asm/proto.h>
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index b93ef5b..140051e 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -2,7 +2,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/fcntl.h>
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c
index 335200a..db2acbf 100644
--- a/arch/x86_64/kernel/mce_amd.c
+++ b/arch/x86_64/kernel/mce_amd.c
@@ -597,7 +597,7 @@
/* sibling symlink */
if (shared_bank[bank] && b->blocks->cpu != cpu) {
sysfs_remove_link(&per_cpu(device_mce, cpu).kobj, name);
- per_cpu(threshold_banks, i)[bank] = NULL;
+ per_cpu(threshold_banks, cpu)[bank] = NULL;
return;
}
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index d91cb84..e71ed53 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -1,9 +1,11 @@
/*
* Derived from arch/powerpc/kernel/iommu.c
*
- * Copyright (C) 2006 Jon Mason <jdmason@us.ibm.com>, IBM Corporation
- * Copyright (C) 2006 Muli Ben-Yehuda <muli@il.ibm.com>, IBM Corporation
+ * Copyright (C) IBM Corporation, 2006
*
+ * Author: Jon Mason <jdmason@us.ibm.com>
+ * Author: Muli Ben-Yehuda <muli@il.ibm.com>
+
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 0925518..8a099ff 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -21,7 +21,7 @@
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index b7c7059..9753802 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -771,12 +771,10 @@
unsigned long start_rip;
struct create_idle c_idle = {
.cpu = cpu,
- .done = COMPLETION_INITIALIZER(c_idle.done),
+ .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
};
DECLARE_WORK(work, do_fork_idle, &c_idle);
- lockdep_set_class(&c_idle.done.wait.lock, &waitqueue_lock_key);
-
/* allocate memory for gdts of secondary cpus. Hotplug is considered */
if (!cpu_gdt_descr[cpu].address &&
!(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
diff --git a/arch/x86_64/kernel/tce.c b/arch/x86_64/kernel/tce.c
index 8d4c67f..d3a9e79 100644
--- a/arch/x86_64/kernel/tce.c
+++ b/arch/x86_64/kernel/tce.c
@@ -1,8 +1,10 @@
/*
* Derived from arch/powerpc/platforms/pseries/iommu.c
*
- * Copyright (C) 2006 Jon Mason <jdmason@us.ibm.com>, IBM Corporation
- * Copyright (C) 2006 Muli Ben-Yehuda <muli@il.ibm.com>, IBM Corporation
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Jon Mason <jdmason@us.ibm.com>
+ * Author: Muli Ben-Yehuda <muli@il.ibm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 79d05c4..eb39a27 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -76,13 +76,13 @@
vmalloc_sync_all();
return atomic_notifier_chain_register(&die_chain, nb);
}
-EXPORT_SYMBOL(register_die_notifier);
+EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
int unregister_die_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(&die_chain, nb);
}
-EXPORT_SYMBOL(unregister_die_notifier);
+EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
static inline void conditional_sti(struct pt_regs *regs)
{
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index edb2941..82684d0 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -17,7 +17,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
#include <linux/bootmem.h>
#include <linux/kernel.h>
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 290c767..56c5ba8 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -107,7 +107,6 @@
config ACPI_VIDEO
tristate "Video"
depends on X86
- default y
help
This driver implement the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in
@@ -133,6 +132,12 @@
This driver adds support for ACPI fan devices, allowing user-mode
applications to perform basic fan control (on, off, status).
+config ACPI_DOCK
+ tristate "Dock"
+ depends on EXPERIMENTAL
+ help
+ This driver adds support for ACPI controlled docking stations
+
config ACPI_PROCESSOR
tristate "Processor"
default y
@@ -207,6 +212,7 @@
config ACPI_IBM_DOCK
bool "Legacy Docking Station Support"
depends on ACPI_IBM
+ depends on ACPI_DOCK=n
default n
---help---
Allows the ibm_acpi driver to handle docking station events.
@@ -350,7 +356,6 @@
tristate "Smart Battery System (EXPERIMENTAL)"
depends on X86 && I2C
depends on EXPERIMENTAL
- default y
help
This driver adds support for the Smart Battery System.
Depends on I2C (Device Drivers ---> I2C support)
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index bb5b80a..bce7ca2 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -42,6 +42,7 @@
obj-$(CONFIG_ACPI_BUTTON) += button.o
obj-$(CONFIG_ACPI_EC) += ec.o
obj-$(CONFIG_ACPI_FAN) += fan.o
+obj-$(CONFIG_ACPI_DOCK) += dock.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o
obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 24ccf81..96309b9 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -72,7 +72,7 @@
unsigned long state;
};
-static struct file_operations acpi_ac_fops = {
+static const struct file_operations acpi_ac_fops = {
.open = acpi_ac_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 24bf4dc..6e52217 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -557,7 +557,7 @@
return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
}
-static struct file_operations acpi_battery_info_ops = {
+static const struct file_operations acpi_battery_info_ops = {
.open = acpi_battery_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -565,7 +565,7 @@
.owner = THIS_MODULE,
};
-static struct file_operations acpi_battery_state_ops = {
+static const struct file_operations acpi_battery_state_ops = {
.open = acpi_battery_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -573,7 +573,7 @@
.owner = THIS_MODULE,
};
-static struct file_operations acpi_battery_alarm_ops = {
+static const struct file_operations acpi_battery_alarm_ops = {
.open = acpi_battery_alarm_open_fs,
.read = seq_read,
.write = acpi_battery_write_alarm,
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index ea5a049..b297769 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -192,8 +192,8 @@
/* Make sure this is a valid target state */
if (!device->flags.power_manageable) {
- printk(KERN_DEBUG "Device `[%s]' is not power manageable",
- device->kobj.name);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable",
+ device->kobj.name));
return -ENODEV;
}
/*
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index fd1ba05..5ef885e 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -87,14 +87,14 @@
unsigned long pushed;
};
-static struct file_operations acpi_button_info_fops = {
+static const struct file_operations acpi_button_info_fops = {
.open = acpi_button_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations acpi_button_state_fops = {
+static const struct file_operations acpi_button_state_fops = {
.open = acpi_button_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c
index 574a75a..a01ce67 100644
--- a/drivers/acpi/cm_sbs.c
+++ b/drivers/acpi/cm_sbs.c
@@ -39,50 +39,43 @@
static struct proc_dir_entry *acpi_ac_dir;
static struct proc_dir_entry *acpi_battery_dir;
-static struct semaphore cm_sbs_sem;
+static DEFINE_MUTEX(cm_sbs_mutex);
-static int lock_ac_dir_cnt = 0;
-static int lock_battery_dir_cnt = 0;
+static int lock_ac_dir_cnt;
+static int lock_battery_dir_cnt;
struct proc_dir_entry *acpi_lock_ac_dir(void)
{
-
- down(&cm_sbs_sem);
- if (!acpi_ac_dir) {
+ mutex_lock(&cm_sbs_mutex);
+ if (!acpi_ac_dir)
acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir);
- }
if (acpi_ac_dir) {
lock_ac_dir_cnt++;
} else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Cannot create %s\n", ACPI_AC_CLASS));
}
- up(&cm_sbs_sem);
+ mutex_unlock(&cm_sbs_mutex);
return acpi_ac_dir;
}
-
EXPORT_SYMBOL(acpi_lock_ac_dir);
void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param)
{
-
- down(&cm_sbs_sem);
- if (acpi_ac_dir_param) {
+ mutex_lock(&cm_sbs_mutex);
+ if (acpi_ac_dir_param)
lock_ac_dir_cnt--;
- }
if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) {
remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
acpi_ac_dir = 0;
}
- up(&cm_sbs_sem);
+ mutex_unlock(&cm_sbs_mutex);
}
-
EXPORT_SYMBOL(acpi_unlock_ac_dir);
struct proc_dir_entry *acpi_lock_battery_dir(void)
{
-
- down(&cm_sbs_sem);
+ mutex_lock(&cm_sbs_mutex);
if (!acpi_battery_dir) {
acpi_battery_dir =
proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir);
@@ -93,39 +86,28 @@
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Cannot create %s\n", ACPI_BATTERY_CLASS));
}
- up(&cm_sbs_sem);
+ mutex_unlock(&cm_sbs_mutex);
return acpi_battery_dir;
}
-
EXPORT_SYMBOL(acpi_lock_battery_dir);
void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param)
{
-
- down(&cm_sbs_sem);
- if (acpi_battery_dir_param) {
+ mutex_lock(&cm_sbs_mutex);
+ if (acpi_battery_dir_param)
lock_battery_dir_cnt--;
- }
if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param
&& acpi_battery_dir) {
remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
acpi_battery_dir = 0;
}
- up(&cm_sbs_sem);
+ mutex_unlock(&cm_sbs_mutex);
return;
}
-
EXPORT_SYMBOL(acpi_unlock_battery_dir);
static int __init acpi_cm_sbs_init(void)
{
-
- if (acpi_disabled)
- return 0;
-
- init_MUTEX(&cm_sbs_sem);
-
return 0;
}
-
subsys_initcall(acpi_cm_sbs_init);
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index daf51b5..1888c05 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -116,16 +116,6 @@
case ACPI_TYPE_METHOD:
- /*
- * Set the execution data width (32 or 64) based upon the
- * revision number of the parent ACPI table.
- * TBD: This is really for possible future support of integer width
- * on a per-table basis. Currently, we just use a global for the width.
- */
- if (info->table_desc->pointer->revision == 1) {
- node->flags |= ANOBJ_DATA_WIDTH_32;
- }
-
info->method_count++;
break;
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index a39a33f..cf888ad 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -134,7 +134,7 @@
union acpi_operand_object *mutex_desc;
acpi_status status;
- ACPI_FUNCTION_NAME(ds_create_method_mutex);
+ ACPI_FUNCTION_TRACE(ds_create_method_mutex);
/* Create the new mutex object */
@@ -493,7 +493,7 @@
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
"****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
- (char *)&walk_state->method_node->name,
+ acpi_ut_get_node_name(walk_state->method_node),
walk_state->method_call_op, return_desc));
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
@@ -610,6 +610,7 @@
acpi_os_release_mutex(method_desc->method.mutex->mutex.
os_mutex);
+ method_desc->method.mutex->mutex.owner_thread = NULL;
}
}
@@ -620,27 +621,11 @@
*/
method_node = walk_state->method_node;
- /* Lock namespace for possible update */
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE(status)) {
- return_VOID;
- }
-
/*
- * Delete any namespace entries created immediately underneath
- * the method
- */
- if (method_node && method_node->child) {
- acpi_ns_delete_namespace_subtree(method_node);
- }
-
- /*
- * Delete any namespace entries created anywhere else within
+ * Delete any namespace objects created anywhere within
* the namespace by the execution of this method
*/
acpi_ns_delete_namespace_by_owner(method_desc->method.owner_id);
- status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
}
/* Decrement the thread count on the method */
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index b1ded62..d7a616c 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -313,10 +313,10 @@
case AML_CLASS_EXECUTE:
case AML_CLASS_CREATE:
/*
- * Most operators with arguments.
+ * Most operators with arguments (except create_xxx_field operators)
* Start a new result/operand state
*/
- if (walk_state->opcode != AML_CREATE_FIELD_OP) {
+ if (walk_state->op_info->object_type != ACPI_TYPE_BUFFER_FIELD) {
status = acpi_ds_result_stack_push(walk_state);
}
break;
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
new file mode 100644
index 0000000..1c0a39d
--- /dev/null
+++ b/drivers/acpi/dock.c
@@ -0,0 +1,740 @@
+/*
+ * dock.c - ACPI dock station driver
+ *
+ * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/notifier.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_DOCK_DRIVER_NAME "ACPI Dock Station Driver"
+
+ACPI_MODULE_NAME("dock")
+MODULE_AUTHOR("Kristen Carlson Accardi");
+MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static struct atomic_notifier_head dock_notifier_list;
+
+struct dock_station {
+ acpi_handle handle;
+ unsigned long last_dock_time;
+ u32 flags;
+ spinlock_t dd_lock;
+ spinlock_t hp_lock;
+ struct list_head dependent_devices;
+ struct list_head hotplug_devices;
+};
+
+struct dock_dependent_device {
+ struct list_head list;
+ struct list_head hotplug_list;
+ acpi_handle handle;
+ acpi_notify_handler handler;
+ void *context;
+};
+
+#define DOCK_DOCKING 0x00000001
+#define DOCK_EVENT KOBJ_DOCK
+#define UNDOCK_EVENT KOBJ_UNDOCK
+
+static struct dock_station *dock_station;
+
+/*****************************************************************************
+ * Dock Dependent device functions *
+ *****************************************************************************/
+/**
+ * alloc_dock_dependent_device - allocate and init a dependent device
+ * @handle: the acpi_handle of the dependent device
+ *
+ * Allocate memory for a dependent device structure for a device referenced
+ * by the acpi handle
+ */
+static struct dock_dependent_device *
+alloc_dock_dependent_device(acpi_handle handle)
+{
+ struct dock_dependent_device *dd;
+
+ dd = kzalloc(sizeof(*dd), GFP_KERNEL);
+ if (dd) {
+ dd->handle = handle;
+ INIT_LIST_HEAD(&dd->list);
+ INIT_LIST_HEAD(&dd->hotplug_list);
+ }
+ return dd;
+}
+
+/**
+ * add_dock_dependent_device - associate a device with the dock station
+ * @ds: The dock station
+ * @dd: The dependent device
+ *
+ * Add the dependent device to the dock's dependent device list.
+ */
+static void
+add_dock_dependent_device(struct dock_station *ds,
+ struct dock_dependent_device *dd)
+{
+ spin_lock(&ds->dd_lock);
+ list_add_tail(&dd->list, &ds->dependent_devices);
+ spin_unlock(&ds->dd_lock);
+}
+
+/**
+ * dock_add_hotplug_device - associate a hotplug handler with the dock station
+ * @ds: The dock station
+ * @dd: The dependent device struct
+ *
+ * Add the dependent device to the dock's hotplug device list
+ */
+static void
+dock_add_hotplug_device(struct dock_station *ds,
+ struct dock_dependent_device *dd)
+{
+ spin_lock(&ds->hp_lock);
+ list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
+ spin_unlock(&ds->hp_lock);
+}
+
+/**
+ * dock_del_hotplug_device - remove a hotplug handler from the dock station
+ * @ds: The dock station
+ * @dd: the dependent device struct
+ *
+ * Delete the dependent device from the dock's hotplug device list
+ */
+static void
+dock_del_hotplug_device(struct dock_station *ds,
+ struct dock_dependent_device *dd)
+{
+ spin_lock(&ds->hp_lock);
+ list_del(&dd->hotplug_list);
+ spin_unlock(&ds->hp_lock);
+}
+
+/**
+ * find_dock_dependent_device - get a device dependent on this dock
+ * @ds: the dock station
+ * @handle: the acpi_handle of the device we want
+ *
+ * iterate over the dependent device list for this dock. If the
+ * dependent device matches the handle, return.
+ */
+static struct dock_dependent_device *
+find_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
+{
+ struct dock_dependent_device *dd;
+
+ spin_lock(&ds->dd_lock);
+ list_for_each_entry(dd, &ds->dependent_devices, list) {
+ if (handle == dd->handle) {
+ spin_unlock(&ds->dd_lock);
+ return dd;
+ }
+ }
+ spin_unlock(&ds->dd_lock);
+ return NULL;
+}
+
+/*****************************************************************************
+ * Dock functions *
+ *****************************************************************************/
+/**
+ * is_dock - see if a device is a dock station
+ * @handle: acpi handle of the device
+ *
+ * If an acpi object has a _DCK method, then it is by definition a dock
+ * station, so return true.
+ */
+static int is_dock(acpi_handle handle)
+{
+ acpi_status status;
+ acpi_handle tmp;
+
+ status = acpi_get_handle(handle, "_DCK", &tmp);
+ if (ACPI_FAILURE(status))
+ return 0;
+ return 1;
+}
+
+/**
+ * is_dock_device - see if a device is on a dock station
+ * @handle: acpi handle of the device
+ *
+ * If this device is either the dock station itself,
+ * or is a device dependent on the dock station, then it
+ * is a dock device
+ */
+int is_dock_device(acpi_handle handle)
+{
+ if (!dock_station)
+ return 0;
+
+ if (is_dock(handle) || find_dock_dependent_device(dock_station, handle))
+ return 1;
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(is_dock_device);
+
+/**
+ * dock_present - see if the dock station is present.
+ * @ds: the dock station
+ *
+ * execute the _STA method. note that present does not
+ * imply that we are docked.
+ */
+static int dock_present(struct dock_station *ds)
+{
+ unsigned long sta;
+ acpi_status status;
+
+ if (ds) {
+ status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
+ if (ACPI_SUCCESS(status) && sta)
+ return 1;
+ }
+ return 0;
+}
+
+
+
+/**
+ * dock_create_acpi_device - add new devices to acpi
+ * @handle - handle of the device to add
+ *
+ * This function will create a new acpi_device for the given
+ * handle if one does not exist already. This should cause
+ * acpi to scan for drivers for the given devices, and call
+ * matching driver's add routine.
+ *
+ * Returns a pointer to the acpi_device corresponding to the handle.
+ */
+static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
+{
+ struct acpi_device *device = NULL;
+ struct acpi_device *parent_device;
+ acpi_handle parent;
+ int ret;
+
+ if (acpi_bus_get_device(handle, &device)) {
+ /*
+ * no device created for this object,
+ * so we should create one.
+ */
+ acpi_get_parent(handle, &parent);
+ if (acpi_bus_get_device(parent, &parent_device))
+ parent_device = NULL;
+
+ ret = acpi_bus_add(&device, parent_device, handle,
+ ACPI_BUS_TYPE_DEVICE);
+ if (ret) {
+ pr_debug("error adding bus, %x\n",
+ -ret);
+ return NULL;
+ }
+ }
+ return device;
+}
+
+/**
+ * dock_remove_acpi_device - remove the acpi_device struct from acpi
+ * @handle - the handle of the device to remove
+ *
+ * Tell acpi to remove the acpi_device. This should cause any loaded
+ * driver to have it's remove routine called.
+ */
+static void dock_remove_acpi_device(acpi_handle handle)
+{
+ struct acpi_device *device;
+ int ret;
+
+ if (!acpi_bus_get_device(handle, &device)) {
+ ret = acpi_bus_trim(device, 1);
+ if (ret)
+ pr_debug("error removing bus, %x\n", -ret);
+ }
+}
+
+
+/**
+ * hotplug_dock_devices - insert or remove devices on the dock station
+ * @ds: the dock station
+ * @event: either bus check or eject request
+ *
+ * Some devices on the dock station need to have drivers called
+ * to perform hotplug operations after a dock event has occurred.
+ * Traverse the list of dock devices that have registered a
+ * hotplug handler, and call the handler.
+ */
+static void hotplug_dock_devices(struct dock_station *ds, u32 event)
+{
+ struct dock_dependent_device *dd;
+
+ spin_lock(&ds->hp_lock);
+
+ /*
+ * First call driver specific hotplug functions
+ */
+ list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
+ if (dd->handler)
+ dd->handler(dd->handle, event, dd->context);
+ }
+
+ /*
+ * Now make sure that an acpi_device is created for each
+ * dependent device, or removed if this is an eject request.
+ * This will cause acpi_drivers to be stopped/started if they
+ * exist
+ */
+ list_for_each_entry(dd, &ds->dependent_devices, list) {
+ if (event == ACPI_NOTIFY_EJECT_REQUEST)
+ dock_remove_acpi_device(dd->handle);
+ else
+ dock_create_acpi_device(dd->handle);
+ }
+ spin_unlock(&ds->hp_lock);
+}
+
+static void dock_event(struct dock_station *ds, u32 event, int num)
+{
+ struct acpi_device *device;
+
+ device = dock_create_acpi_device(ds->handle);
+ if (device)
+ kobject_uevent(&device->kobj, num);
+}
+
+/**
+ * eject_dock - respond to a dock eject request
+ * @ds: the dock station
+ *
+ * This is called after _DCK is called, to execute the dock station's
+ * _EJ0 method.
+ */
+static void eject_dock(struct dock_station *ds)
+{
+ struct acpi_object_list arg_list;
+ union acpi_object arg;
+ acpi_status status;
+ acpi_handle tmp;
+
+ /* all dock devices should have _EJ0, but check anyway */
+ status = acpi_get_handle(ds->handle, "_EJ0", &tmp);
+ if (ACPI_FAILURE(status)) {
+ pr_debug("No _EJ0 support for dock device\n");
+ return;
+ }
+
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = 1;
+
+ if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0",
+ &arg_list, NULL)))
+ pr_debug("Failed to evaluate _EJ0!\n");
+}
+
+/**
+ * handle_dock - handle a dock event
+ * @ds: the dock station
+ * @dock: to dock, or undock - that is the question
+ *
+ * Execute the _DCK method in response to an acpi event
+ */
+static void handle_dock(struct dock_station *ds, int dock)
+{
+ acpi_status status;
+ struct acpi_object_list arg_list;
+ union acpi_object arg;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+
+ acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer);
+ obj = name_buffer.pointer;
+
+ printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking");
+
+ /* _DCK method has one argument */
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = dock;
+ status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
+ if (ACPI_FAILURE(status))
+ pr_debug("%s: failed to execute _DCK\n", obj->string.pointer);
+ kfree(buffer.pointer);
+ kfree(name_buffer.pointer);
+}
+
+static inline void dock(struct dock_station *ds)
+{
+ handle_dock(ds, 1);
+}
+
+static inline void undock(struct dock_station *ds)
+{
+ handle_dock(ds, 0);
+}
+
+static inline void begin_dock(struct dock_station *ds)
+{
+ ds->flags |= DOCK_DOCKING;
+}
+
+static inline void complete_dock(struct dock_station *ds)
+{
+ ds->flags &= ~(DOCK_DOCKING);
+ ds->last_dock_time = jiffies;
+}
+
+/**
+ * dock_in_progress - see if we are in the middle of handling a dock event
+ * @ds: the dock station
+ *
+ * Sometimes while docking, false dock events can be sent to the driver
+ * because good connections aren't made or some other reason. Ignore these
+ * if we are in the middle of doing something.
+ */
+static int dock_in_progress(struct dock_station *ds)
+{
+ if ((ds->flags & DOCK_DOCKING) ||
+ time_before(jiffies, (ds->last_dock_time + HZ)))
+ return 1;
+ return 0;
+}
+
+/**
+ * register_dock_notifier - add yourself to the dock notifier list
+ * @nb: the callers notifier block
+ *
+ * If a driver wishes to be notified about dock events, they can
+ * use this function to put a notifier block on the dock notifier list.
+ * this notifier call chain will be called after a dock event, but
+ * before hotplugging any new devices.
+ */
+int register_dock_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&dock_notifier_list, nb);
+}
+
+EXPORT_SYMBOL_GPL(register_dock_notifier);
+
+/**
+ * unregister_dock_notifier - remove yourself from the dock notifier list
+ * @nb: the callers notifier block
+ */
+void unregister_dock_notifier(struct notifier_block *nb)
+{
+ atomic_notifier_chain_unregister(&dock_notifier_list, nb);
+}
+
+EXPORT_SYMBOL_GPL(unregister_dock_notifier);
+
+/**
+ * register_hotplug_dock_device - register a hotplug function
+ * @handle: the handle of the device
+ * @handler: the acpi_notifier_handler to call after docking
+ * @context: device specific data
+ *
+ * If a driver would like to perform a hotplug operation after a dock
+ * event, they can register an acpi_notifiy_handler to be called by
+ * the dock driver after _DCK is executed.
+ */
+int
+register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
+ void *context)
+{
+ struct dock_dependent_device *dd;
+
+ if (!dock_station)
+ return -ENODEV;
+
+ /*
+ * make sure this handle is for a device dependent on the dock,
+ * this would include the dock station itself
+ */
+ dd = find_dock_dependent_device(dock_station, handle);
+ if (dd) {
+ dd->handler = handler;
+ dd->context = context;
+ dock_add_hotplug_device(dock_station, dd);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
+
+/**
+ * unregister_hotplug_dock_device - remove yourself from the hotplug list
+ * @handle: the acpi handle of the device
+ */
+void unregister_hotplug_dock_device(acpi_handle handle)
+{
+ struct dock_dependent_device *dd;
+
+ if (!dock_station)
+ return;
+
+ dd = find_dock_dependent_device(dock_station, handle);
+ if (dd)
+ dock_del_hotplug_device(dock_station, dd);
+}
+
+EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
+
+/**
+ * dock_notify - act upon an acpi dock notification
+ * @handle: the dock station handle
+ * @event: the acpi event
+ * @data: our driver data struct
+ *
+ * If we are notified to dock, then check to see if the dock is
+ * present and then dock. Notify all drivers of the dock event,
+ * and then hotplug and devices that may need hotplugging. For undock
+ * check to make sure the dock device is still present, then undock
+ * and hotremove all the devices that may need removing.
+ */
+static void dock_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct dock_station *ds = (struct dock_station *)data;
+
+ switch (event) {
+ case ACPI_NOTIFY_BUS_CHECK:
+ if (!dock_in_progress(ds) && dock_present(ds)) {
+ begin_dock(ds);
+ dock(ds);
+ if (!dock_present(ds)) {
+ printk(KERN_ERR PREFIX "Unable to dock!\n");
+ break;
+ }
+ atomic_notifier_call_chain(&dock_notifier_list,
+ event, NULL);
+ hotplug_dock_devices(ds, event);
+ complete_dock(ds);
+ dock_event(ds, event, DOCK_EVENT);
+ }
+ break;
+ case ACPI_NOTIFY_DEVICE_CHECK:
+ /*
+ * According to acpi spec 3.0a, if a DEVICE_CHECK notification
+ * is sent and _DCK is present, it is assumed to mean an
+ * undock request. This notify routine will only be called
+ * for objects defining _DCK, so we will fall through to eject
+ * request here. However, we will pass an eject request through
+ * to the driver who wish to hotplug.
+ */
+ case ACPI_NOTIFY_EJECT_REQUEST:
+ if (!dock_in_progress(ds) && dock_present(ds)) {
+ /*
+ * here we need to generate the undock
+ * event prior to actually doing the undock
+ * so that the device struct still exists.
+ */
+ dock_event(ds, event, UNDOCK_EVENT);
+ hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
+ undock(ds);
+ eject_dock(ds);
+ if (dock_present(ds))
+ printk(KERN_ERR PREFIX "Unable to undock!\n");
+ }
+ break;
+ default:
+ printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
+ }
+}
+
+/**
+ * find_dock_devices - find devices on the dock station
+ * @handle: the handle of the device we are examining
+ * @lvl: unused
+ * @context: the dock station private data
+ * @rv: unused
+ *
+ * This function is called by acpi_walk_namespace. It will
+ * check to see if an object has an _EJD method. If it does, then it
+ * will see if it is dependent on the dock station.
+ */
+static acpi_status
+find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ acpi_status status;
+ acpi_handle tmp;
+ struct dock_station *ds = (struct dock_station *)context;
+ struct dock_dependent_device *dd;
+
+ status = acpi_bus_get_ejd(handle, &tmp);
+ if (ACPI_FAILURE(status))
+ return AE_OK;
+
+ if (tmp == ds->handle) {
+ dd = alloc_dock_dependent_device(handle);
+ if (dd)
+ add_dock_dependent_device(ds, dd);
+ }
+
+ return AE_OK;
+}
+
+/**
+ * dock_add - add a new dock station
+ * @handle: the dock station handle
+ *
+ * allocated and initialize a new dock station device. Find all devices
+ * that are on the dock station, and register for dock event notifications.
+ */
+static int dock_add(acpi_handle handle)
+{
+ int ret;
+ acpi_status status;
+ struct dock_dependent_device *dd;
+
+ /* allocate & initialize the dock_station private data */
+ dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
+ if (!dock_station)
+ return -ENOMEM;
+ dock_station->handle = handle;
+ dock_station->last_dock_time = jiffies - HZ;
+ INIT_LIST_HEAD(&dock_station->dependent_devices);
+ INIT_LIST_HEAD(&dock_station->hotplug_devices);
+ spin_lock_init(&dock_station->dd_lock);
+ spin_lock_init(&dock_station->hp_lock);
+ ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
+
+ /* Find dependent devices */
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, find_dock_devices, dock_station,
+ NULL);
+
+ /* add the dock station as a device dependent on itself */
+ dd = alloc_dock_dependent_device(handle);
+ if (!dd) {
+ kfree(dock_station);
+ return -ENOMEM;
+ }
+ add_dock_dependent_device(dock_station, dd);
+
+ /* register for dock events */
+ status = acpi_install_notify_handler(dock_station->handle,
+ ACPI_SYSTEM_NOTIFY,
+ dock_notify, dock_station);
+
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "Error installing notify handler\n");
+ ret = -ENODEV;
+ goto dock_add_err;
+ }
+
+ printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_NAME);
+
+ return 0;
+
+dock_add_err:
+ kfree(dock_station);
+ kfree(dd);
+ return ret;
+}
+
+/**
+ * dock_remove - free up resources related to the dock station
+ */
+static int dock_remove(void)
+{
+ struct dock_dependent_device *dd, *tmp;
+ acpi_status status;
+
+ if (!dock_station)
+ return 0;
+
+ /* remove dependent devices */
+ list_for_each_entry_safe(dd, tmp, &dock_station->dependent_devices,
+ list)
+ kfree(dd);
+
+ /* remove dock notify handler */
+ status = acpi_remove_notify_handler(dock_station->handle,
+ ACPI_SYSTEM_NOTIFY,
+ dock_notify);
+ if (ACPI_FAILURE(status))
+ printk(KERN_ERR "Error removing notify handler\n");
+
+ /* free dock station memory */
+ kfree(dock_station);
+ return 0;
+}
+
+/**
+ * find_dock - look for a dock station
+ * @handle: acpi handle of a device
+ * @lvl: unused
+ * @context: counter of dock stations found
+ * @rv: unused
+ *
+ * This is called by acpi_walk_namespace to look for dock stations.
+ */
+static acpi_status
+find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ int *count = (int *)context;
+ acpi_status status = AE_OK;
+
+ if (is_dock(handle)) {
+ if (dock_add(handle) >= 0) {
+ (*count)++;
+ status = AE_CTRL_TERMINATE;
+ }
+ }
+ return status;
+}
+
+static int __init dock_init(void)
+{
+ int num = 0;
+
+ dock_station = NULL;
+
+ /* look for a dock station */
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, find_dock, &num, NULL);
+
+ if (!num)
+ return -ENODEV;
+
+ return 0;
+}
+
+static void __exit dock_exit(void)
+{
+ dock_remove();
+}
+
+postcore_initcall(dock_init);
+module_exit(dock_exit);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 8c5d7df..e5d7963 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -929,7 +929,7 @@
return single_open(file, acpi_ec_read_info, PDE(inode)->data);
}
-static struct file_operations acpi_ec_info_ops = {
+static const struct file_operations acpi_ec_info_ops = {
.open = acpi_ec_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index a901b23..959a893 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -99,7 +99,7 @@
return 0;
}
-static struct file_operations acpi_system_event_ops = {
+static const struct file_operations acpi_system_event_ops = {
.open = acpi_system_open_event,
.read = acpi_system_read_event,
.release = acpi_system_close_event,
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 094a17e..21caae0 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -528,34 +528,40 @@
}
}
- /* Call the setup handler with the deactivate notification */
+ /*
+ * If the region has been activated, call the setup handler
+ * with the deactivate notification
+ */
+ if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
+ region_setup = handler_obj->address_space.setup;
+ status =
+ region_setup(region_obj,
+ ACPI_REGION_DEACTIVATE,
+ handler_obj->address_space.
+ context, region_context);
- region_setup = handler_obj->address_space.setup;
- status =
- region_setup(region_obj, ACPI_REGION_DEACTIVATE,
- handler_obj->address_space.context,
- region_context);
+ /* Init routine may fail, Just ignore errors */
- /* Init routine may fail, Just ignore errors */
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "from region handler - deactivate, [%s]",
+ acpi_ut_get_region_name
+ (region_obj->region.
+ space_id)));
+ }
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "from region init, [%s]",
- acpi_ut_get_region_name
- (region_obj->region.space_id)));
+ region_obj->region.flags &=
+ ~(AOPOBJ_SETUP_COMPLETE);
}
- region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
-
/*
* Remove handler reference in the region
*
- * NOTE: this doesn't mean that the region goes away
- * The region is just inaccessible as indicated to
- * the _REG method
+ * NOTE: this doesn't mean that the region goes away, the region
+ * is just inaccessible as indicated to the _REG method
*
- * If the region is on the handler's list
- * this better be the region's handler
+ * If the region is on the handler's list, this must be the
+ * region's handler
*/
region_obj->region.handler = NULL;
acpi_ut_remove_reference(handler_obj);
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 4f948df..923fd2b 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -428,7 +428,7 @@
node = acpi_ns_map_handle_to_node(device);
if (!node) {
status = AE_BAD_PARAMETER;
- goto unlock;
+ goto unlock_and_exit;
}
/* Root Object */
@@ -442,7 +442,7 @@
((handler_type & ACPI_DEVICE_NOTIFY) &&
!acpi_gbl_device_notify.handler)) {
status = AE_NOT_EXIST;
- goto unlock;
+ goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
@@ -474,7 +474,7 @@
if (!acpi_ev_is_notify_object(node)) {
status = AE_TYPE;
- goto unlock;
+ goto unlock_and_exit;
}
/* Check for an existing internal object */
@@ -482,17 +482,21 @@
obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
status = AE_NOT_EXIST;
- goto unlock;
+ goto unlock_and_exit;
}
/* Object exists - make sure there's an existing handler */
if (handler_type & ACPI_SYSTEM_NOTIFY) {
notify_obj = obj_desc->common_notify.system_notify;
- if ((!notify_obj) ||
- (notify_obj->notify.handler != handler)) {
+ if (!notify_obj) {
+ status = AE_NOT_EXIST;
+ goto unlock_and_exit;
+ }
+
+ if (notify_obj->notify.handler != handler) {
status = AE_BAD_PARAMETER;
- goto unlock;
+ goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
@@ -510,10 +514,14 @@
if (handler_type & ACPI_DEVICE_NOTIFY) {
notify_obj = obj_desc->common_notify.device_notify;
- if ((!notify_obj) ||
- (notify_obj->notify.handler != handler)) {
+ if (!notify_obj) {
+ status = AE_NOT_EXIST;
+ goto unlock_and_exit;
+ }
+
+ if (notify_obj->notify.handler != handler) {
status = AE_BAD_PARAMETER;
- goto unlock;
+ goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
@@ -530,9 +538,9 @@
}
}
-unlock:
+ unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-exit:
+ exit:
if (ACPI_FAILURE(status))
ACPI_EXCEPTION((AE_INFO, status, "Removing notify handler"));
return_ACPI_STATUS(status);
@@ -586,7 +594,7 @@
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
- goto unlock;
+ goto unlock_and_exit;
}
/* Make sure that there isn't a handler there already */
@@ -594,7 +602,7 @@
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
status = AE_ALREADY_EXISTS;
- goto unlock;
+ goto unlock_and_exit;
}
/* Allocate and init handler object */
@@ -602,7 +610,7 @@
handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
if (!handler) {
status = AE_NO_MEMORY;
- goto unlock;
+ goto unlock_and_exit;
}
handler->address = address;
@@ -613,7 +621,7 @@
status = acpi_ev_disable_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) {
- goto unlock;
+ goto unlock_and_exit;
}
/* Install the handler */
@@ -628,9 +636,9 @@
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-unlock:
+ unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-exit:
+ exit:
if (ACPI_FAILURE(status))
ACPI_EXCEPTION((AE_INFO, status,
"Installing notify handler failed"));
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index e8b86a0..83b12a9 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -155,7 +155,11 @@
/* Convert and validate the device handle */
node = acpi_ns_map_handle_to_node(device);
- if (!node) {
+ if (!node ||
+ ((node->type != ACPI_TYPE_DEVICE) &&
+ (node->type != ACPI_TYPE_PROCESSOR) &&
+ (node->type != ACPI_TYPE_THERMAL) &&
+ (node != acpi_gbl_root_node))) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
@@ -178,6 +182,13 @@
if (handler_obj->address_space.space_id == space_id) {
+ /* Handler must be the same as the installed handler */
+
+ if (handler_obj->address_space.handler != handler) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
/* Matched space_id, first dereference this in the Regions */
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 83fed07..c8341fa 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -502,7 +502,6 @@
* (Offset contains the table_id)
*/
acpi_ns_delete_namespace_by_owner(table_info->owner_id);
- acpi_ut_release_owner_id(&table_info->owner_id);
/* Delete the table itself */
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index b732e39..544e81a 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -170,6 +170,9 @@
return_ACPI_STATUS(AE_NO_MEMORY);
}
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(result)));
+
/* Save the Result */
return_desc->integer.value = result;
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index d8ac287..3a39c2e 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -267,9 +267,9 @@
&& (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) {
ACPI_ERROR((AE_INFO,
"Thread %X cannot release Mutex [%4.4s] acquired by thread %X",
- walk_state->thread->thread_id,
+ (u32) walk_state->thread->thread_id,
acpi_ut_get_node_name(obj_desc->mutex.node),
- obj_desc->mutex.owner_thread->thread_id));
+ (u32) obj_desc->mutex.owner_thread->thread_id));
return_ACPI_STATUS(AE_AML_NOT_OWNER);
}
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 6b5d1e6..28aef3e 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -60,7 +60,7 @@
*
* DESCRIPTION: Implements a semaphore wait with a check to see if the
* semaphore is available immediately. If it is not, the
- * interpreter is released.
+ * interpreter is released before waiting.
*
******************************************************************************/
acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
@@ -110,9 +110,9 @@
*
* RETURN: Status
*
- * DESCRIPTION: Implements a semaphore wait with a check to see if the
- * semaphore is available immediately. If it is not, the
- * interpreter is released.
+ * DESCRIPTION: Implements a mutex wait with a check to see if the
+ * mutex is available immediately. If it is not, the
+ * interpreter is released before waiting.
*
******************************************************************************/
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index daed246..045c894 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -120,7 +120,7 @@
return count;
}
-static struct file_operations acpi_fan_state_ops = {
+static const struct file_operations acpi_fan_state_ops = {
.open = acpi_fan_state_open_fs,
.read = seq_read,
.write = acpi_fan_write_state,
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
index fd81a0f..32c9d88 100644
--- a/drivers/acpi/hotkey.c
+++ b/drivers/acpi/hotkey.c
@@ -184,7 +184,7 @@
*hotkey_list, int event);
/* event based config */
-static struct file_operations hotkey_config_fops = {
+static const struct file_operations hotkey_config_fops = {
.open = hotkey_open_config,
.read = seq_read,
.write = hotkey_write_config,
@@ -193,7 +193,7 @@
};
/* polling based config */
-static struct file_operations hotkey_poll_config_fops = {
+static const struct file_operations hotkey_poll_config_fops = {
.open = hotkey_poll_open_config,
.read = seq_read,
.write = hotkey_write_config,
@@ -202,7 +202,7 @@
};
/* hotkey driver info */
-static struct file_operations hotkey_info_fops = {
+static const struct file_operations hotkey_info_fops = {
.open = hotkey_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -210,7 +210,7 @@
};
/* action */
-static struct file_operations hotkey_action_fops = {
+static const struct file_operations hotkey_action_fops = {
.open = hotkey_action_open_fs,
.read = seq_read,
.write = hotkey_execute_aml_method,
@@ -219,7 +219,7 @@
};
/* polling results */
-static struct file_operations hotkey_polling_fops = {
+static const struct file_operations hotkey_polling_fops = {
.open = hotkey_polling_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index dc3f073..55b407a 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -386,14 +386,17 @@
* specific ID. Used to delete entire ACPI tables. All
* reference counts are updated.
*
+ * MUTEX: Locks namespace during deletion walk.
+ *
******************************************************************************/
void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
{
struct acpi_namespace_node *child_node;
struct acpi_namespace_node *deletion_node;
- u32 level;
struct acpi_namespace_node *parent_node;
+ u32 level;
+ acpi_status status;
ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id);
@@ -401,6 +404,13 @@
return_VOID;
}
+ /* Lock namespace for possible update */
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_VOID;
+ }
+
deletion_node = NULL;
parent_node = acpi_gbl_root_node;
child_node = NULL;
@@ -469,5 +479,6 @@
}
}
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_VOID;
}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index eedb05c..47dfde9 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -136,16 +136,6 @@
#endif
}
-
-extern int acpi_in_resume;
-void *acpi_os_allocate(acpi_size size)
-{
- if (acpi_in_resume)
- return kmalloc(size, GFP_ATOMIC);
- else
- return kmalloc(size, GFP_KERNEL);
-}
-
acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
{
if (efi_enabled) {
@@ -1115,26 +1105,6 @@
return (AE_OK);
}
-/*******************************************************************************
- *
- * FUNCTION: acpi_os_acquire_object
- *
- * PARAMETERS: Cache - Handle to cache object
- * ReturnObject - Where the object is returned
- *
- * RETURN: Status
- *
- * DESCRIPTION: Return a zero-filled object.
- *
- ******************************************************************************/
-
-void *acpi_os_acquire_object(acpi_cache_t * cache)
-{
- void *object = kmem_cache_zalloc(cache, GFP_KERNEL);
- WARN_ON(!object);
- return object;
-}
-
/******************************************************************************
*
* FUNCTION: acpi_os_validate_interface
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index 182474a..d405387 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -139,12 +139,10 @@
/* The generic op (default) is by far the most common (16 to 1) */
op = acpi_os_acquire_object(acpi_gbl_ps_node_cache);
- memset(op, 0, sizeof(struct acpi_parse_obj_common));
} else {
/* Extended parseop */
op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache);
- memset(op, 0, sizeof(struct acpi_parse_obj_named));
}
/* Initialize the Op */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 8197c0e..7f3e7e7 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -780,11 +780,6 @@
return 0;
}
-/*
- * FIXME: this is a workaround to avoid nasty warning. It will be removed
- * after every device calls pci_disable_device in .resume.
- */
-int acpi_in_resume;
static int irqrouter_resume(struct sys_device *dev)
{
struct list_head *node = NULL;
@@ -794,7 +789,6 @@
/* Make sure SCI is enabled again (Apple firmware bug?) */
acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1, ACPI_MTX_DO_NOT_LOCK);
- acpi_in_resume = 1;
list_for_each(node, &acpi_link.entries) {
link = list_entry(node, struct acpi_pci_link, node);
if (!link) {
@@ -803,7 +797,6 @@
}
acpi_pci_link_resume(link);
}
- acpi_in_resume = 0;
return 0;
}
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 5d3447f..fec225d 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -80,7 +80,7 @@
static struct list_head acpi_power_resource_list;
-static struct file_operations acpi_power_fops = {
+static const struct file_operations acpi_power_fops = {
.open = acpi_power_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 5267432..b13d644 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -102,7 +102,7 @@
#define INSTALL_NOTIFY_HANDLER 1
#define UNINSTALL_NOTIFY_HANDLER 2
-static struct file_operations acpi_processor_info_fops = {
+static const struct file_operations acpi_processor_info_fops = {
.open = acpi_processor_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 8e9c26a..7106606 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -1070,7 +1070,7 @@
PDE(inode)->data);
}
-static struct file_operations acpi_processor_power_fops = {
+static const struct file_operations acpi_processor_power_fops = {
.open = acpi_processor_power_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index cac4fcd..5fcb50c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -663,6 +663,29 @@
Device Enumeration
-------------------------------------------------------------------------- */
+acpi_status
+acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
+{
+ acpi_status status;
+ acpi_handle tmp;
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *obj;
+
+ status = acpi_get_handle(handle, "_EJD", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
+ if (ACPI_SUCCESS(status)) {
+ obj = buffer.pointer;
+ status = acpi_get_handle(NULL, obj->string.pointer, ejd);
+ kfree(buffer.pointer);
+ }
+ return status;
+}
+EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
+
+
static int acpi_bus_get_flags(struct acpi_device *device)
{
acpi_status status = AE_OK;
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 4696a85..3496257 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -434,7 +434,7 @@
PDE(inode)->data);
}
-static struct file_operations acpi_system_wakeup_device_fops = {
+static const struct file_operations acpi_system_wakeup_device_fops = {
.open = acpi_system_wakeup_device_open_fs,
.read = seq_read,
.write = acpi_system_write_wakeup_device,
@@ -443,7 +443,7 @@
};
#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
-static struct file_operations acpi_system_sleep_fops = {
+static const struct file_operations acpi_system_sleep_fops = {
.open = acpi_system_sleep_open_fs,
.read = seq_read,
.write = acpi_system_write_sleep,
@@ -452,7 +452,7 @@
};
#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
-static struct file_operations acpi_system_alarm_fops = {
+static const struct file_operations acpi_system_alarm_fops = {
.open = acpi_system_alarm_open_fs,
.read = seq_read,
.write = acpi_system_write_alarm,
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index c3bb7faa..d86dcb3 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -57,7 +57,7 @@
return single_open(file, acpi_system_read_info, PDE(inode)->data);
}
-static struct file_operations acpi_system_info_ops = {
+static const struct file_operations acpi_system_info_ops = {
.open = acpi_system_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -67,7 +67,7 @@
static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
loff_t *);
-static struct file_operations acpi_system_dsdt_ops = {
+static const struct file_operations acpi_system_dsdt_ops = {
.read = acpi_system_read_dsdt,
};
@@ -94,7 +94,7 @@
static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
loff_t *);
-static struct file_operations acpi_system_fadt_ops = {
+static const struct file_operations acpi_system_fadt_ops = {
.read = acpi_system_read_fadt,
};
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 99eacce..7856db7 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -320,6 +320,16 @@
ACPI_FUNCTION_TRACE(tb_get_this_table);
+ /* Validate minimum length */
+
+ if (header->length < sizeof(struct acpi_table_header)) {
+ ACPI_ERROR((AE_INFO,
+ "Table length (%X) is smaller than minimum (%X)",
+ header->length, sizeof(struct acpi_table_header)));
+
+ return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
+ }
+
/*
* Flags contains the current processor mode (Virtual or Physical
* addressing) The pointer_type is either Logical or Physical
@@ -356,7 +366,7 @@
*/
status = acpi_os_map_memory(address->pointer.physical,
(acpi_size) header->length,
- (void *)&full_table);
+ ACPI_CAST_PTR(void, &full_table));
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO,
"Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X",
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 7ca2df7..1668a23 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -256,7 +256,7 @@
status = acpi_ut_allocate_owner_id(&table_desc->owner_id);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto error_exit1;
}
/* Install the table into the global data structure */
@@ -274,8 +274,8 @@
* at this location, so return an error.
*/
if (list_head->next) {
- ACPI_FREE(table_desc);
- return_ACPI_STATUS(AE_ALREADY_EXISTS);
+ status = AE_ALREADY_EXISTS;
+ goto error_exit2;
}
table_desc->next = list_head->next;
@@ -335,6 +335,17 @@
table_info->owner_id = table_desc->owner_id;
table_info->installed_desc = table_desc;
return_ACPI_STATUS(AE_OK);
+
+ /* Error exit with cleanup */
+
+ error_exit2:
+
+ acpi_ut_release_owner_id(&table_desc->owner_id);
+
+ error_exit1:
+
+ ACPI_FREE(table_desc);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
@@ -525,6 +536,10 @@
acpi_tb_delete_single_table(table_desc);
+ /* Free the owner ID associated with this table */
+
+ acpi_ut_release_owner_id(&table_desc->owner_id);
+
/* Free the table descriptor */
next_desc = table_desc->next;
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index abcb08c..0ad3dbb 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -183,6 +183,17 @@
ACPI_FUNCTION_ENTRY();
+ /* Validate minimum length */
+
+ if (table_ptr->length < sizeof(struct acpi_table_header)) {
+ ACPI_ERROR((AE_INFO,
+ "RSDT/XSDT length (%X) is smaller than minimum (%X)",
+ table_ptr->length,
+ sizeof(struct acpi_table_header)));
+
+ return (AE_INVALID_TABLE_LENGTH);
+ }
+
/* Search for appropriate signature, RSDT or XSDT */
if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
@@ -210,7 +221,7 @@
ACPI_ERROR((AE_INFO, "Looking for XSDT"));
}
- ACPI_DUMP_BUFFER((char *)table_ptr, 48);
+ ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48);
return (AE_BAD_SIGNATURE);
}
@@ -258,7 +269,7 @@
status = acpi_tb_validate_rsdt(table_info.pointer);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto error_cleanup;
}
/* Get the number of tables defined in the RSDT or XSDT */
@@ -270,14 +281,14 @@
status = acpi_tb_convert_to_xsdt(&table_info);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto error_cleanup;
}
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto error_cleanup;
}
acpi_gbl_XSDT =
@@ -285,4 +296,12 @@
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
return_ACPI_STATUS(status);
+
+ error_cleanup:
+
+ /* Free table allocated by acpi_tb_get_table */
+
+ acpi_tb_delete_single_table(&table_info);
+
+ return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 4e91f29..7767987 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -134,8 +134,8 @@
* RETURN: Status
*
* DESCRIPTION: This function is called to load a table from the caller's
- * buffer. The buffer must contain an entire ACPI Table including
- * a valid header. The header fields will be verified, and if it
+ * buffer. The buffer must contain an entire ACPI Table including
+ * a valid header. The header fields will be verified, and if it
* is determined that the table is invalid, the call will fail.
*
******************************************************************************/
@@ -245,15 +245,18 @@
/* Find all tables of the requested type */
table_desc = acpi_gbl_table_lists[table_type].next;
+ if (!table_desc) {
+ return_ACPI_STATUS(AE_NOT_EXIST);
+ }
+
while (table_desc) {
/*
- * Delete all namespace entries owned by this table. Note that these
- * entries can appear anywhere in the namespace by virtue of the AML
- * "Scope" operator. Thus, we need to track ownership by an ID, not
+ * Delete all namespace objects owned by this table. Note that these
+ * objects can appear anywhere in the namespace by virtue of the AML
+ * "Scope" operator. Thus, we need to track ownership by an ID, not
* simply a position within the hierarchy
*/
acpi_ns_delete_namespace_by_owner(table_desc->owner_id);
- acpi_ut_release_owner_id(&table_desc->owner_id);
table_desc = table_desc->next;
}
@@ -275,12 +278,12 @@
* see acpi_gbl_acpi_table_flag
* out_table_header - pointer to the struct acpi_table_header if successful
*
- * DESCRIPTION: This function is called to get an ACPI table header. The caller
+ * DESCRIPTION: This function is called to get an ACPI table header. The caller
* supplies an pointer to a data area sufficient to contain an ACPI
* struct acpi_table_header structure.
*
* The header contains a length field that can be used to determine
- * the size of the buffer needed to contain the entire table. This
+ * the size of the buffer needed to contain the entire table. This
* function is not valid for the RSD PTR table since it does not
* have a standard header and is fixed length.
*
@@ -322,7 +325,8 @@
/* Copy the header to the caller's buffer */
- ACPI_MEMCPY((void *)out_table_header, (void *)tbl_ptr,
+ ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header),
+ ACPI_CAST_PTR(void, tbl_ptr),
sizeof(struct acpi_table_header));
return_ACPI_STATUS(status);
@@ -344,10 +348,10 @@
*
* RETURN: Status
*
- * DESCRIPTION: This function is called to get an ACPI table. The caller
+ * DESCRIPTION: This function is called to get an ACPI table. The caller
* supplies an out_buffer large enough to contain the entire ACPI
- * table. The caller should call the acpi_get_table_header function
- * first to determine the buffer size needed. Upon completion
+ * table. The caller should call the acpi_get_table_header function
+ * first to determine the buffer size needed. Upon completion
* the out_buffer->Length field will indicate the number of bytes
* copied into the out_buffer->buf_ptr buffer. This table will be
* a complete table including the header.
@@ -417,7 +421,9 @@
/* Copy the table to the buffer */
- ACPI_MEMCPY((void *)ret_buffer->pointer, (void *)tbl_ptr, table_length);
+ ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer),
+ ACPI_CAST_PTR(void, tbl_ptr), table_length);
+
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 503c0b9..5753d06 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -176,21 +176,21 @@
struct timer_list timer;
};
-static struct file_operations acpi_thermal_state_fops = {
+static const struct file_operations acpi_thermal_state_fops = {
.open = acpi_thermal_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations acpi_thermal_temp_fops = {
+static const struct file_operations acpi_thermal_temp_fops = {
.open = acpi_thermal_temp_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations acpi_thermal_trip_fops = {
+static const struct file_operations acpi_thermal_trip_fops = {
.open = acpi_thermal_trip_open_fs,
.read = seq_read,
.write = acpi_thermal_write_trip_points,
@@ -198,7 +198,7 @@
.release = single_release,
};
-static struct file_operations acpi_thermal_cooling_fops = {
+static const struct file_operations acpi_thermal_cooling_fops = {
.open = acpi_thermal_cooling_open_fs,
.read = seq_read,
.write = acpi_thermal_write_cooling_mode,
@@ -206,7 +206,7 @@
.release = single_release,
};
-static struct file_operations acpi_thermal_polling_fops = {
+static const struct file_operations acpi_thermal_polling_fops = {
.open = acpi_thermal_polling_open_fs,
.read = seq_read,
.write = acpi_thermal_write_polling,
@@ -1359,13 +1359,28 @@
static int acpi_thermal_resume(struct acpi_device *device, int state)
{
struct acpi_thermal *tz = NULL;
+ int i;
if (!device || !acpi_driver_data(device))
return -EINVAL;
tz = (struct acpi_thermal *)acpi_driver_data(device);
- acpi_thermal_check(tz);
+ acpi_thermal_get_temperature(tz);
+
+ for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
+ if (tz->trips.active[i].flags.valid) {
+ tz->temperature = tz->trips.active[i].temperature;
+ tz->trips.active[i].flags.enabled = 0;
+
+ acpi_thermal_active(tz);
+
+ tz->state.active |= tz->trips.active[i].flags.enabled;
+ tz->state.active_index = i;
+ }
+ }
+
+ acpi_thermal_check(tz);
return AE_OK;
}
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 5cff17d..f6cbc0b 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -285,6 +285,7 @@
return (status);
}
+#ifdef NOT_USED_BY_LINUX
/*******************************************************************************
*
* FUNCTION: acpi_ut_allocate
@@ -360,3 +361,4 @@
return (allocation);
}
+#endif
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 5ec1cfc..bb1eaf9 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -47,7 +47,7 @@
ACPI_MODULE_NAME("utdebug")
#ifdef ACPI_DEBUG_OUTPUT
-static u32 acpi_gbl_prev_thread_id = 0xFFFFFFFF;
+static acpi_thread_id acpi_gbl_prev_thread_id;
static char *acpi_gbl_fn_entry_str = "----Entry";
static char *acpi_gbl_fn_exit_str = "----Exit-";
@@ -181,7 +181,7 @@
if (ACPI_LV_THREADS & acpi_dbg_level) {
acpi_os_printf
("\n**** Context Switch from TID %X to TID %X ****\n\n",
- acpi_gbl_prev_thread_id, thread_id);
+ (u32) acpi_gbl_prev_thread_id, (u32) thread_id);
}
acpi_gbl_prev_thread_id = thread_id;
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 38ebe1c..9d3f114 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -447,11 +447,16 @@
*/
switch (ACPI_GET_OBJECT_TYPE(object)) {
case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_THERMAL:
- acpi_ut_update_ref_count(object->device.system_notify,
- action);
- acpi_ut_update_ref_count(object->device.device_notify,
- action);
+ /* Update the notify objects for these types (if present) */
+
+ acpi_ut_update_ref_count(object->common_notify.
+ system_notify, action);
+ acpi_ut_update_ref_count(object->common_notify.
+ device_notify, action);
break;
case ACPI_TYPE_PACKAGE:
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 3326831..6d8a821 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -65,7 +65,7 @@
u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
{
- /* Ignore tables that contain AML */
+ /* These are the only tables that contain executable AML */
if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) ||
ACPI_COMPARE_NAME(table->signature, PSDT_SIG) ||
@@ -419,10 +419,15 @@
{
if (revision <= 1) {
+
+ /* 32-bit case */
+
acpi_gbl_integer_bit_width = 32;
acpi_gbl_integer_nybble_width = 8;
acpi_gbl_integer_byte_width = 4;
} else {
+ /* 64-bit case (ACPI 2.0+) */
+
acpi_gbl_integer_bit_width = 64;
acpi_gbl_integer_nybble_width = 16;
acpi_gbl_integer_byte_width = 8;
@@ -502,6 +507,7 @@
* FUNCTION: acpi_ut_valid_acpi_char
*
* PARAMETERS: Char - The character to be examined
+ * Position - Byte position (0-3)
*
* RETURN: TRUE if the character is valid, FALSE otherwise
*
@@ -609,7 +615,9 @@
*
* RETURN: Status and Converted value
*
- * DESCRIPTION: Convert a string into an unsigned value.
+ * DESCRIPTION: Convert a string into an unsigned value. Performs either a
+ * 32-bit or 64-bit conversion, depending on the current mode
+ * of the interpreter.
* NOTE: Does not support Octal strings, not needed.
*
******************************************************************************/
@@ -627,7 +635,7 @@
u8 sign_of0x = 0;
u8 term = 0;
- ACPI_FUNCTION_TRACE(ut_stroul64);
+ ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
switch (base) {
case ACPI_ANY_BASE:
@@ -675,11 +683,13 @@
}
}
+ /*
+ * Perform a 32-bit or 64-bit conversion, depending upon the current
+ * execution mode of the interpreter
+ */
dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
- /* At least one character in the string here */
-
- /* Main loop: convert the string to a 64-bit integer */
+ /* Main loop: convert the string to a 32- or 64-bit integer */
while (*string) {
if (ACPI_IS_DIGIT(*string)) {
@@ -754,6 +764,9 @@
all_done:
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(return_value)));
+
*ret_integer = return_value;
return_ACPI_STATUS(AE_OK);
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index dfc8f30..c39062a 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -244,14 +244,14 @@
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
"Thread %X attempting to acquire Mutex [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name(mutex_id)));
+ (u32) this_thread_id, acpi_ut_get_mutex_name(mutex_id)));
status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
ACPI_WAIT_FOREVER);
if (ACPI_SUCCESS(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
"Thread %X acquired Mutex [%s]\n",
- this_thread_id,
+ (u32) this_thread_id,
acpi_ut_get_mutex_name(mutex_id)));
acpi_gbl_mutex_info[mutex_id].use_count++;
@@ -259,7 +259,7 @@
} else {
ACPI_EXCEPTION((AE_INFO, status,
"Thread %X could not acquire Mutex [%X]",
- this_thread_id, mutex_id));
+ (u32) this_thread_id, mutex_id));
}
return (status);
@@ -285,7 +285,7 @@
this_thread_id = acpi_os_get_thread_id();
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
- "Thread %X releasing Mutex [%s]\n", this_thread_id,
+ "Thread %X releasing Mutex [%s]\n", (u32) this_thread_id,
acpi_ut_get_mutex_name(mutex_id)));
if (mutex_id > ACPI_MAX_MUTEX) {
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c
index 0f5c5bb..eaa13d0 100644
--- a/drivers/acpi/utilities/utstate.c
+++ b/drivers/acpi/utilities/utstate.c
@@ -199,6 +199,13 @@
state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD;
state->thread.thread_id = acpi_os_get_thread_id();
+ /* Check for invalid thread ID - zero is very bad, it will break things */
+
+ if (!state->thread.thread_id) {
+ ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
+ state->thread.thread_id = (acpi_thread_id) 1;
+ }
+
return_PTR((struct acpi_thread_state *)state);
}
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 80502dc..0b4e224 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -20,7 +20,7 @@
config FW_LOADER
tristate "Userspace firmware loading support"
- select HOTPLUG
+ depends on HOTPLUG
---help---
This option is provided for the case where no in-kernel-tree modules
require userspace firmware loading support, but a module built outside
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 5327f55..1bc1cf9 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -162,7 +162,7 @@
{
int n, i;
- n = MINOR(inode->i_rdev);
+ n = iminor(inode);
filp->private_data = (void *) (unsigned long) n;
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 6f67141..13ba729 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -234,6 +234,7 @@
data->fw_data = kmalloc(firmware->size, GFP_KERNEL);
if (!data->fw_data) {
BT_ERR("Can't allocate memory for firmware image");
+ release_firmware(firmware);
usb_free_urb(data->urb);
kfree(data->buffer);
kfree(data);
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index ca27ee8..d239cf8 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1837,7 +1837,7 @@
init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ);
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[7] = s->type;
- cgc.cmd[9] = cgc.buflen = 0xff;
+ cgc.cmd[9] = cgc.buflen & 0xff;
if ((ret = cdo->generic_packet(cdi, &cgc)))
return ret;
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index 56612a2..41db806 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -1299,7 +1299,7 @@
hp->inbuf_end = hp->inbuf;
hp->state = HVSI_CLOSED;
hp->vtermno = *vtermno;
- hp->virq = irq_create_mapping(NULL, irq[0], 0);
+ hp->virq = irq_create_mapping(NULL, irq[0]);
if (hp->virq == NO_IRQ) {
printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
__FUNCTION__, irq[0]);
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 518ece7..7907ae8 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -3186,3 +3186,10 @@
MODULE_LICENSE("GPL");
+
+static struct pci_device_id ip2main_pci_tbl[] __devinitdata = {
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index e97c32c..917b204 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -95,7 +95,7 @@
return 1;
}
-static inline int valid_mmap_phys_addr_range(unsigned long addr, size_t size)
+static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
{
return 1;
}
@@ -242,7 +242,7 @@
{
size_t size = vma->vm_end - vma->vm_start;
- if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, size))
+ if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
return -EINVAL;
vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index 4005ee0..11bd78c 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -3,18 +3,18 @@
National Semiconductor PC8736x GPIO driver. Allows a user space
process to play with the GPIO pins.
- Copyright (c) 2005 Jim Cromie <jim.cromie@gmail.com>
+ Copyright (c) 2005,2006 Jim Cromie <jim.cromie@gmail.com>
adapted from linux/drivers/char/scx200_gpio.c
Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>,
*/
-#include <linux/config.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/cdev.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/mutex.h>
@@ -25,7 +25,7 @@
#define DEVNAME "pc8736x_gpio"
MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
-MODULE_DESCRIPTION("NatSemi PC-8736x GPIO Pin Driver");
+MODULE_DESCRIPTION("NatSemi/Winbond PC-8736x GPIO Pin Driver");
MODULE_LICENSE("GPL");
static int major; /* default to dynamic major */
@@ -38,14 +38,14 @@
#define SIO_BASE1 0x2E /* 1st command-reg to check */
#define SIO_BASE2 0x4E /* alt command-reg to check */
-#define SIO_BASE_OFFSET 0x20
#define SIO_SID 0x20 /* SuperI/O ID Register */
#define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */
#define SIO_CF1 0x21 /* chip config, bit0 is chip enable */
-#define PC8736X_GPIO_SIZE 16
+#define PC8736X_GPIO_RANGE 16 /* ioaddr range */
+#define PC8736X_GPIO_CT 32 /* minors matching 4 8 bit ports */
#define SIO_UNIT_SEL 0x7 /* unit select reg */
#define SIO_UNIT_ACT 0x30 /* unit enable */
@@ -231,7 +231,7 @@
dev_dbg(&pdev->dev, "open %d\n", m);
- if (m > 63)
+ if (m >= PC8736X_GPIO_CT)
return -EINVAL;
return nonseekable_open(inode, file);
}
@@ -255,9 +255,12 @@
}
+static struct cdev pc8736x_gpio_cdev;
+
static int __init pc8736x_gpio_init(void)
{
- int rc = 0;
+ int rc;
+ dev_t devid;
pdev = platform_device_alloc(DEVNAME, 0);
if (!pdev)
@@ -297,7 +300,7 @@
pc8736x_gpio_base = (superio_inb(SIO_BASE_HADDR) << 8
| superio_inb(SIO_BASE_LADDR));
- if (!request_region(pc8736x_gpio_base, 16, DEVNAME)) {
+ if (!request_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE, DEVNAME)) {
rc = -ENODEV;
dev_err(&pdev->dev, "GPIO ioport %x busy\n",
pc8736x_gpio_base);
@@ -305,10 +308,17 @@
}
dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base);
- rc = register_chrdev(major, DEVNAME, &pc8736x_gpio_fops);
+ if (major) {
+ devid = MKDEV(major, 0);
+ rc = register_chrdev_region(devid, PC8736X_GPIO_CT, DEVNAME);
+ } else {
+ rc = alloc_chrdev_region(&devid, 0, PC8736X_GPIO_CT, DEVNAME);
+ major = MAJOR(devid);
+ }
+
if (rc < 0) {
dev_err(&pdev->dev, "register-chrdev failed: %d\n", rc);
- goto undo_platform_dev_add;
+ goto undo_request_region;
}
if (!major) {
major = rc;
@@ -316,8 +326,15 @@
}
pc8736x_init_shadow();
+
+ /* ignore minor errs, and succeed */
+ cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fops);
+ cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT);
+
return 0;
+undo_request_region:
+ release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE);
undo_platform_dev_add:
platform_device_del(pdev);
undo_platform_dev_alloc:
@@ -328,11 +345,14 @@
static void __exit pc8736x_gpio_cleanup(void)
{
- dev_dbg(&pdev->dev, " cleanup\n");
+ dev_dbg(&pdev->dev, "cleanup\n");
- release_region(pc8736x_gpio_base, 16);
+ cdev_del(&pc8736x_gpio_cdev);
+ unregister_chrdev_region(MKDEV(major,0), PC8736X_GPIO_CT);
+ release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE);
- unregister_chrdev(major, DEVNAME);
+ platform_device_del(pdev);
+ platform_device_put(pdev);
}
EXPORT_SYMBOL(pc8736x_access);
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index cc7bd1a..6ccc364 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -46,13 +46,12 @@
* 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init
* 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
* CONFIG_HPET_EMULATE_RTC
+ * 1.12a Maciej W. Rozycki: Handle memory-mapped chips properly.
* 1.12ac Alan Cox: Allow read access to the day of week register
*/
#define RTC_VERSION "1.12ac"
-#define RTC_IO_EXTENT 0x8
-
/*
* Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
* interrupts disabled. Due to the index-port/data-port (0x70/0x71)
@@ -337,7 +336,15 @@
if (rtc_has_irq == 0)
return -EIO;
- if (count < sizeof(unsigned))
+ /*
+ * Historically this function used to assume that sizeof(unsigned long)
+ * is the same in userspace and kernelspace. This lead to problems
+ * for configurations with multiple ABIs such a the MIPS o32 and 64
+ * ABIs supported on the same kernel. So now we support read of both
+ * 4 and 8 bytes and assume that's the sizeof(unsigned long) in the
+ * userspace ABI.
+ */
+ if (count != sizeof(unsigned int) && count != sizeof(unsigned long))
return -EINVAL;
add_wait_queue(&rtc_wait, &wait);
@@ -368,10 +375,12 @@
schedule();
} while (1);
- if (count < sizeof(unsigned long))
- retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int);
+ if (count == sizeof(unsigned int))
+ retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int);
else
retval = put_user(data, (unsigned long __user *)buf) ?: sizeof(long);
+ if (!retval)
+ retval = count;
out:
current->state = TASK_RUNNING;
remove_wait_queue(&rtc_wait, &wait);
@@ -923,6 +932,9 @@
struct sparc_isa_device *isa_dev;
#endif
#endif
+#ifndef __sparc__
+ void *r;
+#endif
#ifdef __sparc__
for_each_ebus(ebus) {
@@ -964,8 +976,13 @@
}
no_irq:
#else
- if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc")) {
- printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0));
+ if (RTC_IOMAPPED)
+ r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
+ else
+ r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
+ if (!r) {
+ printk(KERN_ERR "rtc: I/O resource %lx is not free.\n",
+ (long)(RTC_PORT(0)));
return -EIO;
}
@@ -979,7 +996,10 @@
if(request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, "rtc", NULL)) {
/* Yeah right, seeing as irq 8 doesn't even hit the bus. */
printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
- release_region(RTC_PORT(0), RTC_IO_EXTENT);
+ if (RTC_IOMAPPED)
+ release_region(RTC_PORT(0), RTC_IO_EXTENT);
+ else
+ release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
return -EIO;
}
hpet_rtc_timer_init();
@@ -1079,7 +1099,10 @@
if (rtc_has_irq)
free_irq (rtc_irq, &rtc_port);
#else
- release_region (RTC_PORT (0), RTC_IO_EXTENT);
+ if (RTC_IOMAPPED)
+ release_region(RTC_PORT(0), RTC_IO_EXTENT);
+ else
+ release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
#ifdef RTC_IRQ
if (rtc_has_irq)
free_irq (RTC_IRQ, NULL);
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index 8b2210b..d12d4f6 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -220,20 +220,7 @@
" Sending SIGPWR to init...\n");
/* give a SIGPWR signal to init proc */
-
- /* first find init's task */
- read_lock(&tasklist_lock);
- for_each_process(p) {
- if (p->pid == 1)
- break;
- }
- if (p) {
- force_sig(SIGPWR, p);
- } else {
- printk(KERN_ERR "Failed to signal init!\n");
- snsc_shutting_down = 0; /* so can try again (?) */
- }
- read_unlock(&tasklist_lock);
+ kill_proc(1, SIGPWR, 0);
} else {
/* print to system log */
printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index cb28592..a1d303f9 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2584,6 +2584,12 @@
func_exit();
}
+static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
+ { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
+
module_init(specialix_init_module);
module_exit(specialix_exit_module);
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 3a7cfe8..4bde30b 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -1,6 +1,6 @@
/*
* edac_mc kernel module
- * (C) 2005 Linux Networx (http://lnxi.com)
+ * (C) 2005, 2006 Linux Networx (http://lnxi.com)
* This file may be distributed under the terms of the
* GNU General Public License.
*
@@ -33,13 +33,8 @@
#include <asm/edac.h>
#include "edac_mc.h"
-#define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__
+#define EDAC_MC_VERSION "Ver: 2.0.1 " __DATE__
-/* For now, disable the EDAC sysfs code. The sysfs interface that EDAC
- * presents to user space needs more thought, and is likely to change
- * substantially.
- */
-#define DISABLE_EDAC_SYSFS
#ifdef CONFIG_EDAC_DEBUG
/* Values of 0 to 4 will generate output */
@@ -64,31 +59,12 @@
static int panic_on_pci_parity; /* default no panic on PCI Parity */
static atomic_t pci_parity_count = ATOMIC_INIT(0);
-/* Structure of the whitelist and blacklist arrays */
-struct edac_pci_device_list {
- unsigned int vendor; /* Vendor ID */
- unsigned int device; /* Deviice ID */
-};
-
-#define MAX_LISTED_PCI_DEVICES 32
-
-/* List of PCI devices (vendor-id:device-id) that should be skipped */
-static struct edac_pci_device_list pci_blacklist[MAX_LISTED_PCI_DEVICES];
-static int pci_blacklist_count;
-
-/* List of PCI devices (vendor-id:device-id) that should be scanned */
-static struct edac_pci_device_list pci_whitelist[MAX_LISTED_PCI_DEVICES];
-static int pci_whitelist_count ;
-
-#ifndef DISABLE_EDAC_SYSFS
static struct kobject edac_pci_kobj; /* /sys/devices/system/edac/pci */
static struct completion edac_pci_kobj_complete;
-#endif /* DISABLE_EDAC_SYSFS */
#endif /* CONFIG_PCI */
/* START sysfs data and methods */
-#ifndef DISABLE_EDAC_SYSFS
static const char *mem_types[] = {
[MEM_EMPTY] = "Empty",
@@ -147,18 +123,10 @@
* /sys/devices/system/edac/mc;
* data structures and methods
*/
-#if 0
-static ssize_t memctrl_string_show(void *ptr, char *buffer)
-{
- char *value = (char*) ptr;
- return sprintf(buffer, "%s\n", value);
-}
-#endif
-
static ssize_t memctrl_int_show(void *ptr, char *buffer)
{
int *value = (int*) ptr;
- return sprintf(buffer, "%d\n", *value);
+ return sprintf(buffer, "%u\n", *value);
}
static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count)
@@ -224,11 +192,6 @@
.store = _store, \
};
-/* cwrow<id> attribute f*/
-#if 0
-MEMCTRL_STRING_ATTR(mc_version,EDAC_MC_VERSION,S_IRUGO,memctrl_string_show,NULL);
-#endif
-
/* csrow<id> control files */
MEMCTRL_ATTR(panic_on_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
MEMCTRL_ATTR(log_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
@@ -257,8 +220,6 @@
.default_attrs = (struct attribute **) memctrl_attr,
};
-#endif /* DISABLE_EDAC_SYSFS */
-
/* Initialize the main sysfs entries for edac:
* /sys/devices/system/edac
*
@@ -268,11 +229,6 @@
* !0 FAILURE
*/
static int edac_sysfs_memctrl_setup(void)
-#ifdef DISABLE_EDAC_SYSFS
-{
- return 0;
-}
-#else
{
int err=0;
@@ -304,7 +260,6 @@
return err;
}
-#endif /* DISABLE_EDAC_SYSFS */
/*
* MC teardown:
@@ -312,7 +267,6 @@
*/
static void edac_sysfs_memctrl_teardown(void)
{
-#ifndef DISABLE_EDAC_SYSFS
debugf0("MC: " __FILE__ ": %s()\n", __func__);
/* Unregister the MC's kobject and wait for reference count to reach
@@ -324,144 +278,9 @@
/* Unregister the 'edac' object */
sysdev_class_unregister(&edac_class);
-#endif /* DISABLE_EDAC_SYSFS */
}
#ifdef CONFIG_PCI
-
-#ifndef DISABLE_EDAC_SYSFS
-
-/*
- * /sys/devices/system/edac/pci;
- * data structures and methods
- */
-
-struct list_control {
- struct edac_pci_device_list *list;
- int *count;
-};
-
-#if 0
-/* Output the list as: vendor_id:device:id<,vendor_id:device_id> */
-static ssize_t edac_pci_list_string_show(void *ptr, char *buffer)
-{
- struct list_control *listctl;
- struct edac_pci_device_list *list;
- char *p = buffer;
- int len=0;
- int i;
-
- listctl = ptr;
- list = listctl->list;
-
- for (i = 0; i < *(listctl->count); i++, list++ ) {
- if (len > 0)
- len += snprintf(p + len, (PAGE_SIZE-len), ",");
-
- len += snprintf(p + len,
- (PAGE_SIZE-len),
- "%x:%x",
- list->vendor,list->device);
- }
-
- len += snprintf(p + len,(PAGE_SIZE-len), "\n");
- return (ssize_t) len;
-}
-
-/**
- *
- * Scan string from **s to **e looking for one 'vendor:device' tuple
- * where each field is a hex value
- *
- * return 0 if an entry is NOT found
- * return 1 if an entry is found
- * fill in *vendor_id and *device_id with values found
- *
- * In both cases, make sure *s has been moved forward toward *e
- */
-static int parse_one_device(const char **s,const char **e,
- unsigned int *vendor_id, unsigned int *device_id)
-{
- const char *runner, *p;
-
- /* if null byte, we are done */
- if (!**s) {
- (*s)++; /* keep *s moving */
- return 0;
- }
-
- /* skip over newlines & whitespace */
- if ((**s == '\n') || isspace(**s)) {
- (*s)++;
- return 0;
- }
-
- if (!isxdigit(**s)) {
- (*s)++;
- return 0;
- }
-
- /* parse vendor_id */
- runner = *s;
-
- while (runner < *e) {
- /* scan for vendor:device delimiter */
- if (*runner == ':') {
- *vendor_id = simple_strtol((char*) *s, (char**) &p, 16);
- runner = p + 1;
- break;
- }
-
- runner++;
- }
-
- if (!isxdigit(*runner)) {
- *s = ++runner;
- return 0;
- }
-
- /* parse device_id */
- if (runner < *e) {
- *device_id = simple_strtol((char*)runner, (char**)&p, 16);
- runner = p;
- }
-
- *s = runner;
- return 1;
-}
-
-static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer,
- size_t count)
-{
- struct list_control *listctl;
- struct edac_pci_device_list *list;
- unsigned int vendor_id, device_id;
- const char *s, *e;
- int *index;
-
- s = (char*)buffer;
- e = s + count;
- listctl = ptr;
- list = listctl->list;
- index = listctl->count;
- *index = 0;
-
- while (*index < MAX_LISTED_PCI_DEVICES) {
- if (parse_one_device(&s,&e,&vendor_id,&device_id)) {
- list[ *index ].vendor = vendor_id;
- list[ *index ].device = device_id;
- (*index)++;
- }
-
- /* check for all data consume */
- if (s >= e)
- break;
- }
-
- return count;
-}
-
-#endif
static ssize_t edac_pci_int_show(void *ptr, char *buffer)
{
int *value = ptr;
@@ -529,31 +348,6 @@
.store = _store, \
};
-#if 0
-static struct list_control pci_whitelist_control = {
- .list = pci_whitelist,
- .count = &pci_whitelist_count
-};
-
-static struct list_control pci_blacklist_control = {
- .list = pci_blacklist,
- .count = &pci_blacklist_count
-};
-
-/* whitelist attribute */
-EDAC_PCI_STRING_ATTR(pci_parity_whitelist,
- &pci_whitelist_control,
- S_IRUGO|S_IWUSR,
- edac_pci_list_string_show,
- edac_pci_list_string_store);
-
-EDAC_PCI_STRING_ATTR(pci_parity_blacklist,
- &pci_blacklist_control,
- S_IRUGO|S_IWUSR,
- edac_pci_list_string_show,
- edac_pci_list_string_store);
-#endif
-
/* PCI Parity control files */
EDAC_PCI_ATTR(check_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show,
edac_pci_int_store);
@@ -582,18 +376,11 @@
.default_attrs = (struct attribute **) edac_pci_attr,
};
-#endif /* DISABLE_EDAC_SYSFS */
-
/**
* edac_sysfs_pci_setup()
*
*/
static int edac_sysfs_pci_setup(void)
-#ifdef DISABLE_EDAC_SYSFS
-{
- return 0;
-}
-#else
{
int err;
@@ -617,16 +404,13 @@
return err;
}
-#endif /* DISABLE_EDAC_SYSFS */
static void edac_sysfs_pci_teardown(void)
{
-#ifndef DISABLE_EDAC_SYSFS
debugf0("%s()\n", __func__);
init_completion(&edac_pci_kobj_complete);
kobject_unregister(&edac_pci_kobj);
wait_for_completion(&edac_pci_kobj_complete);
-#endif
}
@@ -756,36 +540,6 @@
}
/*
- * check_dev_on_list: Scan for a PCI device on a white/black list
- * @list: an EDAC &edac_pci_device_list white/black list pointer
- * @free_index: index of next free entry on the list
- * @pci_dev: PCI Device pointer
- *
- * see if list contains the device.
- *
- * Returns: 0 not found
- * 1 found on list
- */
-static int check_dev_on_list(struct edac_pci_device_list *list,
- int free_index, struct pci_dev *dev)
-{
- int i;
- int rc = 0; /* Assume not found */
- unsigned short vendor=dev->vendor;
- unsigned short device=dev->device;
-
- /* Scan the list, looking for a vendor/device match */
- for (i = 0; i < free_index; i++, list++ ) {
- if ((list->vendor == vendor ) && (list->device == device )) {
- rc = 1;
- break;
- }
- }
-
- return rc;
-}
-
-/*
* pci_dev parity list iterator
* Scan the PCI device list for one iteration, looking for SERRORs
* Master Parity ERRORS or Parity ERRORs on primary or secondary devices
@@ -799,22 +553,7 @@
* bumped until we are done with it
*/
while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- /* if whitelist exists then it has priority, so only scan
- * those devices on the whitelist
- */
- if (pci_whitelist_count > 0 ) {
- if (check_dev_on_list(pci_whitelist,
- pci_whitelist_count, dev))
- fn(dev);
- } else {
- /*
- * if no whitelist, then check if this devices is
- * blacklisted
- */
- if (!check_dev_on_list(pci_blacklist,
- pci_blacklist_count, dev))
- fn(dev);
- }
+ fn(dev);
}
}
@@ -855,154 +594,101 @@
#else /* CONFIG_PCI */
-static inline void do_pci_parity_check(void)
-{
- /* no-op */
-}
+/* pre-process these away */
+#define do_pci_parity_check()
+#define clear_pci_parity_errors()
+#define edac_sysfs_pci_teardown()
+#define edac_sysfs_pci_setup() (0)
-static inline void clear_pci_parity_errors(void)
-{
- /* no-op */
-}
-
-static void edac_sysfs_pci_teardown(void)
-{
-}
-
-static int edac_sysfs_pci_setup(void)
-{
- return 0;
-}
#endif /* CONFIG_PCI */
-#ifndef DISABLE_EDAC_SYSFS
+/* EDAC sysfs CSROW data structures and methods
+ */
-/* EDAC sysfs CSROW data structures and methods */
-
-/* Set of more detailed csrow<id> attribute show/store functions */
-static ssize_t csrow_ch0_dimm_label_show(struct csrow_info *csrow, char *data)
-{
- ssize_t size = 0;
-
- if (csrow->nr_channels > 0) {
- size = snprintf(data, EDAC_MC_LABEL_LEN,"%s\n",
- csrow->channels[0].label);
- }
-
- return size;
-}
-
-static ssize_t csrow_ch1_dimm_label_show(struct csrow_info *csrow, char *data)
-{
- ssize_t size = 0;
-
- if (csrow->nr_channels > 0) {
- size = snprintf(data, EDAC_MC_LABEL_LEN, "%s\n",
- csrow->channels[1].label);
- }
-
- return size;
-}
-
-static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow,
- const char *data, size_t size)
-{
- ssize_t max_size = 0;
-
- if (csrow->nr_channels > 0) {
- max_size = min((ssize_t)size,(ssize_t)EDAC_MC_LABEL_LEN-1);
- strncpy(csrow->channels[0].label, data, max_size);
- csrow->channels[0].label[max_size] = '\0';
- }
-
- return size;
-}
-
-static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow,
- const char *data, size_t size)
-{
- ssize_t max_size = 0;
-
- if (csrow->nr_channels > 1) {
- max_size = min((ssize_t)size,(ssize_t)EDAC_MC_LABEL_LEN-1);
- strncpy(csrow->channels[1].label, data, max_size);
- csrow->channels[1].label[max_size] = '\0';
- }
-
- return max_size;
-}
-
-static ssize_t csrow_ue_count_show(struct csrow_info *csrow, char *data)
+/* Set of more default csrow<id> attribute show/store functions */
+static ssize_t csrow_ue_count_show(struct csrow_info *csrow, char *data, int private)
{
return sprintf(data,"%u\n", csrow->ue_count);
}
-static ssize_t csrow_ce_count_show(struct csrow_info *csrow, char *data)
+static ssize_t csrow_ce_count_show(struct csrow_info *csrow, char *data, int private)
{
return sprintf(data,"%u\n", csrow->ce_count);
}
-static ssize_t csrow_ch0_ce_count_show(struct csrow_info *csrow, char *data)
-{
- ssize_t size = 0;
-
- if (csrow->nr_channels > 0) {
- size = sprintf(data,"%u\n", csrow->channels[0].ce_count);
- }
-
- return size;
-}
-
-static ssize_t csrow_ch1_ce_count_show(struct csrow_info *csrow, char *data)
-{
- ssize_t size = 0;
-
- if (csrow->nr_channels > 1) {
- size = sprintf(data,"%u\n", csrow->channels[1].ce_count);
- }
-
- return size;
-}
-
-static ssize_t csrow_size_show(struct csrow_info *csrow, char *data)
+static ssize_t csrow_size_show(struct csrow_info *csrow, char *data, int private)
{
return sprintf(data,"%u\n", PAGES_TO_MiB(csrow->nr_pages));
}
-static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data)
+static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data, int private)
{
return sprintf(data,"%s\n", mem_types[csrow->mtype]);
}
-static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data)
+static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data, int private)
{
return sprintf(data,"%s\n", dev_types[csrow->dtype]);
}
-static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data)
+static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data, int private)
{
return sprintf(data,"%s\n", edac_caps[csrow->edac_mode]);
}
+/* show/store functions for DIMM Label attributes */
+static ssize_t channel_dimm_label_show(struct csrow_info *csrow,
+ char *data, int channel)
+{
+ return snprintf(data, EDAC_MC_LABEL_LEN,"%s",
+ csrow->channels[channel].label);
+}
+
+static ssize_t channel_dimm_label_store(struct csrow_info *csrow,
+ const char *data,
+ size_t count,
+ int channel)
+{
+ ssize_t max_size = 0;
+
+ max_size = min((ssize_t)count,(ssize_t)EDAC_MC_LABEL_LEN-1);
+ strncpy(csrow->channels[channel].label, data, max_size);
+ csrow->channels[channel].label[max_size] = '\0';
+
+ return max_size;
+}
+
+/* show function for dynamic chX_ce_count attribute */
+static ssize_t channel_ce_count_show(struct csrow_info *csrow,
+ char *data,
+ int channel)
+{
+ return sprintf(data, "%u\n", csrow->channels[channel].ce_count);
+}
+
+/* csrow specific attribute structure */
struct csrowdev_attribute {
struct attribute attr;
- ssize_t (*show)(struct csrow_info *,char *);
- ssize_t (*store)(struct csrow_info *, const char *,size_t);
+ ssize_t (*show)(struct csrow_info *,char *,int);
+ ssize_t (*store)(struct csrow_info *, const char *,size_t,int);
+ int private;
};
#define to_csrow(k) container_of(k, struct csrow_info, kobj)
#define to_csrowdev_attr(a) container_of(a, struct csrowdev_attribute, attr)
-/* Set of show/store higher level functions for csrow objects */
-static ssize_t csrowdev_show(struct kobject *kobj, struct attribute *attr,
- char *buffer)
+/* Set of show/store higher level functions for default csrow attributes */
+static ssize_t csrowdev_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buffer)
{
struct csrow_info *csrow = to_csrow(kobj);
struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr);
if (csrowdev_attr->show)
- return csrowdev_attr->show(csrow, buffer);
-
+ return csrowdev_attr->show(csrow,
+ buffer,
+ csrowdev_attr->private);
return -EIO;
}
@@ -1013,8 +699,10 @@
struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr);
if (csrowdev_attr->store)
- return csrowdev_attr->store(csrow, buffer, count);
-
+ return csrowdev_attr->store(csrow,
+ buffer,
+ count,
+ csrowdev_attr->private);
return -EIO;
}
@@ -1023,69 +711,157 @@
.store = csrowdev_store
};
-#define CSROWDEV_ATTR(_name,_mode,_show,_store) \
+#define CSROWDEV_ATTR(_name,_mode,_show,_store,_private) \
struct csrowdev_attribute attr_##_name = { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
+ .private = _private, \
};
-/* cwrow<id>/attribute files */
-CSROWDEV_ATTR(size_mb,S_IRUGO,csrow_size_show,NULL);
-CSROWDEV_ATTR(dev_type,S_IRUGO,csrow_dev_type_show,NULL);
-CSROWDEV_ATTR(mem_type,S_IRUGO,csrow_mem_type_show,NULL);
-CSROWDEV_ATTR(edac_mode,S_IRUGO,csrow_edac_mode_show,NULL);
-CSROWDEV_ATTR(ue_count,S_IRUGO,csrow_ue_count_show,NULL);
-CSROWDEV_ATTR(ce_count,S_IRUGO,csrow_ce_count_show,NULL);
-CSROWDEV_ATTR(ch0_ce_count,S_IRUGO,csrow_ch0_ce_count_show,NULL);
-CSROWDEV_ATTR(ch1_ce_count,S_IRUGO,csrow_ch1_ce_count_show,NULL);
+/* default cwrow<id>/attribute files */
+CSROWDEV_ATTR(size_mb,S_IRUGO,csrow_size_show,NULL,0);
+CSROWDEV_ATTR(dev_type,S_IRUGO,csrow_dev_type_show,NULL,0);
+CSROWDEV_ATTR(mem_type,S_IRUGO,csrow_mem_type_show,NULL,0);
+CSROWDEV_ATTR(edac_mode,S_IRUGO,csrow_edac_mode_show,NULL,0);
+CSROWDEV_ATTR(ue_count,S_IRUGO,csrow_ue_count_show,NULL,0);
+CSROWDEV_ATTR(ce_count,S_IRUGO,csrow_ce_count_show,NULL,0);
-/* control/attribute files */
-CSROWDEV_ATTR(ch0_dimm_label,S_IRUGO|S_IWUSR,
- csrow_ch0_dimm_label_show,
- csrow_ch0_dimm_label_store);
-CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR,
- csrow_ch1_dimm_label_show,
- csrow_ch1_dimm_label_store);
-
-/* Attributes of the CSROW<id> object */
-static struct csrowdev_attribute *csrow_attr[] = {
+/* default attributes of the CSROW<id> object */
+static struct csrowdev_attribute *default_csrow_attr[] = {
&attr_dev_type,
&attr_mem_type,
&attr_edac_mode,
&attr_size_mb,
&attr_ue_count,
&attr_ce_count,
- &attr_ch0_ce_count,
- &attr_ch1_ce_count,
- &attr_ch0_dimm_label,
- &attr_ch1_dimm_label,
NULL,
};
-/* No memory to release */
+
+/* possible dynamic channel DIMM Label attribute files */
+CSROWDEV_ATTR(ch0_dimm_label,S_IRUGO|S_IWUSR,
+ channel_dimm_label_show,
+ channel_dimm_label_store,
+ 0 );
+CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR,
+ channel_dimm_label_show,
+ channel_dimm_label_store,
+ 1 );
+CSROWDEV_ATTR(ch2_dimm_label,S_IRUGO|S_IWUSR,
+ channel_dimm_label_show,
+ channel_dimm_label_store,
+ 2 );
+CSROWDEV_ATTR(ch3_dimm_label,S_IRUGO|S_IWUSR,
+ channel_dimm_label_show,
+ channel_dimm_label_store,
+ 3 );
+CSROWDEV_ATTR(ch4_dimm_label,S_IRUGO|S_IWUSR,
+ channel_dimm_label_show,
+ channel_dimm_label_store,
+ 4 );
+CSROWDEV_ATTR(ch5_dimm_label,S_IRUGO|S_IWUSR,
+ channel_dimm_label_show,
+ channel_dimm_label_store,
+ 5 );
+
+/* Total possible dynamic DIMM Label attribute file table */
+static struct csrowdev_attribute *dynamic_csrow_dimm_attr[] = {
+ &attr_ch0_dimm_label,
+ &attr_ch1_dimm_label,
+ &attr_ch2_dimm_label,
+ &attr_ch3_dimm_label,
+ &attr_ch4_dimm_label,
+ &attr_ch5_dimm_label
+};
+
+/* possible dynamic channel ce_count attribute files */
+CSROWDEV_ATTR(ch0_ce_count,S_IRUGO|S_IWUSR,
+ channel_ce_count_show,
+ NULL,
+ 0 );
+CSROWDEV_ATTR(ch1_ce_count,S_IRUGO|S_IWUSR,
+ channel_ce_count_show,
+ NULL,
+ 1 );
+CSROWDEV_ATTR(ch2_ce_count,S_IRUGO|S_IWUSR,
+ channel_ce_count_show,
+ NULL,
+ 2 );
+CSROWDEV_ATTR(ch3_ce_count,S_IRUGO|S_IWUSR,
+ channel_ce_count_show,
+ NULL,
+ 3 );
+CSROWDEV_ATTR(ch4_ce_count,S_IRUGO|S_IWUSR,
+ channel_ce_count_show,
+ NULL,
+ 4 );
+CSROWDEV_ATTR(ch5_ce_count,S_IRUGO|S_IWUSR,
+ channel_ce_count_show,
+ NULL,
+ 5 );
+
+/* Total possible dynamic ce_count attribute file table */
+static struct csrowdev_attribute *dynamic_csrow_ce_count_attr[] = {
+ &attr_ch0_ce_count,
+ &attr_ch1_ce_count,
+ &attr_ch2_ce_count,
+ &attr_ch3_ce_count,
+ &attr_ch4_ce_count,
+ &attr_ch5_ce_count
+};
+
+
+#define EDAC_NR_CHANNELS 6
+
+/* Create dynamic CHANNEL files, indexed by 'chan', under specifed CSROW */
+static int edac_create_channel_files(struct kobject *kobj, int chan)
+{
+ int err=-ENODEV;
+
+ if (chan >= EDAC_NR_CHANNELS)
+ return err;
+
+ /* create the DIMM label attribute file */
+ err = sysfs_create_file(kobj,
+ (struct attribute *) dynamic_csrow_dimm_attr[chan]);
+
+ if (!err) {
+ /* create the CE Count attribute file */
+ err = sysfs_create_file(kobj,
+ (struct attribute *) dynamic_csrow_ce_count_attr[chan]);
+ } else {
+ debugf1("%s() dimm labels and ce_count files created", __func__);
+ }
+
+ return err;
+}
+
+/* No memory to release for this kobj */
static void edac_csrow_instance_release(struct kobject *kobj)
{
struct csrow_info *cs;
- debugf1("%s()\n", __func__);
cs = container_of(kobj, struct csrow_info, kobj);
complete(&cs->kobj_complete);
}
+/* the kobj_type instance for a CSROW */
static struct kobj_type ktype_csrow = {
.release = edac_csrow_instance_release,
.sysfs_ops = &csrowfs_ops,
- .default_attrs = (struct attribute **) csrow_attr,
+ .default_attrs = (struct attribute **) default_csrow_attr,
};
/* Create a CSROW object under specifed edac_mc_device */
-static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
- struct csrow_info *csrow, int index)
+static int edac_create_csrow_object(
+ struct kobject *edac_mci_kobj,
+ struct csrow_info *csrow,
+ int index)
{
int err = 0;
+ int chan;
- debugf0("%s()\n", __func__);
memset(&csrow->kobj, 0, sizeof(csrow->kobj));
/* generate ..../edac/mc/mc<id>/csrow<index> */
@@ -1095,21 +871,27 @@
/* name this instance of csrow<id> */
err = kobject_set_name(&csrow->kobj,"csrow%d",index);
+ if (err)
+ goto error_exit;
+ /* Instanstiate the csrow object */
+ err = kobject_register(&csrow->kobj);
if (!err) {
- /* Instanstiate the csrow object */
- err = kobject_register(&csrow->kobj);
-
- if (err)
- debugf0("Failed to register CSROW%d\n",index);
- else
- debugf0("Registered CSROW%d\n",index);
+ /* Create the dyanmic attribute files on this csrow,
+ * namely, the DIMM labels and the channel ce_count
+ */
+ for (chan = 0; chan < csrow->nr_channels; chan++) {
+ err = edac_create_channel_files(&csrow->kobj,chan);
+ if (err)
+ break;
+ }
}
+error_exit:
return err;
}
-/* sysfs data structures and methods for the MCI kobjects */
+/* default sysfs methods and data structures for the main MCI kobject */
static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
const char *data, size_t count)
@@ -1135,6 +917,7 @@
return count;
}
+/* default attribute files for the MCI object */
static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data)
{
return sprintf(data,"%d\n", mci->ue_count);
@@ -1160,71 +943,11 @@
return sprintf(data,"%ld\n", (jiffies - mci->start_time) / HZ);
}
-static ssize_t mci_mod_name_show(struct mem_ctl_info *mci, char *data)
-{
- return sprintf(data,"%s %s\n", mci->mod_name, mci->mod_ver);
-}
-
static ssize_t mci_ctl_name_show(struct mem_ctl_info *mci, char *data)
{
return sprintf(data,"%s\n", mci->ctl_name);
}
-static int mci_output_edac_cap(char *buf, unsigned long edac_cap)
-{
- char *p = buf;
- int bit_idx;
-
- for (bit_idx = 0; bit_idx < 8 * sizeof(edac_cap); bit_idx++) {
- if ((edac_cap >> bit_idx) & 0x1)
- p += sprintf(p, "%s ", edac_caps[bit_idx]);
- }
-
- return p - buf;
-}
-
-static ssize_t mci_edac_capability_show(struct mem_ctl_info *mci, char *data)
-{
- char *p = data;
-
- p += mci_output_edac_cap(p,mci->edac_ctl_cap);
- p += sprintf(p, "\n");
- return p - data;
-}
-
-static ssize_t mci_edac_current_capability_show(struct mem_ctl_info *mci,
- char *data)
-{
- char *p = data;
-
- p += mci_output_edac_cap(p,mci->edac_cap);
- p += sprintf(p, "\n");
- return p - data;
-}
-
-static int mci_output_mtype_cap(char *buf, unsigned long mtype_cap)
-{
- char *p = buf;
- int bit_idx;
-
- for (bit_idx = 0; bit_idx < 8 * sizeof(mtype_cap); bit_idx++) {
- if ((mtype_cap >> bit_idx) & 0x1)
- p += sprintf(p, "%s ", mem_types[bit_idx]);
- }
-
- return p - buf;
-}
-
-static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci,
- char *data)
-{
- char *p = data;
-
- p += mci_output_mtype_cap(p,mci->mtype_cap);
- p += sprintf(p, "\n");
- return p - data;
-}
-
static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data)
{
int total_pages, csrow_idx;
@@ -1251,6 +974,7 @@
#define to_mci(k) container_of(k, struct mem_ctl_info, edac_mci_kobj)
#define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr)
+/* MCI show/store functions for top most object */
static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr,
char *buffer)
{
@@ -1287,31 +1011,21 @@
.store = _store, \
};
-/* Control file */
+/* default Control file */
MCIDEV_ATTR(reset_counters,S_IWUSR,NULL,mci_reset_counters_store);
-/* Attribute files */
+/* default Attribute files */
MCIDEV_ATTR(mc_name,S_IRUGO,mci_ctl_name_show,NULL);
-MCIDEV_ATTR(module_name,S_IRUGO,mci_mod_name_show,NULL);
-MCIDEV_ATTR(edac_capability,S_IRUGO,mci_edac_capability_show,NULL);
MCIDEV_ATTR(size_mb,S_IRUGO,mci_size_mb_show,NULL);
MCIDEV_ATTR(seconds_since_reset,S_IRUGO,mci_seconds_show,NULL);
MCIDEV_ATTR(ue_noinfo_count,S_IRUGO,mci_ue_noinfo_show,NULL);
MCIDEV_ATTR(ce_noinfo_count,S_IRUGO,mci_ce_noinfo_show,NULL);
MCIDEV_ATTR(ue_count,S_IRUGO,mci_ue_count_show,NULL);
MCIDEV_ATTR(ce_count,S_IRUGO,mci_ce_count_show,NULL);
-MCIDEV_ATTR(edac_current_capability,S_IRUGO,
- mci_edac_current_capability_show,NULL);
-MCIDEV_ATTR(supported_mem_type,S_IRUGO,
- mci_supported_mem_type_show,NULL);
static struct mcidev_attribute *mci_attr[] = {
&mci_attr_reset_counters,
- &mci_attr_module_name,
&mci_attr_mc_name,
- &mci_attr_edac_capability,
- &mci_attr_edac_current_capability,
- &mci_attr_supported_mem_type,
&mci_attr_size_mb,
&mci_attr_seconds_since_reset,
&mci_attr_ue_noinfo_count,
@@ -1339,7 +1053,6 @@
.default_attrs = (struct attribute **) mci_attr,
};
-#endif /* DISABLE_EDAC_SYSFS */
#define EDAC_DEVICE_SYMLINK "device"
@@ -1352,11 +1065,6 @@
* !0 Failure
*/
static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
-#ifdef DISABLE_EDAC_SYSFS
-{
- return 0;
-}
-#else
{
int i;
int err;
@@ -1368,7 +1076,6 @@
/* set the name of the mc<id> object */
err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx);
-
if (err)
return err;
@@ -1378,14 +1085,12 @@
/* register the mc<id> kobject */
err = kobject_register(edac_mci_kobj);
-
if (err)
return err;
/* create a symlink for the device */
err = sysfs_create_link(edac_mci_kobj, &mci->dev->kobj,
EDAC_DEVICE_SYMLINK);
-
if (err)
goto fail0;
@@ -1398,7 +1103,6 @@
/* Only expose populated CSROWs */
if (csrow->nr_pages > 0) {
err = edac_create_csrow_object(edac_mci_kobj,csrow,i);
-
if (err)
goto fail1;
}
@@ -1422,14 +1126,12 @@
wait_for_completion(&mci->kobj_complete);
return err;
}
-#endif /* DISABLE_EDAC_SYSFS */
/*
* remove a Memory Controller instance
*/
static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
{
-#ifndef DISABLE_EDAC_SYSFS
int i;
debugf0("%s()\n", __func__);
@@ -1447,7 +1149,6 @@
init_completion(&mci->kobj_complete);
kobject_unregister(&mci->edac_mci_kobj);
wait_for_completion(&mci->kobj_complete);
-#endif /* DISABLE_EDAC_SYSFS */
}
/* END OF sysfs data and methods */
diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c
index a98c5e3..93ff941 100644
--- a/drivers/isdn/hisax/asuscom.c
+++ b/drivers/isdn/hisax/asuscom.c
@@ -297,7 +297,7 @@
}
#ifdef __ISAPNP__
-static struct isapnp_device_id asus_ids[] __initdata = {
+static struct isapnp_device_id asus_ids[] __devinitdata = {
{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
(unsigned long) "Asus1688 PnP" },
@@ -313,11 +313,11 @@
{ 0, }
};
-static struct isapnp_device_id *ipid __initdata = &asus_ids[0];
+static struct isapnp_device_id *ipid __devinitdata = &asus_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
-int __init
+int __devinit
setup_asuscom(struct IsdnCard *card)
{
int bytecnt;
diff --git a/drivers/isdn/hisax/avm_a1.c b/drivers/isdn/hisax/avm_a1.c
index 9a8b025..729e906b 100644
--- a/drivers/isdn/hisax/avm_a1.c
+++ b/drivers/isdn/hisax/avm_a1.c
@@ -178,7 +178,7 @@
return(0);
}
-int __init
+int __devinit
setup_avm_a1(struct IsdnCard *card)
{
u_char val;
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 04f5917..369afd3 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -639,7 +639,7 @@
}
#endif /* 0 */
-static void __init
+static void
inithdlc(struct IsdnCardState *cs)
{
cs->bcs[0].BC_SetStack = setstack_hdlc;
@@ -727,13 +727,13 @@
}
#ifdef CONFIG_PCI
-static struct pci_dev *dev_avm __initdata = NULL;
+static struct pci_dev *dev_avm __devinitdata = NULL;
#endif
#ifdef __ISAPNP__
-static struct pnp_card *pnp_avm_c __initdata = NULL;
+static struct pnp_card *pnp_avm_c __devinitdata = NULL;
#endif
-int __init
+int __devinit
setup_avm_pcipnp(struct IsdnCard *card)
{
u_int val, ver;
diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c
index 3cf1f24..87a6301 100644
--- a/drivers/isdn/hisax/bkm_a4t.c
+++ b/drivers/isdn/hisax/bkm_a4t.c
@@ -255,9 +255,9 @@
return (0);
}
-static struct pci_dev *dev_a4t __initdata = NULL;
+static struct pci_dev *dev_a4t __devinitdata = NULL;
-int __init
+int __devinit
setup_bkm_a4t(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c
index 15681f3..dae090a 100644
--- a/drivers/isdn/hisax/bkm_a8.c
+++ b/drivers/isdn/hisax/bkm_a8.c
@@ -260,7 +260,7 @@
return (0);
}
-static int __init
+static int __devinit
sct_alloc_io(u_int adr, u_int len)
{
if (!request_region(adr, len, "scitel")) {
@@ -272,16 +272,16 @@
return(0);
}
-static struct pci_dev *dev_a8 __initdata = NULL;
-static u16 sub_vendor_id __initdata = 0;
-static u16 sub_sys_id __initdata = 0;
-static u_char pci_bus __initdata = 0;
-static u_char pci_device_fn __initdata = 0;
-static u_char pci_irq __initdata = 0;
+static struct pci_dev *dev_a8 __devinitdata = NULL;
+static u16 sub_vendor_id __devinitdata = 0;
+static u16 sub_sys_id __devinitdata = 0;
+static u_char pci_bus __devinitdata = 0;
+static u_char pci_device_fn __devinitdata = 0;
+static u_char pci_irq __devinitdata = 0;
#endif /* CONFIG_PCI */
-int __init
+int __devinit
setup_sct_quadro(struct IsdnCard *card)
{
#ifdef CONFIG_PCI
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 5333be5..e103503 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1875,7 +1875,7 @@
#ifdef CONFIG_PCI
#include <linux/pci.h>
-static struct pci_device_id hisax_pci_tbl[] __initdata = {
+static struct pci_device_id hisax_pci_tbl[] __devinitdata = {
#ifdef CONFIG_HISAX_FRITZPCI
{PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID},
#endif
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index 323a02e..e294fa3 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -887,13 +887,13 @@
return(0);
}
-static struct pci_dev *dev_diva __initdata = NULL;
-static struct pci_dev *dev_diva_u __initdata = NULL;
-static struct pci_dev *dev_diva201 __initdata = NULL;
-static struct pci_dev *dev_diva202 __initdata = NULL;
+static struct pci_dev *dev_diva __devinitdata = NULL;
+static struct pci_dev *dev_diva_u __devinitdata = NULL;
+static struct pci_dev *dev_diva201 __devinitdata = NULL;
+static struct pci_dev *dev_diva202 __devinitdata = NULL;
#ifdef __ISAPNP__
-static struct isapnp_device_id diva_ids[] __initdata = {
+static struct isapnp_device_id diva_ids[] __devinitdata = {
{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
(unsigned long) "Diva picola" },
@@ -915,12 +915,12 @@
{ 0, }
};
-static struct isapnp_device_id *ipid __initdata = &diva_ids[0];
+static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
-int __init
+int __devinit
setup_diva(struct IsdnCard *card)
{
int bytecnt = 8;
diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c
index 8fcbe2e..76c7d29 100644
--- a/drivers/isdn/hisax/enternow_pci.c
+++ b/drivers/isdn/hisax/enternow_pci.c
@@ -301,10 +301,10 @@
}
-static struct pci_dev *dev_netjet __initdata = NULL;
+static struct pci_dev *dev_netjet __devinitdata = NULL;
/* called by config.c */
-int __init
+int __devinit
setup_enternow_pci(struct IsdnCard *card)
{
int bytecnt;
diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c
index 3e7d923..fe29372 100644
--- a/drivers/isdn/hisax/gazel.c
+++ b/drivers/isdn/hisax/gazel.c
@@ -484,7 +484,7 @@
return 1;
}
-static int __init
+static int __devinit
setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs)
{
printk(KERN_INFO "Gazel: ISA PnP card automatic recognition\n");
@@ -532,9 +532,9 @@
return (0);
}
-static struct pci_dev *dev_tel __initdata = NULL;
+static struct pci_dev *dev_tel __devinitdata = NULL;
-static int __init
+static int __devinit
setup_gazelpci(struct IsdnCardState *cs)
{
u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0;
@@ -621,7 +621,7 @@
return (0);
}
-int __init
+int __devinit
setup_gazel(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 0f967b3..3a5ca8a 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -1703,7 +1703,7 @@
/* driver module exit : */
/* release the HFC-4s/8s hardware */
/*************************************/
-static void
+static void __exit
hfc4s8s_module_exit(void)
{
pci_unregister_driver(&hfc4s8s_driver);
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 637a261..6360e82 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -1015,7 +1015,7 @@
{
}
-static unsigned int __init
+static unsigned int
*init_send_hfcd(int cnt)
{
int i, *send;
@@ -1030,7 +1030,7 @@
return(send);
}
-void __init
+void
init2bds0(struct IsdnCardState *cs)
{
cs->setstack_d = setstack_hfcd;
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index c964539..d0520ad 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -551,7 +551,7 @@
return (0);
}
-static void __init
+static void
init_send(struct BCState *bcs)
{
int i;
@@ -565,7 +565,7 @@
bcs->hw.hfc.send[i] = 0x1fff;
}
-void __init
+void
inithfc(struct IsdnCardState *cs)
{
init_send(&cs->bcs[0]);
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 7241e73..1df60ca 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1581,7 +1581,7 @@
/********************************/
/* called for card init message */
/********************************/
-static void __init
+static void
inithfcpci(struct IsdnCardState *cs)
{
cs->bcs[0].BC_SetStack = setstack_2b;
@@ -1638,11 +1638,11 @@
/* this variable is used as card index when more than one cards are present */
-static struct pci_dev *dev_hfcpci __initdata = NULL;
+static struct pci_dev *dev_hfcpci __devinitdata = NULL;
#endif /* CONFIG_PCI */
-int __init
+int __devinit
setup_hfcpci(struct IsdnCard *card)
{
u_long flags;
diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c
index 86ab1c1..4e7f472 100644
--- a/drivers/isdn/hisax/hfcscard.c
+++ b/drivers/isdn/hisax/hfcscard.c
@@ -139,7 +139,7 @@
}
#ifdef __ISAPNP__
-static struct isapnp_device_id hfc_ids[] __initdata = {
+static struct isapnp_device_id hfc_ids[] __devinitdata = {
{ ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
(unsigned long) "Acer P10" },
@@ -164,11 +164,11 @@
{ 0, }
};
-static struct isapnp_device_id *ipid __initdata = &hfc_ids[0];
+static struct isapnp_device_id *ipid __devinitdata = &hfc_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
-int __init
+int __devinit
setup_hfcs(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index c615752..2cf7b66 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -24,10 +24,10 @@
#define DBUSY_TIMER_VALUE 80
#define ARCOFI_USE 0
-static char *ICCVer[] __initdata =
+static char *ICCVer[] =
{"2070 A1/A3", "2070 B1", "2070 B2/B3", "2070 V2.4"};
-void __init
+void
ICCVersion(struct IsdnCardState *cs, char *s)
{
int val;
@@ -613,7 +613,7 @@
}
}
-void __init
+void
initicc(struct IsdnCardState *cs)
{
cs->setstack_d = setstack_icc;
@@ -646,7 +646,7 @@
ph_command(cs, ICC_CMD_DI);
}
-void __init
+void
clear_pending_icc_ints(struct IsdnCardState *cs)
{
int val, eval;
diff --git a/drivers/isdn/hisax/icc.h b/drivers/isdn/hisax/icc.h
index b3bb3d5..e7f5939 100644
--- a/drivers/isdn/hisax/icc.h
+++ b/drivers/isdn/hisax/icc.h
@@ -65,7 +65,7 @@
#define ICC_IND_AIL 0xE
#define ICC_IND_DC 0xF
-extern void __init ICCVersion(struct IsdnCardState *cs, char *s);
+extern void ICCVersion(struct IsdnCardState *cs, char *s);
extern void initicc(struct IsdnCardState *cs);
extern void icc_interrupt(struct IsdnCardState *cs, u_char val);
extern void clear_pending_icc_ints(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index df5fc92..00afd55 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -38,8 +38,8 @@
static void dch_empty_fifo(struct IsdnCardState *cs, int count);
static void dch_fill_fifo(struct IsdnCardState *cs);
static inline void dch_int(struct IsdnCardState *cs);
-static void __devinit dch_setstack(struct PStack *st, struct IsdnCardState *cs);
-static void __devinit dch_init(struct IsdnCardState *cs);
+static void dch_setstack(struct PStack *st, struct IsdnCardState *cs);
+static void dch_init(struct IsdnCardState *cs);
static void bch_l2l1(struct PStack *st, int pr, void *arg);
static void bch_empty_fifo(struct BCState *bcs, int count);
static void bch_fill_fifo(struct BCState *bcs);
@@ -48,8 +48,8 @@
static void bch_close_state(struct BCState *bcs);
static int bch_open_state(struct IsdnCardState *cs, struct BCState *bcs);
static int bch_setstack(struct PStack *st, struct BCState *bcs);
-static void __devinit bch_init(struct IsdnCardState *cs, int hscx);
-static void __init clear_pending_ints(struct IsdnCardState *cs);
+static void bch_init(struct IsdnCardState *cs, int hscx);
+static void clear_pending_ints(struct IsdnCardState *cs);
//----------------------------------------------------------
// Issue Layer 1 command to chip
@@ -408,7 +408,7 @@
//----------------------------------------------------------
//----------------------------------------------------------
-static void __devinit
+static void
dch_setstack(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = dch_l2l1;
@@ -416,7 +416,7 @@
//----------------------------------------------------------
//----------------------------------------------------------
-static void __devinit
+static void
dch_init(struct IsdnCardState *cs)
{
printk(KERN_INFO "HiSax: IPACX ISDN driver v0.1.0\n");
@@ -823,7 +823,7 @@
//----------------------------------------------------------
//----------------------------------------------------------
-static void __devinit
+static void
bch_init(struct IsdnCardState *cs, int hscx)
{
cs->bcs[hscx].BC_SetStack = bch_setstack;
@@ -861,7 +861,7 @@
//----------------------------------------------------------
// Clears chip interrupt status
//----------------------------------------------------------
-static void __init
+static void
clear_pending_ints(struct IsdnCardState *cs)
{
int ista;
@@ -883,7 +883,7 @@
// Does chip configuration work
// Work to do depends on bit mask in part
//----------------------------------------------------------
-void __init
+void
init_ipacx(struct IsdnCardState *cs, int part)
{
if (part &1) { // initialise chip
diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c
index 33747af..715a1a8 100644
--- a/drivers/isdn/hisax/isurf.c
+++ b/drivers/isdn/hisax/isurf.c
@@ -196,10 +196,10 @@
}
#ifdef __ISAPNP__
-static struct pnp_card *pnp_c __initdata = NULL;
+static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
-int __init
+int __devinit
setup_isurf(struct IsdnCard *card)
{
int ver;
diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c
index 908a7e1..3971750 100644
--- a/drivers/isdn/hisax/ix1_micro.c
+++ b/drivers/isdn/hisax/ix1_micro.c
@@ -210,7 +210,7 @@
}
#ifdef __ISAPNP__
-static struct isapnp_device_id itk_ids[] __initdata = {
+static struct isapnp_device_id itk_ids[] __devinitdata = {
{ ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
(unsigned long) "ITK micro 2" },
@@ -220,12 +220,12 @@
{ 0, }
};
-static struct isapnp_device_id *ipid __initdata = &itk_ids[0];
+static struct isapnp_device_id *ipid __devinitdata = &itk_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
-int __init
+int __devinit
setup_ix1micro(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index 2659fec..43d61d1 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -19,7 +19,7 @@
#include <linux/interrupt.h>
-int __init
+int
JadeVersion(struct IsdnCardState *cs, char *s)
{
int ver,i;
@@ -253,7 +253,7 @@
return (0);
}
-void __init
+void
clear_pending_jade_ints(struct IsdnCardState *cs)
{
int val;
@@ -279,7 +279,7 @@
cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8);
}
-void __init
+void
initjade(struct IsdnCardState *cs)
{
cs->bcs[0].BC_SetStack = setstack_jade;
diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c
index fe11f22..8c82519 100644
--- a/drivers/isdn/hisax/mic.c
+++ b/drivers/isdn/hisax/mic.c
@@ -189,7 +189,7 @@
return(0);
}
-int __init
+int __devinit
setup_mic(struct IsdnCard *card)
{
int bytecnt;
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index 47a47ef..38f648f 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -909,7 +909,7 @@
}
-void __init
+void
inittiger(struct IsdnCardState *cs)
{
if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int),
diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c
index 79a97b1..489022b 100644
--- a/drivers/isdn/hisax/niccy.c
+++ b/drivers/isdn/hisax/niccy.c
@@ -232,12 +232,12 @@
return(0);
}
-static struct pci_dev *niccy_dev __initdata = NULL;
+static struct pci_dev *niccy_dev __devinitdata = NULL;
#ifdef __ISAPNP__
static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
-int __init
+int __devinit
setup_niccy(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c
index e5b900a..80025fd 100644
--- a/drivers/isdn/hisax/nj_s.c
+++ b/drivers/isdn/hisax/nj_s.c
@@ -148,9 +148,9 @@
return(0);
}
-static struct pci_dev *dev_netjet __initdata = NULL;
+static struct pci_dev *dev_netjet __devinitdata = NULL;
-int __init
+int __devinit
setup_netjet_s(struct IsdnCard *card)
{
int bytecnt,cfg;
diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c
index 7002b09..3749716 100644
--- a/drivers/isdn/hisax/nj_u.c
+++ b/drivers/isdn/hisax/nj_u.c
@@ -128,9 +128,9 @@
return(0);
}
-static struct pci_dev *dev_netjet __initdata = NULL;
+static struct pci_dev *dev_netjet __devinitdata = NULL;
-int __init
+int __devinit
setup_netjet_u(struct IsdnCard *card)
{
int bytecnt;
diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c
index 7b63085..e76042d 100644
--- a/drivers/isdn/hisax/s0box.c
+++ b/drivers/isdn/hisax/s0box.c
@@ -211,7 +211,7 @@
return(0);
}
-int __init
+int __devinit
setup_s0box(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c
index 821776e..d943d36 100644
--- a/drivers/isdn/hisax/saphir.c
+++ b/drivers/isdn/hisax/saphir.c
@@ -241,7 +241,7 @@
}
-int __init
+int __devinit
setup_saphir(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c
index cdf35dc..a49b694 100644
--- a/drivers/isdn/hisax/sportster.c
+++ b/drivers/isdn/hisax/sportster.c
@@ -184,7 +184,7 @@
return(0);
}
-static int __init
+static int __devinit
get_io_range(struct IsdnCardState *cs)
{
int i, j, adr;
@@ -209,7 +209,7 @@
}
}
-int __init
+int __devinit
setup_sportster(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c
index a2b1816..e94dc6f 100644
--- a/drivers/isdn/hisax/teleint.c
+++ b/drivers/isdn/hisax/teleint.c
@@ -261,7 +261,7 @@
return(0);
}
-int __init
+int __devinit
setup_TeleInt(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c
index 2b7df8f..f94af09 100644
--- a/drivers/isdn/hisax/teles0.c
+++ b/drivers/isdn/hisax/teles0.c
@@ -265,7 +265,7 @@
return(0);
}
-int __init
+int __devinit
setup_teles0(struct IsdnCard *card)
{
u_char val;
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c
index 9382cdf..dca4468 100644
--- a/drivers/isdn/hisax/telespci.c
+++ b/drivers/isdn/hisax/telespci.c
@@ -284,9 +284,9 @@
return(0);
}
-static struct pci_dev *dev_tel __initdata = NULL;
+static struct pci_dev *dev_tel __devinitdata = NULL;
-int __init
+int __devinit
setup_telespci(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index 6c68419..0595293 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -44,11 +44,11 @@
#define DBUSY_TIMER_VALUE 80
-static char *W6692Ver[] __initdata =
+static char *W6692Ver[] =
{"W6692 V00", "W6692 V01", "W6692 V10",
"W6692 V11"};
-static void __init
+static void
W6692Version(struct IsdnCardState *cs, char *s)
{
int val;
@@ -897,7 +897,7 @@
}
}
-static void __init initW6692(struct IsdnCardState *cs, int part)
+static void initW6692(struct IsdnCardState *cs, int part)
{
if (part & 1) {
cs->setstack_d = setstack_W6692;
@@ -992,9 +992,9 @@
static int id_idx ;
-static struct pci_dev *dev_w6692 __initdata = NULL;
+static struct pci_dev *dev_w6692 __devinitdata = NULL;
-int __init
+int __devinit
setup_w6692(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 9f6c637..c3d79ee 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1059,7 +1059,7 @@
static ssize_t
isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
{
- uint minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ uint minor = iminor(file->f_dentry->d_inode);
int len = 0;
int drvidx;
int chidx;
@@ -1163,7 +1163,7 @@
static ssize_t
isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
{
- uint minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ uint minor = iminor(file->f_dentry->d_inode);
int drvidx;
int chidx;
int retval;
@@ -1225,7 +1225,7 @@
isdn_poll(struct file *file, poll_table * wait)
{
unsigned int mask = 0;
- unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ unsigned int minor = iminor(file->f_dentry->d_inode);
int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
lock_kernel();
@@ -1266,7 +1266,7 @@
static int
isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
{
- uint minor = MINOR(inode->i_rdev);
+ uint minor = iminor(inode);
isdn_ctrl c;
int drvidx;
int chidx;
@@ -1717,7 +1717,7 @@
static int
isdn_open(struct inode *ino, struct file *filep)
{
- uint minor = MINOR(ino->i_rdev);
+ uint minor = iminor(ino);
int drvidx;
int chidx;
int retval = -ENODEV;
@@ -1779,7 +1779,7 @@
static int
isdn_close(struct inode *ino, struct file *filep)
{
- uint minor = MINOR(ino->i_rdev);
+ uint minor = iminor(ino);
lock_kernel();
if (minor == ISDN_MINOR_STATUS) {
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 29e7667..119412d 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -667,7 +667,7 @@
if (is->debug & 0x2)
printk(KERN_DEBUG "isdn_ppp_poll: minor: %d\n",
- MINOR(file->f_dentry->d_inode->i_rdev));
+ iminor(file->f_dentry->d_inode));
/* just registers wait_queue hook. This doesn't really wait. */
poll_wait(file, &is->wq, wait);
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9650998..9c39b98 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -69,6 +69,13 @@
help
This option enables support for the LEDs on Amstrad Delta (E3).
+config LEDS_NET48XX
+ tristate "LED Support for Soekris net48xx series Error LED"
+ depends on LEDS_CLASS && SCx200_GPIO
+ help
+ This option enables support for the Soekris net4801 and net4826 error
+ LED.
+
comment "LED Triggers"
config LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 88d3b6e..6aa2aed 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -12,6 +12,7 @@
obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
+obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
diff --git a/drivers/leds/leds-net48xx.c b/drivers/leds/leds-net48xx.c
new file mode 100644
index 0000000..35ee52f
--- /dev/null
+++ b/drivers/leds/leds-net48xx.c
@@ -0,0 +1,115 @@
+/*
+ * LEDs driver for Soekris net48xx
+ *
+ * Copyright (C) 2006 Chris Boot <bootc@bootc.net>
+ *
+ * Based on leds-ams-delta.c
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <linux/scx200_gpio.h>
+
+#define NET48XX_ERROR_LED_GPIO 20
+
+static struct platform_device *pdev;
+
+static void net48xx_error_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ scx200_gpio_set_high(NET48XX_ERROR_LED_GPIO);
+ else
+ scx200_gpio_set_low(NET48XX_ERROR_LED_GPIO);
+}
+
+static struct led_classdev net48xx_error_led = {
+ .name = "net48xx:error",
+ .brightness_set = net48xx_error_led_set,
+};
+
+#ifdef CONFIG_PM
+static int net48xx_led_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ led_classdev_suspend(&net48xx_error_led);
+ return 0;
+}
+
+static int net48xx_led_resume(struct platform_device *dev)
+{
+ led_classdev_resume(&net48xx_error_led);
+ return 0;
+}
+#else
+#define net48xx_led_suspend NULL
+#define net48xx_led_resume NULL
+#endif
+
+static int net48xx_led_probe(struct platform_device *pdev)
+{
+ return led_classdev_register(&pdev->dev, &net48xx_error_led);
+}
+
+static int net48xx_led_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&net48xx_error_led);
+ return 0;
+}
+
+static struct platform_driver net48xx_led_driver = {
+ .driver.owner = THIS_MODULE,
+ .probe = net48xx_led_probe,
+ .remove = net48xx_led_remove,
+ .suspend = net48xx_led_suspend,
+ .resume = net48xx_led_resume,
+ .driver = {
+ .name = "net48xx-led",
+ },
+};
+
+static int __init net48xx_led_init(void)
+{
+ int ret;
+
+ if (!scx200_gpio_present()) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ret = platform_driver_register(&net48xx_led_driver);
+ if (ret < 0)
+ goto out;
+
+ pdev = platform_device_register_simple("net48xx-led", -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ platform_driver_unregister(&net48xx_led_driver);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit net48xx_led_exit(void)
+{
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&net48xx_led_driver);
+}
+
+module_init(net48xx_led_init);
+module_exit(net48xx_led_exit);
+
+MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
+MODULE_DESCRIPTION("Soekris net48xx LED driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 54f3f6b..f5fe7fb 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -113,7 +113,10 @@
config PMAC_BACKLIGHT
bool "Backlight control for LCD screens"
- depends on ADB_PMU && (BROKEN || !PPC64)
+ depends on ADB_PMU && FB = y && (BROKEN || !PPC64)
+ select FB_BACKLIGHT
+ select BACKLIGHT_CLASS_DEVICE
+ select BACKLIGHT_LCD_SUPPORT
help
Say Y here to enable Macintosh specific extensions of the generic
backlight code. With this enabled, the brightness keys on older
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 80c0c66..82657bc 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -330,7 +330,7 @@
{
unsigned int irq;
- irq = irq_create_mapping(NULL, line, 0);
+ irq = irq_create_mapping(NULL, line);
if (irq != NO_IRQ) {
dev->interrupt[index].start = irq;
dev->interrupt[index].flags = IORESOURCE_IRQ;
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index f139a74..00ef468 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -75,9 +75,11 @@
struct of_device *of_dev;
int doorbell; /* doorbell gpio */
u32 __iomem *db_buf; /* doorbell buffer */
- int db_irq;
+ struct device_node *db_node;
+ unsigned int db_irq;
int msg;
- int msg_irq;
+ struct device_node *msg_node;
+ unsigned int msg_irq;
struct smu_cmd_buf *cmd_buf; /* command buffer virtual */
u32 cmd_buf_abs; /* command buffer absolute */
struct list_head cmd_list;
@@ -93,6 +95,7 @@
*/
static struct smu_device *smu;
static DEFINE_MUTEX(smu_part_access);
+static int smu_irq_inited;
static void smu_i2c_retry(unsigned long data);
@@ -257,6 +260,10 @@
smu_start_cmd();
spin_unlock_irqrestore(&smu->lock, flags);
+ /* Workaround for early calls when irq isn't available */
+ if (!smu_irq_inited || smu->db_irq == NO_IRQ)
+ smu_spinwait_cmd(cmd);
+
return 0;
}
EXPORT_SYMBOL(smu_queue_cmd);
@@ -478,14 +485,15 @@
smu->cmd_buf_abs = (u32)smu_cmdbuf_abs;
smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs);
- np = of_find_node_by_name(NULL, "smu-doorbell");
- if (np == NULL) {
+ smu->db_node = of_find_node_by_name(NULL, "smu-doorbell");
+ if (smu->db_node == NULL) {
printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n");
goto fail;
}
- data = (u32 *)get_property(np, "reg", NULL);
+ data = (u32 *)get_property(smu->db_node, "reg", NULL);
if (data == NULL) {
- of_node_put(np);
+ of_node_put(smu->db_node);
+ smu->db_node = NULL;
printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n");
goto fail;
}
@@ -497,25 +505,21 @@
smu->doorbell = *data;
if (smu->doorbell < 0x50)
smu->doorbell += 0x50;
- smu->db_irq = irq_of_parse_and_map(np, 0);
-
- of_node_put(np);
/* Now look for the smu-interrupt GPIO */
do {
- np = of_find_node_by_name(NULL, "smu-interrupt");
- if (np == NULL)
+ smu->msg_node = of_find_node_by_name(NULL, "smu-interrupt");
+ if (smu->msg_node == NULL)
break;
- data = (u32 *)get_property(np, "reg", NULL);
+ data = (u32 *)get_property(smu->msg_node, "reg", NULL);
if (data == NULL) {
- of_node_put(np);
+ of_node_put(smu->msg_node);
+ smu->msg_node = NULL;
break;
}
smu->msg = *data;
if (smu->msg < 0x50)
smu->msg += 0x50;
- smu->msg_irq = irq_of_parse_and_map(np, 0);
- of_node_put(np);
} while(0);
/* Doorbell buffer is currently hard-coded, I didn't find a proper
@@ -547,6 +551,19 @@
smu->i2c_timer.function = smu_i2c_retry;
smu->i2c_timer.data = (unsigned long)smu;
+ if (smu->db_node) {
+ smu->db_irq = irq_of_parse_and_map(smu->db_node, 0);
+ if (smu->db_irq == NO_IRQ)
+ printk(KERN_ERR "smu: failed to map irq for node %s\n",
+ smu->db_node->full_name);
+ }
+ if (smu->msg_node) {
+ smu->msg_irq = irq_of_parse_and_map(smu->msg_node, 0);
+ if (smu->msg_irq == NO_IRQ)
+ printk(KERN_ERR "smu: failed to map irq for node %s\n",
+ smu->msg_node->full_name);
+ }
+
/*
* Try to request the interrupts
*/
@@ -571,6 +588,7 @@
}
}
+ smu_irq_inited = 1;
return 0;
}
/* This has to be before arch_initcall as the low i2c stuff relies on the
@@ -742,6 +760,11 @@
if (fail && --cmd->retries > 0) {
DPRINTK("SMU: i2c failure, starting timer...\n");
BUG_ON(cmd != smu->cmd_i2c_cur);
+ if (!smu_irq_inited) {
+ mdelay(5);
+ smu_i2c_retry(0);
+ return;
+ }
mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5));
return;
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index e4e1613..b6d1602 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -110,7 +110,7 @@
.procname = "speed_limit_min",
.data = &sysctl_speed_limit_min,
.maxlen = sizeof(int),
- .mode = 0644,
+ .mode = S_IRUGO|S_IWUSR,
.proc_handler = &proc_dointvec,
},
{
@@ -118,7 +118,7 @@
.procname = "speed_limit_max",
.data = &sysctl_speed_limit_max,
.maxlen = sizeof(int),
- .mode = 0644,
+ .mode = S_IRUGO|S_IWUSR,
.proc_handler = &proc_dointvec,
},
{ .ctl_name = 0 }
@@ -129,7 +129,7 @@
.ctl_name = DEV_RAID,
.procname = "raid",
.maxlen = 0,
- .mode = 0555,
+ .mode = S_IRUGO|S_IXUGO,
.child = raid_table,
},
{ .ctl_name = 0 }
@@ -1062,6 +1062,11 @@
if (rdev->sb_size & bmask)
rdev-> sb_size = (rdev->sb_size | bmask)+1;
+ if (sb->level == cpu_to_le32(LEVEL_MULTIPATH))
+ rdev->desc_nr = -1;
+ else
+ rdev->desc_nr = le32_to_cpu(sb->dev_number);
+
if (refdev == 0)
ret = 1;
else {
@@ -1171,7 +1176,6 @@
}
if (mddev->level != LEVEL_MULTIPATH) {
int role;
- rdev->desc_nr = le32_to_cpu(sb->dev_number);
role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
switch(role) {
case 0xffff: /* spare */
@@ -1779,8 +1783,8 @@
}
return err ? err : len;
}
-static struct rdev_sysfs_entry
-rdev_state = __ATTR(state, 0644, state_show, state_store);
+static struct rdev_sysfs_entry rdev_state =
+__ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store);
static ssize_t
super_show(mdk_rdev_t *rdev, char *page)
@@ -1811,7 +1815,7 @@
return -EINVAL;
}
static struct rdev_sysfs_entry rdev_errors =
-__ATTR(errors, 0644, errors_show, errors_store);
+__ATTR(errors, S_IRUGO|S_IWUSR, errors_show, errors_store);
static ssize_t
slot_show(mdk_rdev_t *rdev, char *page)
@@ -1845,7 +1849,7 @@
static struct rdev_sysfs_entry rdev_slot =
-__ATTR(slot, 0644, slot_show, slot_store);
+__ATTR(slot, S_IRUGO|S_IWUSR, slot_show, slot_store);
static ssize_t
offset_show(mdk_rdev_t *rdev, char *page)
@@ -1867,7 +1871,7 @@
}
static struct rdev_sysfs_entry rdev_offset =
-__ATTR(offset, 0644, offset_show, offset_store);
+__ATTR(offset, S_IRUGO|S_IWUSR, offset_show, offset_store);
static ssize_t
rdev_size_show(mdk_rdev_t *rdev, char *page)
@@ -1891,7 +1895,7 @@
}
static struct rdev_sysfs_entry rdev_size =
-__ATTR(size, 0644, rdev_size_show, rdev_size_store);
+__ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store);
static struct attribute *rdev_default_attrs[] = {
&rdev_state.attr,
@@ -1922,6 +1926,8 @@
if (!entry->store)
return -EIO;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
return entry->store(rdev, page, length);
}
@@ -2128,7 +2134,7 @@
return len;
}
static struct md_sysfs_entry md_safe_delay =
-__ATTR(safe_mode_delay, 0644,safe_delay_show, safe_delay_store);
+__ATTR(safe_mode_delay, S_IRUGO|S_IWUSR,safe_delay_show, safe_delay_store);
static ssize_t
level_show(mddev_t *mddev, char *page)
@@ -2163,7 +2169,7 @@
}
static struct md_sysfs_entry md_level =
-__ATTR(level, 0644, level_show, level_store);
+__ATTR(level, S_IRUGO|S_IWUSR, level_show, level_store);
static ssize_t
@@ -2188,7 +2194,7 @@
return len;
}
static struct md_sysfs_entry md_layout =
-__ATTR(layout, 0655, layout_show, layout_store);
+__ATTR(layout, S_IRUGO|S_IWUSR, layout_show, layout_store);
static ssize_t
@@ -2219,7 +2225,7 @@
return rv ? rv : len;
}
static struct md_sysfs_entry md_raid_disks =
-__ATTR(raid_disks, 0644, raid_disks_show, raid_disks_store);
+__ATTR(raid_disks, S_IRUGO|S_IWUSR, raid_disks_show, raid_disks_store);
static ssize_t
chunk_size_show(mddev_t *mddev, char *page)
@@ -2243,7 +2249,7 @@
return len;
}
static struct md_sysfs_entry md_chunk_size =
-__ATTR(chunk_size, 0644, chunk_size_show, chunk_size_store);
+__ATTR(chunk_size, S_IRUGO|S_IWUSR, chunk_size_show, chunk_size_store);
static ssize_t
resync_start_show(mddev_t *mddev, char *page)
@@ -2267,7 +2273,7 @@
return len;
}
static struct md_sysfs_entry md_resync_start =
-__ATTR(resync_start, 0644, resync_start_show, resync_start_store);
+__ATTR(resync_start, S_IRUGO|S_IWUSR, resync_start_show, resync_start_store);
/*
* The array state can be:
@@ -2437,7 +2443,8 @@
else
return len;
}
-static struct md_sysfs_entry md_array_state = __ATTR(array_state, 0644, array_state_show, array_state_store);
+static struct md_sysfs_entry md_array_state =
+__ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
static ssize_t
null_show(mddev_t *mddev, char *page)
@@ -2497,7 +2504,7 @@
}
static struct md_sysfs_entry md_new_device =
-__ATTR(new_dev, 0200, null_show, new_dev_store);
+__ATTR(new_dev, S_IWUSR, null_show, new_dev_store);
static ssize_t
size_show(mddev_t *mddev, char *page)
@@ -2535,7 +2542,7 @@
}
static struct md_sysfs_entry md_size =
-__ATTR(component_size, 0644, size_show, size_store);
+__ATTR(component_size, S_IRUGO|S_IWUSR, size_show, size_store);
/* Metdata version.
@@ -2583,7 +2590,7 @@
}
static struct md_sysfs_entry md_metadata =
-__ATTR(metadata_version, 0644, metadata_show, metadata_store);
+__ATTR(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
static ssize_t
action_show(mddev_t *mddev, char *page)
@@ -2651,12 +2658,11 @@
(unsigned long long) mddev->resync_mismatches);
}
-static struct md_sysfs_entry
-md_scan_mode = __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
+static struct md_sysfs_entry md_scan_mode =
+__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
-static struct md_sysfs_entry
-md_mismatches = __ATTR_RO(mismatch_cnt);
+static struct md_sysfs_entry md_mismatches = __ATTR_RO(mismatch_cnt);
static ssize_t
sync_min_show(mddev_t *mddev, char *page)
@@ -2715,15 +2721,14 @@
sync_speed_show(mddev_t *mddev, char *page)
{
unsigned long resync, dt, db;
- resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
+ resync = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active));
dt = ((jiffies - mddev->resync_mark) / HZ);
if (!dt) dt++;
db = resync - (mddev->resync_mark_cnt);
return sprintf(page, "%ld\n", db/dt/2); /* K/sec */
}
-static struct md_sysfs_entry
-md_sync_speed = __ATTR_RO(sync_speed);
+static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed);
static ssize_t
sync_completed_show(mddev_t *mddev, char *page)
@@ -2739,8 +2744,7 @@
return sprintf(page, "%lu / %lu\n", resync, max_blocks);
}
-static struct md_sysfs_entry
-md_sync_completed = __ATTR_RO(sync_completed);
+static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
static ssize_t
suspend_lo_show(mddev_t *mddev, char *page)
@@ -2857,6 +2861,8 @@
if (!entry->store)
return -EIO;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
rv = mddev_lock(mddev);
if (!rv) {
rv = entry->store(mddev, page, length);
@@ -3091,7 +3097,6 @@
}
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
- md_wakeup_thread(mddev->thread);
if (mddev->sb_dirty)
md_update_sb(mddev);
@@ -3112,7 +3117,7 @@
* start recovery here. If we leave it to md_check_recovery,
* it will remove the drives and not do the right thing
*/
- if (mddev->degraded) {
+ if (mddev->degraded && !mddev->sync_thread) {
struct list_head *rtmp;
int spares = 0;
ITERATE_RDEV(mddev,rdev,rtmp)
@@ -3133,10 +3138,11 @@
mdname(mddev));
/* leave the spares where they are, it shouldn't hurt */
mddev->recovery = 0;
- } else
- md_wakeup_thread(mddev->sync_thread);
+ }
}
}
+ md_wakeup_thread(mddev->thread);
+ md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
mddev->changed = 1;
md_new_event(mddev);
@@ -4586,6 +4592,8 @@
__builtin_return_address(0),__builtin_return_address(1),
__builtin_return_address(2),__builtin_return_address(3));
*/
+ if (!mddev->pers)
+ return;
if (!mddev->pers->error_handler)
return;
mddev->pers->error_handler(mddev,rdev);
@@ -4683,12 +4691,13 @@
*/
dt = ((jiffies - mddev->resync_mark) / HZ);
if (!dt) dt++;
- db = resync - (mddev->resync_mark_cnt/2);
- rt = (dt * ((unsigned long)(max_blocks-resync) / (db/100+1)))/100;
+ db = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active))
+ - mddev->resync_mark_cnt;
+ rt = (dt * ((unsigned long)(max_blocks-resync) / (db/2/100+1)))/100;
seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
- seq_printf(seq, " speed=%ldK/sec", db/dt);
+ seq_printf(seq, " speed=%ldK/sec", db/2/dt);
}
static void *md_seq_start(struct seq_file *seq, loff_t *pos)
@@ -5199,6 +5208,7 @@
j += sectors;
if (j>1) mddev->curr_resync = j;
+ mddev->curr_mark_cnt = io_sectors;
if (last_check == 0)
/* this is the earliers that rebuilt will be
* visible in /proc/mdstat
@@ -5645,8 +5655,8 @@
return -EINVAL;
}
-module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
-module_param(start_dirty_degraded, int, 0644);
+module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR);
+module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR);
EXPORT_SYMBOL(register_md_personality);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index cead918..1efe22a 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1145,7 +1145,7 @@
long sectors_to_go = r1_bio->sectors;
/* make sure these bits doesn't get cleared. */
do {
- bitmap_end_sync(mddev->bitmap, r1_bio->sector,
+ bitmap_end_sync(mddev->bitmap, s,
&sync_blocks, 1);
s += sync_blocks;
sectors_to_go -= sync_blocks;
@@ -1509,6 +1509,9 @@
s<<9, conf->tmppage, READ) == 0)
/* Well, this device is dead */
md_error(mddev, rdev);
+ else
+ printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n",
+ mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b));
}
}
} else {
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 7f63628..016ddb8 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1492,6 +1492,10 @@
s<<9, conf->tmppage, READ) == 0)
/* Well, this device is dead */
md_error(mddev, rdev);
+ else
+ printk(KERN_INFO "raid10:%s: read error corrected (%d sectors at %llu on %s)\n",
+ mdname(mddev), s, (unsigned long long)(sect+rdev->data_offset), bdevname(rdev->bdev, b));
+
rdev_dec_pending(rdev, mddev);
rcu_read_lock();
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 7433871..4500660 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -18,6 +18,30 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/*
+ * BITMAP UNPLUGGING:
+ *
+ * The sequencing for updating the bitmap reliably is a little
+ * subtle (and I got it wrong the first time) so it deserves some
+ * explanation.
+ *
+ * We group bitmap updates into batches. Each batch has a number.
+ * We may write out several batches at once, but that isn't very important.
+ * conf->bm_write is the number of the last batch successfully written.
+ * conf->bm_flush is the number of the last batch that was closed to
+ * new additions.
+ * When we discover that we will need to write to any block in a stripe
+ * (in add_stripe_bio) we update the in-memory bitmap and record in sh->bm_seq
+ * the number of the batch it will be in. This is bm_flush+1.
+ * When we are ready to do a write, if that batch hasn't been written yet,
+ * we plug the array and queue the stripe for later.
+ * When an unplug happens, we increment bm_flush, thus closing the current
+ * batch.
+ * When we notice that bm_flush > bm_write, we write out all pending updates
+ * to the bitmap, and advance bm_write to where bm_flush was.
+ * This may occasionally write a bit out twice, but is sure never to
+ * miss any bits.
+ */
#include <linux/module.h>
#include <linux/slab.h>
@@ -88,12 +112,14 @@
BUG_ON(!list_empty(&sh->lru));
BUG_ON(atomic_read(&conf->active_stripes)==0);
if (test_bit(STRIPE_HANDLE, &sh->state)) {
- if (test_bit(STRIPE_DELAYED, &sh->state))
+ if (test_bit(STRIPE_DELAYED, &sh->state)) {
list_add_tail(&sh->lru, &conf->delayed_list);
- else if (test_bit(STRIPE_BIT_DELAY, &sh->state) &&
- conf->seq_write == sh->bm_seq)
+ blk_plug_device(conf->mddev->queue);
+ } else if (test_bit(STRIPE_BIT_DELAY, &sh->state) &&
+ sh->bm_seq - conf->seq_write > 0) {
list_add_tail(&sh->lru, &conf->bitmap_list);
- else {
+ blk_plug_device(conf->mddev->queue);
+ } else {
clear_bit(STRIPE_BIT_DELAY, &sh->state);
list_add_tail(&sh->lru, &conf->handle_list);
}
@@ -270,7 +296,7 @@
< (conf->max_nr_stripes *3/4)
|| !conf->inactive_blocked),
conf->device_lock,
- unplug_slaves(conf->mddev)
+ raid5_unplug_device(conf->mddev->queue)
);
conf->inactive_blocked = 0;
} else
@@ -281,7 +307,8 @@
} else {
if (!test_bit(STRIPE_HANDLE, &sh->state))
atomic_inc(&conf->active_stripes);
- if (list_empty(&sh->lru))
+ if (list_empty(&sh->lru) &&
+ !test_bit(STRIPE_EXPANDING, &sh->state))
BUG();
list_del_init(&sh->lru);
}
@@ -496,6 +523,8 @@
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
+ char b[BDEVNAME_SIZE];
+ mdk_rdev_t *rdev;
if (bi->bi_size)
return 1;
@@ -543,25 +572,39 @@
set_bit(R5_UPTODATE, &sh->dev[i].flags);
#endif
if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
- printk(KERN_INFO "raid5: read error corrected!!\n");
+ rdev = conf->disks[i].rdev;
+ printk(KERN_INFO "raid5:%s: read error corrected (%lu sectors at %llu on %s)\n",
+ mdname(conf->mddev), STRIPE_SECTORS,
+ (unsigned long long)sh->sector + rdev->data_offset,
+ bdevname(rdev->bdev, b));
clear_bit(R5_ReadError, &sh->dev[i].flags);
clear_bit(R5_ReWrite, &sh->dev[i].flags);
}
if (atomic_read(&conf->disks[i].rdev->read_errors))
atomic_set(&conf->disks[i].rdev->read_errors, 0);
} else {
+ const char *bdn = bdevname(conf->disks[i].rdev->bdev, b);
int retry = 0;
+ rdev = conf->disks[i].rdev;
+
clear_bit(R5_UPTODATE, &sh->dev[i].flags);
- atomic_inc(&conf->disks[i].rdev->read_errors);
+ atomic_inc(&rdev->read_errors);
if (conf->mddev->degraded)
- printk(KERN_WARNING "raid5: read error not correctable.\n");
+ printk(KERN_WARNING "raid5:%s: read error not correctable (sector %llu on %s).\n",
+ mdname(conf->mddev),
+ (unsigned long long)sh->sector + rdev->data_offset,
+ bdn);
else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
/* Oh, no!!! */
- printk(KERN_WARNING "raid5: read error NOT corrected!!\n");
- else if (atomic_read(&conf->disks[i].rdev->read_errors)
+ printk(KERN_WARNING "raid5:%s: read error NOT corrected!! (sector %llu on %s).\n",
+ mdname(conf->mddev),
+ (unsigned long long)sh->sector + rdev->data_offset,
+ bdn);
+ else if (atomic_read(&rdev->read_errors)
> conf->max_nr_stripes)
printk(KERN_WARNING
- "raid5: Too many read errors, failing device.\n");
+ "raid5:%s: Too many read errors, failing device %s.\n",
+ mdname(conf->mddev), bdn);
else
retry = 1;
if (retry)
@@ -569,7 +612,7 @@
else {
clear_bit(R5_ReadError, &sh->dev[i].flags);
clear_bit(R5_ReWrite, &sh->dev[i].flags);
- md_error(conf->mddev, conf->disks[i].rdev);
+ md_error(conf->mddev, rdev);
}
}
rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
@@ -1270,9 +1313,9 @@
(unsigned long long)sh->sector, dd_idx);
if (conf->mddev->bitmap && firstwrite) {
- sh->bm_seq = conf->seq_write;
bitmap_startwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS, 0);
+ sh->bm_seq = conf->seq_flush+1;
set_bit(STRIPE_BIT_DELAY, &sh->state);
}
@@ -2554,13 +2597,6 @@
return ret;
}
-static inline void raid5_plug_device(raid5_conf_t *conf)
-{
- spin_lock_irq(&conf->device_lock);
- blk_plug_device(conf->mddev->queue);
- spin_unlock_irq(&conf->device_lock);
-}
-
static int make_request(request_queue_t *q, struct bio * bi)
{
mddev_t *mddev = q->queuedata;
@@ -2670,7 +2706,6 @@
goto retry;
}
finish_wait(&conf->wait_for_overlap, &w);
- raid5_plug_device(conf);
handle_stripe(sh, NULL);
release_stripe(sh);
} else {
@@ -2923,7 +2958,7 @@
while (1) {
struct list_head *first;
- if (conf->seq_flush - conf->seq_write > 0) {
+ if (conf->seq_flush != conf->seq_write) {
int seq = conf->seq_flush;
spin_unlock_irq(&conf->device_lock);
bitmap_unplug(mddev->bitmap);
@@ -3246,9 +3281,6 @@
set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
mddev->sync_thread = md_register_thread(md_do_sync, mddev,
"%s_reshape");
- /* FIXME if md_register_thread fails?? */
- md_wakeup_thread(mddev->sync_thread);
-
}
/* read-ahead size must cover two whole stripes, which is
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index 55671cb..87c286e 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -896,9 +896,9 @@
}
ret = nxt2002_load_firmware(fe, fw);
+ release_firmware(fw);
if (ret) {
printk("nxt2002: Writing firmware to device failed\n");
- release_firmware(fw);
return ret;
}
printk("nxt2002: Firmware upload complete\n");
@@ -960,9 +960,9 @@
}
ret = nxt2004_load_firmware(fe, fw);
+ release_firmware(fw);
if (ret) {
printk("nxt2004: Writing firmware to device failed\n");
- release_firmware(fw);
return ret;
}
printk("nxt2004: Firmware upload complete\n");
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 26bed61..2bf124b 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -437,10 +437,10 @@
}
ret = or51211_load_firmware(fe, fw);
+ release_firmware(fw);
if (ret) {
printk(KERN_WARNING "or51211: Writing firmware to "
"device failed!\n");
- release_firmware(fw);
return ret;
}
printk(KERN_INFO "or51211: Firmware upload complete.\n");
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index 44ec5b9..d98fd5c 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -318,7 +318,6 @@
printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
printk("sp8870: no firmware upload (timeout or file not found?)\n");
- release_firmware(fw);
return -EIO;
}
@@ -327,6 +326,7 @@
release_firmware(fw);
return -EIO;
}
+ release_firmware(fw);
printk("sp8870: firmware upload complete\n");
/* enable TS output and interface pins */
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index b0a2b02..5c2f8f4 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -520,9 +520,9 @@
}
ret = sp887x_initial_setup(fe, fw);
+ release_firmware(fw);
if (ret) {
printk("sp887x: writing firmware to device failed\n");
- release_firmware(fw);
return ret;
}
printk("sp887x: firmware upload complete\n");
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 349632b..b60177f 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -453,11 +453,13 @@
if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
+ release_firmware(firmware);
return -1;
}
if (0 != memcmp(firmware->data, magic, 8)) {
dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
+ release_firmware(firmware);
return -1;
}
@@ -478,6 +480,7 @@
}
if (checksum) {
dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
+ release_firmware(firmware);
return -1;
}
release_firmware(firmware);
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
index 184974c..dc388a3 100644
--- a/drivers/message/i2o/core.h
+++ b/drivers/message/i2o/core.h
@@ -38,6 +38,9 @@
extern void i2o_device_remove(struct i2o_device *);
extern int i2o_device_parse_lct(struct i2o_controller *);
+int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
+ int oplen, void *reslist, int reslen);
+
/* IOP */
extern struct i2o_controller *i2o_iop_alloc(void);
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 89daf67..7d23e08 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -36,9 +36,9 @@
#include <asm/uaccess.h>
-#define SG_TABLESIZE 30
+#include "core.h"
-extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
+#define SG_TABLESIZE 30
static int i2o_cfg_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 0641f54..889f338 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -122,6 +122,12 @@
static LIST_HEAD(bpq_devices);
+/*
+ * bpqether network devices are paired with ethernet devices below them, so
+ * form a special "super class" of normal ethernet devices; split their locks
+ * off into a separate class since they always nest.
+ */
+static struct lock_class_key bpq_netdev_xmit_lock_key;
/* ------------------------------------------------------------------------ */
@@ -528,6 +534,7 @@
err = register_netdevice(ndev);
if (err)
goto error;
+ lockdep_set_class(&ndev->_xmit_lock, &bpq_netdev_xmit_lock_key);
/* List protected by RTNL */
list_add_rcu(&bpq->bpq_list, &bpq_devices);
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 1546527..7f78b78 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -34,8 +34,6 @@
#include "orinoco.h"
-static unsigned char *primsym;
-static unsigned char *secsym;
static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
@@ -440,7 +438,7 @@
*/
static int
spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
- const unsigned char *image)
+ const unsigned char *image, int secondary)
{
int ret;
const unsigned char *ptr;
@@ -455,7 +453,7 @@
first_block = (const struct dblock *) ptr;
/* Read the PDA */
- if (image != primsym) {
+ if (secondary) {
ret = spectrum_read_pda(hw, pda, sizeof(pda));
if (ret)
return ret;
@@ -472,7 +470,7 @@
return ret;
/* Write the PDA to the adapter */
- if (image != primsym) {
+ if (secondary) {
ret = spectrum_apply_pda(hw, first_block, pda);
if (ret)
return ret;
@@ -487,7 +485,7 @@
ret = hermes_init(hw);
/* hermes_reset() should return 0 with the secondary firmware */
- if (image != primsym && ret != 0)
+ if (secondary && ret != 0)
return -ENODEV;
/* And this should work with any firmware */
@@ -509,33 +507,30 @@
const struct firmware *fw_entry;
if (request_firmware(&fw_entry, primary_fw_name,
- &handle_to_dev(link)) == 0) {
- primsym = fw_entry->data;
- } else {
+ &handle_to_dev(link)) != 0) {
printk(KERN_ERR PFX "Cannot find firmware: %s\n",
primary_fw_name);
return -ENOENT;
}
- if (request_firmware(&fw_entry, secondary_fw_name,
- &handle_to_dev(link)) == 0) {
- secsym = fw_entry->data;
- } else {
- printk(KERN_ERR PFX "Cannot find firmware: %s\n",
- secondary_fw_name);
- return -ENOENT;
- }
-
/* Load primary firmware */
- ret = spectrum_dl_image(hw, link, primsym);
+ ret = spectrum_dl_image(hw, link, fw_entry->data, 0);
+ release_firmware(fw_entry);
if (ret) {
printk(KERN_ERR PFX "Primary firmware download failed\n");
return ret;
}
- /* Load secondary firmware */
- ret = spectrum_dl_image(hw, link, secsym);
+ if (request_firmware(&fw_entry, secondary_fw_name,
+ &handle_to_dev(link)) != 0) {
+ printk(KERN_ERR PFX "Cannot find firmware: %s\n",
+ secondary_fw_name);
+ return -ENOENT;
+ }
+ /* Load secondary firmware */
+ ret = spectrum_dl_image(hw, link, fw_entry->data, 1);
+ release_firmware(fw_entry);
if (ret) {
printk(KERN_ERR PFX "Secondary firmware download failed\n");
}
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 222a1cc..3fae77f 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -6,8 +6,7 @@
config HOTPLUG_PCI
tristate "Support for PCI Hotplug (EXPERIMENTAL)"
- depends on PCI && EXPERIMENTAL
- select HOTPLUG
+ depends on PCI && EXPERIMENTAL && HOTPLUG
---help---
Say Y here if you have a motherboard with a PCI Hotplug controller.
This allows you to add and remove PCI cards while the machine is
@@ -77,7 +76,7 @@
config HOTPLUG_PCI_ACPI
tristate "ACPI PCI Hotplug driver"
- depends on ACPI && HOTPLUG_PCI
+ depends on ACPI_DOCK && HOTPLUG_PCI
help
Say Y here if you have a system that supports PCI Hotplug using
ACPI.
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index f89dbc3..c5a58d1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -815,6 +815,7 @@
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
dev->cfg_size = pci_cfg_space_size(dev);
+ dev->error_state = pci_channel_io_normal;
/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
set this higher, assuming the system even supports it. */
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 61cb4b2..35f8864 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -6,7 +6,7 @@
config PCCARD
tristate "PCCard (PCMCIA/CardBus) support"
- select HOTPLUG
+ depends on HOTPLUG
---help---
Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
computer. These are credit-card size devices such as network cards,
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 23d53bf..95f4e10 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -529,7 +529,7 @@
printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__);
#endif
CLAW_DBF_TEXT(4,trace,"open");
- if (!dev | (dev->name[0] == 0x00)) {
+ if (!dev || (dev->name[0] == 0x00)) {
CLAW_DBF_TEXT(2,trace,"BadDev");
printk(KERN_WARNING "claw: Bad device at open failing \n");
return -ENODEV;
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index b452cc1..5d6e6cb 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -2029,7 +2029,7 @@
count = IFNAMSIZ-1;
for (i=0, p=(char *)buf; i<count && *p; i++, p++) {
- if ((*p == '\n') | (*p == ' ')) {
+ if ((*p == '\n') || (*p == ' ')) {
/* trailing lf, grr */
break;
} else {
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 329e12c..4caced2 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -4420,8 +4420,10 @@
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
struct qeth_eddp_context *ctx = NULL;
int tx_bytes = skb->len;
+#ifdef CONFIG_QETH_PERF_STATS
unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
unsigned short tso_size = skb_shinfo(skb)->gso_size;
+#endif
int rc;
QETH_DBF_TEXT(trace, 6, "sendpkt");
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 9e871de..601340d 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -93,7 +93,6 @@
#endif
/********************************** Misc Macros *******************************/
-#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
#define powerof2(x) ((((x)-1)&(x))==0)
/************************* Forward Declarations *******************************/
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index eb7188b..d6acc92 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -180,7 +180,7 @@
if (timeleft <= 0) {
US_DEBUGP("%s -- cancelling URB\n",
timeleft == 0 ? "Timeout" : "Signal");
- usb_unlink_urb(us->current_urb);
+ usb_kill_urb(us->current_urb);
}
/* return the URB status */
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 78488bb..0dda73d 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -32,7 +32,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index e714e84..afd146f 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -28,7 +28,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index f9bc9f7..f1ba54f 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -45,7 +45,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index fd95c2d..70dd811 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -39,7 +39,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index eaeaf4d..1fd22f4 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -34,7 +34,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index e69ab65..5831893 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -53,7 +53,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 72c5891..c64a717 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -52,7 +52,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
@@ -456,6 +455,7 @@
static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
static void wait_for_idle(struct aty128fb_par *par);
static u32 depth_to_dst(u32 depth);
+static void aty128_bl_set_power(struct fb_info *info, int power);
#define BIOS_IN8(v) (readb(bios + (v)))
#define BIOS_IN16(v) (readb(bios + (v)) | \
@@ -1258,25 +1258,11 @@
reg &= ~LVDS_DISPLAY_DIS;
aty_st_le32(LVDS_GEN_CNTL, reg);
#ifdef CONFIG_FB_ATY128_BACKLIGHT
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
+ aty128_bl_set_power(info, FB_BLANK_UNBLANK);
#endif
} else {
#ifdef CONFIG_FB_ATY128_BACKLIGHT
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->brightness = 0;
- info->bl_dev->props->power = FB_BLANK_POWERDOWN;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
+ aty128_bl_set_power(info, FB_BLANK_POWERDOWN);
#endif
reg = aty_ld_le32(LVDS_GEN_CNTL);
reg |= LVDS_DISPLAY_DIS;
@@ -1703,6 +1689,7 @@
static struct backlight_properties aty128_bl_data;
+/* Call with fb_info->bl_mutex held */
static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
int level)
{
@@ -1710,10 +1697,8 @@
int atylevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
atylevel = MAX_LEVEL -
(info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
- mutex_unlock(&info->bl_mutex);
if (atylevel < 0)
atylevel = 0;
@@ -1731,7 +1716,8 @@
/* That one prevents proper CRT output with LCD off */
#undef BACKLIGHT_DAC_OFF
-static int aty128_bl_update_status(struct backlight_device *bd)
+/* Call with fb_info->bl_mutex held */
+static int __aty128_bl_update_status(struct backlight_device *bd)
{
struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
@@ -1784,6 +1770,19 @@
return 0;
}
+static int aty128_bl_update_status(struct backlight_device *bd)
+{
+ struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
+ struct fb_info *info = pci_get_drvdata(par->pdev);
+ int ret;
+
+ mutex_lock(&info->bl_mutex);
+ ret = __aty128_bl_update_status(bd);
+ mutex_unlock(&info->bl_mutex);
+
+ return ret;
+}
+
static int aty128_bl_get_brightness(struct backlight_device *bd)
{
return bd->props->brightness;
@@ -1796,6 +1795,16 @@
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
+static void aty128_bl_set_power(struct fb_info *info, int power)
+{
+ mutex_lock(&info->bl_mutex);
+ up(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __aty128_bl_update_status(info->bl_dev);
+ down(&info->bl_dev->sem);
+ mutex_unlock(&info->bl_mutex);
+}
+
static void aty128_bl_init(struct aty128fb_par *par)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -2198,12 +2207,8 @@
return 0;
#ifdef CONFIG_FB_ATY128_BACKLIGHT
- if (machine_is(powermac) && blank) {
- down(&fb->bl_dev->sem);
- fb->bl_dev->props->power = FB_BLANK_POWERDOWN;
- fb->bl_dev->props->update_status(fb->bl_dev);
- up(&fb->bl_dev->sem);
- }
+ if (machine_is(powermac) && blank)
+ aty128_bl_set_power(fb, FB_BLANK_POWERDOWN);
#endif
if (blank & FB_BLANK_VSYNC_SUSPEND)
@@ -2219,14 +2224,12 @@
aty128_set_crt_enable(par, par->crt_on && !blank);
aty128_set_lcd_enable(par, par->lcd_on && !blank);
}
+
#ifdef CONFIG_FB_ATY128_BACKLIGHT
- if (machine_is(powermac) && !blank) {
- down(&fb->bl_dev->sem);
- fb->bl_dev->props->power = FB_BLANK_UNBLANK;
- fb->bl_dev->props->update_status(fb->bl_dev);
- up(&fb->bl_dev->sem);
- }
+ if (machine_is(powermac) && !blank)
+ aty128_bl_set_power(fb, FB_BLANK_UNBLANK);
#endif
+
return 0;
}
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 0c97067..1507d19 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2129,15 +2129,14 @@
static struct backlight_properties aty_bl_data;
+/* Call with fb_info->bl_mutex held */
static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
int atylevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
- mutex_unlock(&info->bl_mutex);
if (atylevel < 0)
atylevel = 0;
@@ -2147,7 +2146,8 @@
return atylevel;
}
-static int aty_bl_update_status(struct backlight_device *bd)
+/* Call with fb_info->bl_mutex held */
+static int __aty_bl_update_status(struct backlight_device *bd)
{
struct atyfb_par *par = class_get_devdata(&bd->class_dev);
unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
@@ -2172,6 +2172,19 @@
return 0;
}
+static int aty_bl_update_status(struct backlight_device *bd)
+{
+ struct atyfb_par *par = class_get_devdata(&bd->class_dev);
+ struct fb_info *info = pci_get_drvdata(par->pdev);
+ int ret;
+
+ mutex_lock(&info->bl_mutex);
+ ret = __aty_bl_update_status(bd);
+ mutex_unlock(&info->bl_mutex);
+
+ return ret;
+}
+
static int aty_bl_get_brightness(struct backlight_device *bd)
{
return bd->props->brightness;
@@ -2184,6 +2197,16 @@
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
+static void aty_bl_set_power(struct fb_info *info, int power)
+{
+ mutex_lock(&info->bl_mutex);
+ up(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __aty_bl_update_status(info->bl_dev);
+ down(&info->bl_dev->sem);
+ mutex_unlock(&info->bl_mutex);
+}
+
static void aty_bl_init(struct atyfb_par *par)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -2790,16 +2813,8 @@
return 0;
#ifdef CONFIG_PMAC_BACKLIGHT
- if (machine_is(powermac) && blank > FB_BLANK_NORMAL) {
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = FB_BLANK_POWERDOWN;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
- }
+ if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
+ aty_bl_set_power(info, FB_BLANK_POWERDOWN);
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
if (par->lcd_table && blank > FB_BLANK_NORMAL &&
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
@@ -2830,16 +2845,8 @@
aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
#ifdef CONFIG_PMAC_BACKLIGHT
- if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) {
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = FB_BLANK_UNBLANK;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
- }
+ if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
+ aty_bl_set_power(info, FB_BLANK_UNBLANK);
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 51b78f8..8d85fc5 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -58,7 +58,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/time.h>
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 0e465c8..73cb426 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -19,7 +19,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
@@ -150,12 +149,11 @@
mutex_lock(&pmac_backlight_mutex);
if (pmac_backlight) {
- down(&pmac_backlight->sem);
-
/* used to disable backlight only for blank > 1, but it seems
* useful at blank = 1 too (saves battery, extends backlight
* life)
*/
+ down(&pmac_backlight->sem);
if (blank)
pmac_backlight->props->power = FB_BLANK_POWERDOWN;
else
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 7355da09..daf43f5 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -41,7 +41,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index 878707a..d9315d9 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -7,9 +7,9 @@
#include <linux/types.h>
#include <linux/kdev_t.h>
-#include <linux/tty.h>
#include <linux/console.h>
#include <linux/vt_kern.h>
+#include <linux/screen_info.h>
#include <linux/init.h>
#include <linux/module.h>
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 94e9f70..390439b 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -64,7 +64,6 @@
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/delay.h> /* MSch: for IRQ probe */
-#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/kd.h>
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index c89f90ed..52ed12b 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -31,7 +31,6 @@
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/kd.h>
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 0304131..7fa1afe 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/tty.h>
#include <linux/kd.h>
#include <linux/selection.h>
#include <linux/console.h>
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
index 5cd5e11..b78eac6 100644
--- a/drivers/video/console/promcon.c
+++ b/drivers/video/console/promcon.c
@@ -10,7 +10,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/console.h>
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 3957fc7..557c563 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -10,7 +10,6 @@
#include <linux/module.h>
#include <linux/string.h>
-#include <linux/tty.h>
#include <linux/fb.h>
#include <linux/slab.h>
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 45c4f22..45586aa 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -37,7 +37,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/tty.h>
#include <linux/console.h>
#include <linux/errno.h>
#include <linux/vt_kern.h>
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 05735ff..0a2c10a 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -38,7 +38,6 @@
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/kernel.h>
-#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/kd.h>
@@ -48,6 +47,7 @@
#include <linux/spinlock.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/screen_info.h>
#include <linux/smp_lock.h>
#include <video/vga.h>
#include <asm/io.h>
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index acdd6a1..8cc6c0e 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -36,7 +36,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 2e29249..aae6d9c 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -41,7 +41,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
index a3e189f..c40e72d 100644
--- a/drivers/video/cyberfb.c
+++ b/drivers/video/cyberfb.c
@@ -81,7 +81,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/zorro.h>
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 5abd3cb..b083ea7 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -2,7 +2,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index f0a621e..737257d 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -48,7 +48,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 1f98392..e8b135f 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -13,7 +13,6 @@
#include <linux/string.h>
#include <linux/module.h>
-#include <linux/tty.h>
#include <linux/fb.h>
#include <linux/slab.h>
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 33034f8..4fc9df4 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -23,7 +23,7 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/mman.h>
-#include <linux/tty.h>
+#include <linux/vt.h>
#include <linux/init.h>
#include <linux/linux_logo.h>
#include <linux/proc_fs.h>
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 3ccfff7..de93139 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -26,7 +26,6 @@
* for more details.
*
*/
-#include <linux/tty.h>
#include <linux/fb.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c
index 605d1a1..1b981b6 100644
--- a/drivers/video/g364fb.c
+++ b/drivers/video/g364fb.c
@@ -21,7 +21,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 4d3a887..bcf9cea 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -15,7 +15,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 5ef12a3..0d3643f 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -25,7 +25,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c
index 4e39035..fb9e672 100644
--- a/drivers/video/hgafb.c
+++ b/drivers/video/hgafb.c
@@ -36,7 +36,6 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 0186476..4cc6b45 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index abd920a..91cf3b5 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -11,7 +11,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index fbe8a2c..a6ca02f 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -33,7 +33,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/init.h>
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index 8a0c2d3..67f384f 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -33,7 +33,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c
index cdbae17..ff233b8 100644
--- a/drivers/video/imacfb.c
+++ b/drivers/video/imacfb.c
@@ -15,9 +15,9 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/screen_info.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <linux/tty.h>
#include <asm/io.h>
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 5f393d9..5715b8a 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -21,7 +21,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 3f39d84..06af89d 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -113,7 +113,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
@@ -122,6 +121,7 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
+#include <linux/screen_info.h>
#include <asm/io.h>
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 3b78a57..2a9322f 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -24,7 +24,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index 2fdbe9b..f0d614a 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/ioctl.h>
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index e6cbd9d..80a0438 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -24,7 +24,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/nubus.h>
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index b95779b..9c25c2f 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -30,7 +30,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
index f85421b..38c8d38 100644
--- a/drivers/video/maxinefb.c
+++ b/drivers/video/maxinefb.c
@@ -29,7 +29,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index ff54546..d126790 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -12,7 +12,6 @@
*/
#include <linux/module.h>
-#include <linux/tty.h>
#include <linux/fb.h>
#include <linux/sched.h>
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 773855a..59a6f5f 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -59,7 +59,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index 1c1c10c..b45f577 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -26,9 +26,11 @@
*/
#define MIN_LEVEL 0x158
#define MAX_LEVEL 0x534
+#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
static struct backlight_properties nvidia_bl_data;
+/* Call with fb_info->bl_mutex held */
static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
int level)
{
@@ -36,9 +38,7 @@
int nlevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
- nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
- mutex_unlock(&info->bl_mutex);
+ nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
if (nlevel < 0)
nlevel = 0;
@@ -50,7 +50,8 @@
return nlevel;
}
-static int nvidia_bl_update_status(struct backlight_device *bd)
+/* Call with fb_info->bl_mutex held */
+static int __nvidia_bl_update_status(struct backlight_device *bd)
{
struct nvidia_par *par = class_get_devdata(&bd->class_dev);
u32 tmp_pcrt, tmp_pmc, fpcontrol;
@@ -84,6 +85,19 @@
return 0;
}
+static int nvidia_bl_update_status(struct backlight_device *bd)
+{
+ struct nvidia_par *par = class_get_devdata(&bd->class_dev);
+ struct fb_info *info = pci_get_drvdata(par->pci_dev);
+ int ret;
+
+ mutex_lock(&info->bl_mutex);
+ ret = __nvidia_bl_update_status(bd);
+ mutex_unlock(&info->bl_mutex);
+
+ return ret;
+}
+
static int nvidia_bl_get_brightness(struct backlight_device *bd)
{
return bd->props->brightness;
@@ -96,6 +110,16 @@
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
+void nvidia_bl_set_power(struct fb_info *info, int power)
+{
+ mutex_lock(&info->bl_mutex);
+ up(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __nvidia_bl_update_status(info->bl_dev);
+ down(&info->bl_dev->sem);
+ mutex_unlock(&info->bl_mutex);
+}
+
void nvidia_bl_init(struct nvidia_par *par)
{
struct fb_info *info = pci_get_drvdata(par->pci_dev);
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 6fba656..8612710 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -68,9 +68,11 @@
#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
extern void nvidia_bl_init(struct nvidia_par *par);
extern void nvidia_bl_exit(struct nvidia_par *par);
+extern void nvidia_bl_set_power(struct fb_info *info, int power);
#else
static inline void nvidia_bl_init(struct nvidia_par *par) {}
static inline void nvidia_bl_exit(struct nvidia_par *par) {}
+static inline void nvidia_bl_set_power(struct fb_info *info, int power) {}
#endif
#endif /* __NV_PROTO_H__ */
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index b02d603..9f2066f 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -14,7 +14,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
@@ -933,16 +932,7 @@
NVWriteSeq(par, 0x01, tmp);
NVWriteCrtc(par, 0x1a, vesa);
-#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = blank;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
-#endif
+ nvidia_bl_set_power(info, blank);
NVTRACE_LEAVE();
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 71ce1fa..ce5f303 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 450e802..983be3e 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -22,7 +22,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 49a203e..a560a22 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -33,7 +33,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 0e0f977..1d81ef4 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -57,7 +57,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/pmag-aa-fb.c
index d92f352..68ca3cc 100644
--- a/drivers/video/pmag-aa-fb.c
+++ b/drivers/video/pmag-aa-fb.c
@@ -29,7 +29,6 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 4a1e0e8..940ba2b 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -53,7 +53,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index fc91dbf..48536c3 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -14,7 +14,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
index 5e2c64f..cf41ff1 100644
--- a/drivers/video/retz3fb.c
+++ b/drivers/video/retz3fb.c
@@ -25,7 +25,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 2788655..33dddba 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -34,7 +34,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
@@ -278,9 +277,11 @@
*/
#define MIN_LEVEL 0x158
#define MAX_LEVEL 0x534
+#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
static struct backlight_properties riva_bl_data;
+/* Call with fb_info->bl_mutex held */
static int riva_bl_get_level_brightness(struct riva_par *par,
int level)
{
@@ -288,9 +289,7 @@
int nlevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
- nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
- mutex_unlock(&info->bl_mutex);
+ nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
if (nlevel < 0)
nlevel = 0;
@@ -302,7 +301,8 @@
return nlevel;
}
-static int riva_bl_update_status(struct backlight_device *bd)
+/* Call with fb_info->bl_mutex held */
+static int __riva_bl_update_status(struct backlight_device *bd)
{
struct riva_par *par = class_get_devdata(&bd->class_dev);
U032 tmp_pcrt, tmp_pmc;
@@ -327,6 +327,19 @@
return 0;
}
+static int riva_bl_update_status(struct backlight_device *bd)
+{
+ struct riva_par *par = class_get_devdata(&bd->class_dev);
+ struct fb_info *info = pci_get_drvdata(par->pdev);
+ int ret;
+
+ mutex_lock(&info->bl_mutex);
+ ret = __riva_bl_update_status(bd);
+ mutex_unlock(&info->bl_mutex);
+
+ return ret;
+}
+
static int riva_bl_get_brightness(struct backlight_device *bd)
{
return bd->props->brightness;
@@ -339,6 +352,16 @@
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
+static void riva_bl_set_power(struct fb_info *info, int power)
+{
+ mutex_lock(&info->bl_mutex);
+ up(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __riva_bl_update_status(info->bl_dev);
+ down(&info->bl_dev->sem);
+ mutex_unlock(&info->bl_mutex);
+}
+
static void riva_bl_init(struct riva_par *par)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -419,6 +442,7 @@
#else
static inline void riva_bl_init(struct riva_par *par) {}
static inline void riva_bl_exit(struct riva_par *par) {}
+static inline void riva_bl_set_power(struct fb_info *info, int power) {}
#endif /* CONFIG_FB_RIVA_BACKLIGHT */
/* ------------------------------------------------------------------------- *
@@ -1337,16 +1361,7 @@
SEQout(par, 0x01, tmp);
CRTCout(par, 0x1a, vesa);
-#ifdef CONFIG_FB_RIVA_BACKLIGHT
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = blank;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
-#endif
+ riva_bl_set_power(info, blank);
NVTRACE_LEAVE();
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index f461eb1..ad3bdd6 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -76,7 +76,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 4729af4..461e094 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -46,7 +46,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index b848ca7..895ebda 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -44,7 +44,13 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
#include <linux/tty.h>
+#else
+#include <linux/screen_info.h>
+#endif
+
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/selection.h>
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 67f429e..bb96cb6 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -47,7 +47,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c
index e046e20..f80356d 100644
--- a/drivers/video/sun3fb.c
+++ b/drivers/video/sun3fb.c
@@ -30,7 +30,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 239b149..689ce02 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -63,7 +63,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 6c2c78a..94fde62 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
index d904da4..07389ba 100644
--- a/drivers/video/tx3912fb.c
+++ b/drivers/video/tx3912fb.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 1d76c03..47f2792 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -44,7 +44,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 5718924..2196448 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -13,13 +13,13 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/screen_info.h>
#include <video/vga.h>
#include <asm/io.h>
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index d073ffb..a9b99b0 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -15,7 +15,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 3c404c9..43d5a6d 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -15,13 +15,13 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/screen_info.h>
#include <asm/io.h>
#include <video/vga.h>
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index 5ea2345..6437895 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -39,7 +39,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/zorro.h>
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index f42e642..672a3b9 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1185,8 +1185,6 @@
return 1;
}
-#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
-
/* An ELF note in memory */
struct memelfnote
{
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index eba4e23..2f33658 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1,6 +1,6 @@
/* binfmt_elf_fdpic.c: FDPIC ELF binary format
*
- * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2003, 2004, 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
* Derived from binfmt_elf.c
*
@@ -24,7 +24,9 @@
#include <linux/file.h>
#include <linux/fcntl.h>
#include <linux/slab.h>
+#include <linux/pagemap.h>
#include <linux/highmem.h>
+#include <linux/highuid.h>
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/init.h>
@@ -48,45 +50,59 @@
#define kdebug(fmt, ...) do {} while(0)
#endif
-MODULE_LICENSE("GPL");
-
-static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs);
-//static int load_elf_fdpic_library(struct file *);
-static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file);
-static int elf_fdpic_map_file(struct elf_fdpic_params *params,
- struct file *file,
- struct mm_struct *mm,
- const char *what);
-
-static int create_elf_fdpic_tables(struct linux_binprm *bprm,
- struct mm_struct *mm,
- struct elf_fdpic_params *exec_params,
- struct elf_fdpic_params *interp_params);
-
-#ifndef CONFIG_MMU
-static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp);
-static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params,
- struct file *file,
- struct mm_struct *mm);
+#if 0
+#define kdcore(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
+#else
+#define kdcore(fmt, ...) do {} while(0)
#endif
-static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
- struct file *file,
- struct mm_struct *mm);
+MODULE_LICENSE("GPL");
+
+static int load_elf_fdpic_binary(struct linux_binprm *, struct pt_regs *);
+static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *, struct file *);
+static int elf_fdpic_map_file(struct elf_fdpic_params *, struct file *,
+ struct mm_struct *, const char *);
+
+static int create_elf_fdpic_tables(struct linux_binprm *, struct mm_struct *,
+ struct elf_fdpic_params *,
+ struct elf_fdpic_params *);
+
+#ifndef CONFIG_MMU
+static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *,
+ unsigned long *);
+static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *,
+ struct file *,
+ struct mm_struct *);
+#endif
+
+static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *,
+ struct file *, struct mm_struct *);
+
+#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
+static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *);
+#endif
static struct linux_binfmt elf_fdpic_format = {
.module = THIS_MODULE,
.load_binary = load_elf_fdpic_binary,
-// .load_shlib = load_elf_fdpic_library,
-// .core_dump = elf_fdpic_core_dump,
+#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
+ .core_dump = elf_fdpic_core_dump,
+#endif
.min_coredump = ELF_EXEC_PAGESIZE,
};
-static int __init init_elf_fdpic_binfmt(void) { return register_binfmt(&elf_fdpic_format); }
-static void __exit exit_elf_fdpic_binfmt(void) { unregister_binfmt(&elf_fdpic_format); }
+static int __init init_elf_fdpic_binfmt(void)
+{
+ return register_binfmt(&elf_fdpic_format);
+}
-module_init(init_elf_fdpic_binfmt)
-module_exit(exit_elf_fdpic_binfmt)
+static void __exit exit_elf_fdpic_binfmt(void)
+{
+ unregister_binfmt(&elf_fdpic_format);
+}
+
+core_initcall(init_elf_fdpic_binfmt);
+module_exit(exit_elf_fdpic_binfmt);
static int is_elf_fdpic(struct elfhdr *hdr, struct file *file)
{
@@ -105,7 +121,8 @@
/*
* read the program headers table into memory
*/
-static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file)
+static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params,
+ struct file *file)
{
struct elf32_phdr *phdr;
unsigned long size;
@@ -121,7 +138,8 @@
if (!params->phdrs)
return -ENOMEM;
- retval = kernel_read(file, params->hdr.e_phoff, (char *) params->phdrs, size);
+ retval = kernel_read(file, params->hdr.e_phoff,
+ (char *) params->phdrs, size);
if (retval < 0)
return retval;
@@ -141,17 +159,24 @@
}
return 0;
-} /* end elf_fdpic_fetch_phdrs() */
+}
/*****************************************************************************/
/*
* load an fdpic binary into various bits of memory
*/
-static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+static int load_elf_fdpic_binary(struct linux_binprm *bprm,
+ struct pt_regs *regs)
{
struct elf_fdpic_params exec_params, interp_params;
struct elf_phdr *phdr;
- unsigned long stack_size;
+ unsigned long stack_size, entryaddr;
+#ifndef CONFIG_MMU
+ unsigned long fullsize;
+#endif
+#ifdef ELF_FDPIC_PLAT_INIT
+ unsigned long dynaddr;
+#endif
struct file *interpreter = NULL; /* to shut gcc up */
char *interpreter_name = NULL;
int executable_stack;
@@ -212,7 +237,8 @@
goto error;
}
- retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE);
+ retval = kernel_read(interpreter, 0, bprm->buf,
+ BINPRM_BUF_SIZE);
if (retval < 0)
goto error;
@@ -295,7 +321,8 @@
¤t->mm->start_stack,
¤t->mm->start_brk);
- retval = setup_arg_pages(bprm, current->mm->start_stack, executable_stack);
+ retval = setup_arg_pages(bprm, current->mm->start_stack,
+ executable_stack);
if (retval < 0) {
send_sig(SIGKILL, current, 0);
goto error_kill;
@@ -303,7 +330,8 @@
#endif
/* load the executable and interpreter into memory */
- retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, "executable");
+ retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm,
+ "executable");
if (retval < 0)
goto error_kill;
@@ -324,7 +352,8 @@
if (!current->mm->start_brk)
current->mm->start_brk = current->mm->end_data;
- current->mm->brk = current->mm->start_brk = PAGE_ALIGN(current->mm->start_brk);
+ current->mm->brk = current->mm->start_brk =
+ PAGE_ALIGN(current->mm->start_brk);
#else
/* create a stack and brk area big enough for everyone
@@ -336,47 +365,45 @@
stack_size = PAGE_SIZE * 2;
down_write(¤t->mm->mmap_sem);
- current->mm->start_brk = do_mmap(NULL,
- 0,
- stack_size,
+ current->mm->start_brk = do_mmap(NULL, 0, stack_size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN,
0);
- if (IS_ERR((void *) current->mm->start_brk)) {
+ if (IS_ERR_VALUE(current->mm->start_brk)) {
up_write(¤t->mm->mmap_sem);
retval = current->mm->start_brk;
current->mm->start_brk = 0;
goto error_kill;
}
- if (do_mremap(current->mm->start_brk,
- stack_size,
- ksize((char *) current->mm->start_brk),
- 0, 0
- ) == current->mm->start_brk
- )
- stack_size = ksize((char *) current->mm->start_brk);
+ /* expand the stack mapping to use up the entire allocation granule */
+ fullsize = ksize((char *) current->mm->start_brk);
+ if (!IS_ERR_VALUE(do_mremap(current->mm->start_brk, stack_size,
+ fullsize, 0, 0)))
+ stack_size = fullsize;
up_write(¤t->mm->mmap_sem);
current->mm->brk = current->mm->start_brk;
current->mm->context.end_brk = current->mm->start_brk;
- current->mm->context.end_brk += (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
+ current->mm->context.end_brk +=
+ (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
current->mm->start_stack = current->mm->start_brk + stack_size;
#endif
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
- if (create_elf_fdpic_tables(bprm, current->mm, &exec_params, &interp_params) < 0)
+ if (create_elf_fdpic_tables(bprm, current->mm,
+ &exec_params, &interp_params) < 0)
goto error_kill;
- kdebug("- start_code %lx", (long) current->mm->start_code);
- kdebug("- end_code %lx", (long) current->mm->end_code);
- kdebug("- start_data %lx", (long) current->mm->start_data);
- kdebug("- end_data %lx", (long) current->mm->end_data);
- kdebug("- start_brk %lx", (long) current->mm->start_brk);
- kdebug("- brk %lx", (long) current->mm->brk);
- kdebug("- start_stack %lx", (long) current->mm->start_stack);
+ kdebug("- start_code %lx", current->mm->start_code);
+ kdebug("- end_code %lx", current->mm->end_code);
+ kdebug("- start_data %lx", current->mm->start_data);
+ kdebug("- end_data %lx", current->mm->end_data);
+ kdebug("- start_brk %lx", current->mm->start_brk);
+ kdebug("- brk %lx", current->mm->brk);
+ kdebug("- start_stack %lx", current->mm->start_stack);
#ifdef ELF_FDPIC_PLAT_INIT
/*
@@ -385,21 +412,18 @@
* example. This macro performs whatever initialization to
* the regs structure is required.
*/
- ELF_FDPIC_PLAT_INIT(regs,
- exec_params.map_addr,
- interp_params.map_addr,
- interp_params.dynamic_addr ?: exec_params.dynamic_addr
- );
+ dynaddr = interp_params.dynamic_addr ?: exec_params.dynamic_addr;
+ ELF_FDPIC_PLAT_INIT(regs, exec_params.map_addr, interp_params.map_addr,
+ dynaddr);
#endif
/* everything is now ready... get the userspace context ready to roll */
- start_thread(regs,
- interp_params.entry_addr ?: exec_params.entry_addr,
- current->mm->start_stack);
+ entryaddr = interp_params.entry_addr ?: exec_params.entry_addr;
+ start_thread(regs, entryaddr, current->mm->start_stack);
if (unlikely(current->ptrace & PT_PTRACED)) {
if (current->ptrace & PT_TRACE_EXEC)
- ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
+ ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
else
send_sig(SIGTRAP, current, 0);
}
@@ -419,11 +443,11 @@
return retval;
/* unrecoverable error - kill the process */
- error_kill:
+error_kill:
send_sig(SIGSEGV, current, 0);
goto error;
-} /* end load_elf_fdpic_binary() */
+}
/*****************************************************************************/
/*
@@ -459,6 +483,7 @@
*/
hwcap = ELF_HWCAP;
k_platform = ELF_PLATFORM;
+ u_platform = NULL;
if (k_platform) {
platform_len = strlen(k_platform) + 1;
@@ -470,11 +495,11 @@
#if defined(__i386__) && defined(CONFIG_SMP)
/* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
- * by the processes running on the same package. One thing we can do
- * is to shuffle the initial stack for them.
+ * by the processes running on the same package. One thing we can do is
+ * to shuffle the initial stack for them.
*
- * the conditionals here are unneeded, but kept in to make the
- * code behaviour the same as pre change unless we have hyperthreaded
+ * the conditionals here are unneeded, but kept in to make the code
+ * behaviour the same as pre change unless we have hyperthreaded
* processors. This keeps Mr Marcelo Person happier but should be
* removed for 2.5
*/
@@ -497,11 +522,13 @@
if (interp_params->loadmap) {
len = sizeof(struct elf32_fdpic_loadmap);
- len += sizeof(struct elf32_fdpic_loadseg) * interp_params->loadmap->nsegs;
+ len += sizeof(struct elf32_fdpic_loadseg) *
+ interp_params->loadmap->nsegs;
sp = (sp - len) & ~7UL;
interp_params->map_addr = sp;
- if (copy_to_user((void __user *) sp, interp_params->loadmap, len) != 0)
+ if (copy_to_user((void __user *) sp, interp_params->loadmap,
+ len) != 0)
return -EFAULT;
current->mm->context.interp_fdpic_loadmap = (unsigned long) sp;
@@ -525,34 +552,37 @@
sp -= sp & 15UL;
/* put the ELF interpreter info on the stack */
-#define NEW_AUX_ENT(nr, id, val) \
- do { \
- struct { unsigned long _id, _val; } __user *ent = (void __user *) csp; \
- __put_user((id), &ent[nr]._id); \
- __put_user((val), &ent[nr]._val); \
+#define NEW_AUX_ENT(nr, id, val) \
+ do { \
+ struct { unsigned long _id, _val; } __user *ent; \
+ \
+ ent = (void __user *) csp; \
+ __put_user((id), &ent[nr]._id); \
+ __put_user((val), &ent[nr]._val); \
} while (0)
csp -= 2 * sizeof(unsigned long);
NEW_AUX_ENT(0, AT_NULL, 0);
if (k_platform) {
csp -= 2 * sizeof(unsigned long);
- NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
+ NEW_AUX_ENT(0, AT_PLATFORM,
+ (elf_addr_t) (unsigned long) u_platform);
}
csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
- NEW_AUX_ENT( 0, AT_HWCAP, hwcap);
- NEW_AUX_ENT( 1, AT_PAGESZ, PAGE_SIZE);
- NEW_AUX_ENT( 2, AT_CLKTCK, CLOCKS_PER_SEC);
- NEW_AUX_ENT( 3, AT_PHDR, exec_params->ph_addr);
- NEW_AUX_ENT( 4, AT_PHENT, sizeof(struct elf_phdr));
- NEW_AUX_ENT( 5, AT_PHNUM, exec_params->hdr.e_phnum);
- NEW_AUX_ENT( 6, AT_BASE, interp_params->elfhdr_addr);
- NEW_AUX_ENT( 7, AT_FLAGS, 0);
- NEW_AUX_ENT( 8, AT_ENTRY, exec_params->entry_addr);
- NEW_AUX_ENT( 9, AT_UID, (elf_addr_t) current->uid);
- NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid);
- NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid);
- NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid);
+ NEW_AUX_ENT( 0, AT_HWCAP, hwcap);
+ NEW_AUX_ENT( 1, AT_PAGESZ, PAGE_SIZE);
+ NEW_AUX_ENT( 2, AT_CLKTCK, CLOCKS_PER_SEC);
+ NEW_AUX_ENT( 3, AT_PHDR, exec_params->ph_addr);
+ NEW_AUX_ENT( 4, AT_PHENT, sizeof(struct elf_phdr));
+ NEW_AUX_ENT( 5, AT_PHNUM, exec_params->hdr.e_phnum);
+ NEW_AUX_ENT( 6, AT_BASE, interp_params->elfhdr_addr);
+ NEW_AUX_ENT( 7, AT_FLAGS, 0);
+ NEW_AUX_ENT( 8, AT_ENTRY, exec_params->entry_addr);
+ NEW_AUX_ENT( 9, AT_UID, (elf_addr_t) current->uid);
+ NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid);
+ NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid);
+ NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid);
#ifdef ARCH_DLINFO
/* ARCH_DLINFO must come last so platform specific code can enforce
@@ -578,7 +608,8 @@
#ifdef CONFIG_MMU
current->mm->arg_start = bprm->p;
#else
- current->mm->arg_start = current->mm->start_stack - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p);
+ current->mm->arg_start = current->mm->start_stack -
+ (MAX_ARG_PAGES * PAGE_SIZE - bprm->p);
#endif
p = (char __user *) current->mm->arg_start;
@@ -606,7 +637,7 @@
mm->start_stack = (unsigned long) sp;
return 0;
-} /* end create_elf_fdpic_tables() */
+}
/*****************************************************************************/
/*
@@ -614,7 +645,8 @@
* the stack
*/
#ifndef CONFIG_MMU
-static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp)
+static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm,
+ unsigned long *_sp)
{
unsigned long index, stop, sp;
char *src;
@@ -635,9 +667,9 @@
*_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15;
- out:
+out:
return ret;
-} /* end elf_fdpic_transfer_args_to_stack() */
+}
#endif
/*****************************************************************************/
@@ -712,17 +744,18 @@
seg = loadmap->segs;
for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
if (params->hdr.e_entry >= seg->p_vaddr &&
- params->hdr.e_entry < seg->p_vaddr + seg->p_memsz
- ) {
+ params->hdr.e_entry < seg->p_vaddr + seg->p_memsz) {
params->entry_addr =
- (params->hdr.e_entry - seg->p_vaddr) + seg->addr;
+ (params->hdr.e_entry - seg->p_vaddr) +
+ seg->addr;
break;
}
}
}
/* determine where the program header table has wound up if mapped */
- stop = params->hdr.e_phoff + params->hdr.e_phnum * sizeof (struct elf_phdr);
+ stop = params->hdr.e_phoff;
+ stop += params->hdr.e_phnum * sizeof (struct elf_phdr);
phdr = params->phdrs;
for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
@@ -736,9 +769,11 @@
seg = loadmap->segs;
for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
if (phdr->p_vaddr >= seg->p_vaddr &&
- phdr->p_vaddr + phdr->p_filesz <= seg->p_vaddr + seg->p_memsz
- ) {
- params->ph_addr = (phdr->p_vaddr - seg->p_vaddr) + seg->addr +
+ phdr->p_vaddr + phdr->p_filesz <=
+ seg->p_vaddr + seg->p_memsz) {
+ params->ph_addr =
+ (phdr->p_vaddr - seg->p_vaddr) +
+ seg->addr +
params->hdr.e_phoff - phdr->p_offset;
break;
}
@@ -755,18 +790,22 @@
seg = loadmap->segs;
for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
if (phdr->p_vaddr >= seg->p_vaddr &&
- phdr->p_vaddr + phdr->p_memsz <= seg->p_vaddr + seg->p_memsz
- ) {
- params->dynamic_addr = (phdr->p_vaddr - seg->p_vaddr) + seg->addr;
+ phdr->p_vaddr + phdr->p_memsz <=
+ seg->p_vaddr + seg->p_memsz) {
+ params->dynamic_addr =
+ (phdr->p_vaddr - seg->p_vaddr) +
+ seg->addr;
- /* check the dynamic section contains at least one item, and that
- * the last item is a NULL entry */
+ /* check the dynamic section contains at least
+ * one item, and that the last item is a NULL
+ * entry */
if (phdr->p_memsz == 0 ||
phdr->p_memsz % sizeof(Elf32_Dyn) != 0)
goto dynamic_error;
tmp = phdr->p_memsz / sizeof(Elf32_Dyn);
- if (((Elf32_Dyn *) params->dynamic_addr)[tmp - 1].d_tag != 0)
+ if (((Elf32_Dyn *)
+ params->dynamic_addr)[tmp - 1].d_tag != 0)
goto dynamic_error;
break;
}
@@ -775,8 +814,8 @@
}
/* now elide adjacent segments in the load map on MMU linux
- * - on uClinux the holes between may actually be filled with system stuff or stuff from
- * other processes
+ * - on uClinux the holes between may actually be filled with system
+ * stuff or stuff from other processes
*/
#ifdef CONFIG_MMU
nloads = loadmap->nsegs;
@@ -787,7 +826,9 @@
if (seg->p_vaddr - mseg->p_vaddr == seg->addr - mseg->addr) {
load_addr = PAGE_ALIGN(mseg->addr + mseg->p_memsz);
if (load_addr == (seg->addr & PAGE_MASK)) {
- mseg->p_memsz += load_addr - (mseg->addr + mseg->p_memsz);
+ mseg->p_memsz +=
+ load_addr -
+ (mseg->addr + mseg->p_memsz);
mseg->p_memsz += seg->addr & ~PAGE_MASK;
mseg->p_memsz += seg->p_memsz;
loadmap->nsegs--;
@@ -815,20 +856,21 @@
return 0;
- dynamic_error:
+dynamic_error:
printk("ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n",
what, file->f_dentry->d_inode->i_ino);
return -ELIBBAD;
-} /* end elf_fdpic_map_file() */
+}
/*****************************************************************************/
/*
* map a file with constant displacement under uClinux
*/
#ifndef CONFIG_MMU
-static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params,
- struct file *file,
- struct mm_struct *mm)
+static int elf_fdpic_map_file_constdisp_on_uclinux(
+ struct elf_fdpic_params *params,
+ struct file *file,
+ struct mm_struct *mm)
{
struct elf32_fdpic_loadseg *seg;
struct elf32_phdr *phdr;
@@ -839,7 +881,8 @@
load_addr = params->load_addr;
seg = params->loadmap->segs;
- /* determine the bounds of the contiguous overall allocation we must make */
+ /* determine the bounds of the contiguous overall allocation we must
+ * make */
phdr = params->phdrs;
for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
if (params->phdrs[loop].p_type != PT_LOAD)
@@ -860,7 +903,7 @@
maddr = do_mmap(NULL, load_addr, top - base,
PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
up_write(&mm->mmap_sem);
- if (IS_ERR((void *) maddr))
+ if (IS_ERR_VALUE(maddr))
return (int) maddr;
if (load_addr != 0)
@@ -878,7 +921,8 @@
seg->p_vaddr = phdr->p_vaddr;
seg->p_memsz = phdr->p_memsz;
- ret = file->f_op->read(file, (void *) seg->addr, phdr->p_filesz, &fpos);
+ ret = file->f_op->read(file, (void *) seg->addr,
+ phdr->p_filesz, &fpos);
if (ret < 0)
return ret;
@@ -895,8 +939,7 @@
if (phdr->p_flags & PF_X) {
mm->start_code = seg->addr;
mm->end_code = seg->addr + phdr->p_memsz;
- }
- else if (!mm->start_data) {
+ } else if (!mm->start_data) {
mm->start_data = seg->addr;
#ifndef CONFIG_MMU
mm->end_data = seg->addr + phdr->p_memsz;
@@ -913,7 +956,7 @@
}
return 0;
-} /* end elf_fdpic_map_file_constdisp_on_uclinux() */
+}
#endif
/*****************************************************************************/
@@ -974,14 +1017,14 @@
case ELF_FDPIC_FLAG_CONSTDISP:
/* constant displacement
- * - can be mapped anywhere, but must be mapped as a unit
+ * - can be mapped anywhere, but must be mapped as a
+ * unit
*/
if (!dvset) {
maddr = load_addr;
delta_vaddr = phdr->p_vaddr;
dvset = 1;
- }
- else {
+ } else {
maddr = load_addr + phdr->p_vaddr - delta_vaddr;
flags |= MAP_FIXED;
}
@@ -1005,13 +1048,14 @@
up_write(&mm->mmap_sem);
kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
- loop, phdr->p_memsz + disp, prot, flags, phdr->p_offset - disp,
- maddr);
+ loop, phdr->p_memsz + disp, prot, flags,
+ phdr->p_offset - disp, maddr);
- if (IS_ERR((void *) maddr))
+ if (IS_ERR_VALUE(maddr))
return (int) maddr;
- if ((params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) == ELF_FDPIC_FLAG_CONTIGUOUS)
+ if ((params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) ==
+ ELF_FDPIC_FLAG_CONTIGUOUS)
load_addr += PAGE_ALIGN(phdr->p_memsz + disp);
seg->addr = maddr + disp;
@@ -1022,7 +1066,8 @@
if (phdr->p_offset == 0)
params->elfhdr_addr = seg->addr;
- /* clear the bit between beginning of mapping and beginning of PT_LOAD */
+ /* clear the bit between beginning of mapping and beginning of
+ * PT_LOAD */
if (prot & PROT_WRITE && disp > 0) {
kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
clear_user((void __user *) maddr, disp);
@@ -1038,19 +1083,20 @@
excess1 = PAGE_SIZE - ((maddr + phdr->p_filesz) & ~PAGE_MASK);
#ifdef CONFIG_MMU
-
if (excess > excess1) {
unsigned long xaddr = maddr + phdr->p_filesz + excess1;
unsigned long xmaddr;
flags |= MAP_FIXED | MAP_ANONYMOUS;
down_write(&mm->mmap_sem);
- xmaddr = do_mmap(NULL, xaddr, excess - excess1, prot, flags, 0);
+ xmaddr = do_mmap(NULL, xaddr, excess - excess1,
+ prot, flags, 0);
up_write(&mm->mmap_sem);
kdebug("mmap[%d] <anon>"
" ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
- loop, xaddr, excess - excess1, prot, flags, xmaddr);
+ loop, xaddr, excess - excess1, prot, flags,
+ xmaddr);
if (xmaddr != xaddr)
return -ENOMEM;
@@ -1059,7 +1105,8 @@
if (prot & PROT_WRITE && excess1 > 0) {
kdebug("clear[%d] ad=%lx sz=%lx",
loop, maddr + phdr->p_filesz, excess1);
- clear_user((void __user *) maddr + phdr->p_filesz, excess1);
+ clear_user((void __user *) maddr + phdr->p_filesz,
+ excess1);
}
#else
@@ -1074,8 +1121,7 @@
if (phdr->p_flags & PF_X) {
mm->start_code = maddr;
mm->end_code = maddr + phdr->p_memsz;
- }
- else if (!mm->start_data) {
+ } else if (!mm->start_data) {
mm->start_data = maddr;
mm->end_data = maddr + phdr->p_memsz;
}
@@ -1085,4 +1131,662 @@
}
return 0;
-} /* end elf_fdpic_map_file_by_direct_mmap() */
+}
+
+/*****************************************************************************/
+/*
+ * ELF-FDPIC core dumper
+ *
+ * Modelled on fs/exec.c:aout_core_dump()
+ * Jeremy Fitzhardinge <jeremy@sw.oz.au>
+ *
+ * Modelled on fs/binfmt_elf.c core dumper
+ */
+#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
+
+/*
+ * These are the only things you should do on a core-file: use only these
+ * functions to write out all the necessary info.
+ */
+static int dump_write(struct file *file, const void *addr, int nr)
+{
+ return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+}
+
+static int dump_seek(struct file *file, loff_t off)
+{
+ if (file->f_op->llseek) {
+ if (file->f_op->llseek(file, off, SEEK_SET) != off)
+ return 0;
+ } else {
+ file->f_pos = off;
+ }
+ return 1;
+}
+
+/*
+ * Decide whether a segment is worth dumping; default is yes to be
+ * sure (missing info is worse than too much; etc).
+ * Personally I'd include everything, and use the coredump limit...
+ *
+ * I think we should skip something. But I am not sure how. H.J.
+ */
+static int maydump(struct vm_area_struct *vma)
+{
+ /* Do not dump I/O mapped devices or special mappings */
+ if (vma->vm_flags & (VM_IO | VM_RESERVED)) {
+ kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags);
+ return 0;
+ }
+
+ /* If we may not read the contents, don't allow us to dump
+ * them either. "dump_write()" can't handle it anyway.
+ */
+ if (!(vma->vm_flags & VM_READ)) {
+ kdcore("%08lx: %08lx: no (!read)", vma->vm_start, vma->vm_flags);
+ return 0;
+ }
+
+ /* Dump shared memory only if mapped from an anonymous file. */
+ if (vma->vm_flags & VM_SHARED) {
+ if (vma->vm_file->f_dentry->d_inode->i_nlink == 0) {
+ kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags);
+ return 1;
+ }
+
+ kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags);
+ return 0;
+ }
+
+#ifdef CONFIG_MMU
+ /* If it hasn't been written to, don't write it out */
+ if (!vma->anon_vma) {
+ kdcore("%08lx: %08lx: no (!anon)", vma->vm_start, vma->vm_flags);
+ return 0;
+ }
+#endif
+
+ kdcore("%08lx: %08lx: yes", vma->vm_start, vma->vm_flags);
+ return 1;
+}
+
+/* An ELF note in memory */
+struct memelfnote
+{
+ const char *name;
+ int type;
+ unsigned int datasz;
+ void *data;
+};
+
+static int notesize(struct memelfnote *en)
+{
+ int sz;
+
+ sz = sizeof(struct elf_note);
+ sz += roundup(strlen(en->name) + 1, 4);
+ sz += roundup(en->datasz, 4);
+
+ return sz;
+}
+
+/* #define DEBUG */
+
+#define DUMP_WRITE(addr, nr) \
+ do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
+#define DUMP_SEEK(off) \
+ do { if (!dump_seek(file, (off))) return 0; } while(0)
+
+static int writenote(struct memelfnote *men, struct file *file)
+{
+ struct elf_note en;
+
+ en.n_namesz = strlen(men->name) + 1;
+ en.n_descsz = men->datasz;
+ en.n_type = men->type;
+
+ DUMP_WRITE(&en, sizeof(en));
+ DUMP_WRITE(men->name, en.n_namesz);
+ /* XXX - cast from long long to long to avoid need for libgcc.a */
+ DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
+ DUMP_WRITE(men->data, men->datasz);
+ DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
+
+ return 1;
+}
+#undef DUMP_WRITE
+#undef DUMP_SEEK
+
+#define DUMP_WRITE(addr, nr) \
+ if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
+ goto end_coredump;
+#define DUMP_SEEK(off) \
+ if (!dump_seek(file, (off))) \
+ goto end_coredump;
+
+static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs)
+{
+ memcpy(elf->e_ident, ELFMAG, SELFMAG);
+ elf->e_ident[EI_CLASS] = ELF_CLASS;
+ elf->e_ident[EI_DATA] = ELF_DATA;
+ elf->e_ident[EI_VERSION] = EV_CURRENT;
+ elf->e_ident[EI_OSABI] = ELF_OSABI;
+ memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
+
+ elf->e_type = ET_CORE;
+ elf->e_machine = ELF_ARCH;
+ elf->e_version = EV_CURRENT;
+ elf->e_entry = 0;
+ elf->e_phoff = sizeof(struct elfhdr);
+ elf->e_shoff = 0;
+ elf->e_flags = ELF_FDPIC_CORE_EFLAGS;
+ elf->e_ehsize = sizeof(struct elfhdr);
+ elf->e_phentsize = sizeof(struct elf_phdr);
+ elf->e_phnum = segs;
+ elf->e_shentsize = 0;
+ elf->e_shnum = 0;
+ elf->e_shstrndx = 0;
+ return;
+}
+
+static inline void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, loff_t offset)
+{
+ phdr->p_type = PT_NOTE;
+ phdr->p_offset = offset;
+ phdr->p_vaddr = 0;
+ phdr->p_paddr = 0;
+ phdr->p_filesz = sz;
+ phdr->p_memsz = 0;
+ phdr->p_flags = 0;
+ phdr->p_align = 0;
+ return;
+}
+
+static inline void fill_note(struct memelfnote *note, const char *name, int type,
+ unsigned int sz, void *data)
+{
+ note->name = name;
+ note->type = type;
+ note->datasz = sz;
+ note->data = data;
+ return;
+}
+
+/*
+ * fill up all the fields in prstatus from the given task struct, except
+ * registers which need to be filled up seperately.
+ */
+static void fill_prstatus(struct elf_prstatus *prstatus,
+ struct task_struct *p, long signr)
+{
+ prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
+ prstatus->pr_sigpend = p->pending.signal.sig[0];
+ prstatus->pr_sighold = p->blocked.sig[0];
+ prstatus->pr_pid = p->pid;
+ prstatus->pr_ppid = p->parent->pid;
+ prstatus->pr_pgrp = process_group(p);
+ prstatus->pr_sid = p->signal->session;
+ if (thread_group_leader(p)) {
+ /*
+ * This is the record for the group leader. Add in the
+ * cumulative times of previous dead threads. This total
+ * won't include the time of each live thread whose state
+ * is included in the core dump. The final total reported
+ * to our parent process when it calls wait4 will include
+ * those sums as well as the little bit more time it takes
+ * this and each other thread to finish dying after the
+ * core dump synchronization phase.
+ */
+ cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
+ &prstatus->pr_utime);
+ cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
+ &prstatus->pr_stime);
+ } else {
+ cputime_to_timeval(p->utime, &prstatus->pr_utime);
+ cputime_to_timeval(p->stime, &prstatus->pr_stime);
+ }
+ cputime_to_timeval(p->signal->cutime, &prstatus->pr_cutime);
+ cputime_to_timeval(p->signal->cstime, &prstatus->pr_cstime);
+
+ prstatus->pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
+ prstatus->pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
+}
+
+static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
+ struct mm_struct *mm)
+{
+ unsigned int i, len;
+
+ /* first copy the parameters from user space */
+ memset(psinfo, 0, sizeof(struct elf_prpsinfo));
+
+ len = mm->arg_end - mm->arg_start;
+ if (len >= ELF_PRARGSZ)
+ len = ELF_PRARGSZ - 1;
+ if (copy_from_user(&psinfo->pr_psargs,
+ (const char __user *) mm->arg_start, len))
+ return -EFAULT;
+ for (i = 0; i < len; i++)
+ if (psinfo->pr_psargs[i] == 0)
+ psinfo->pr_psargs[i] = ' ';
+ psinfo->pr_psargs[len] = 0;
+
+ psinfo->pr_pid = p->pid;
+ psinfo->pr_ppid = p->parent->pid;
+ psinfo->pr_pgrp = process_group(p);
+ psinfo->pr_sid = p->signal->session;
+
+ i = p->state ? ffz(~p->state) + 1 : 0;
+ psinfo->pr_state = i;
+ psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i];
+ psinfo->pr_zomb = psinfo->pr_sname == 'Z';
+ psinfo->pr_nice = task_nice(p);
+ psinfo->pr_flag = p->flags;
+ SET_UID(psinfo->pr_uid, p->uid);
+ SET_GID(psinfo->pr_gid, p->gid);
+ strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
+
+ return 0;
+}
+
+/* Here is the structure in which status of each thread is captured. */
+struct elf_thread_status
+{
+ struct list_head list;
+ struct elf_prstatus prstatus; /* NT_PRSTATUS */
+ elf_fpregset_t fpu; /* NT_PRFPREG */
+ struct task_struct *thread;
+#ifdef ELF_CORE_COPY_XFPREGS
+ elf_fpxregset_t xfpu; /* NT_PRXFPREG */
+#endif
+ struct memelfnote notes[3];
+ int num_notes;
+};
+
+/*
+ * In order to add the specific thread information for the elf file format,
+ * we need to keep a linked list of every thread's pr_status and then create
+ * a single section for them in the final core file.
+ */
+static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
+{
+ struct task_struct *p = t->thread;
+ int sz = 0;
+
+ t->num_notes = 0;
+
+ fill_prstatus(&t->prstatus, p, signr);
+ elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
+
+ fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
+ &t->prstatus);
+ t->num_notes++;
+ sz += notesize(&t->notes[0]);
+
+ t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL, &t->fpu);
+ if (t->prstatus.pr_fpvalid) {
+ fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu),
+ &t->fpu);
+ t->num_notes++;
+ sz += notesize(&t->notes[1]);
+ }
+
+#ifdef ELF_CORE_COPY_XFPREGS
+ if (elf_core_copy_task_xfpregs(p, &t->xfpu)) {
+ fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu),
+ &t->xfpu);
+ t->num_notes++;
+ sz += notesize(&t->notes[2]);
+ }
+#endif
+ return sz;
+}
+
+/*
+ * dump the segments for an MMU process
+ */
+#ifdef CONFIG_MMU
+static int elf_fdpic_dump_segments(struct file *file, struct mm_struct *mm,
+ size_t *size, unsigned long *limit)
+{
+ struct vm_area_struct *vma;
+
+ for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
+ unsigned long addr;
+
+ if (!maydump(vma))
+ continue;
+
+ for (addr = vma->vm_start;
+ addr < vma->vm_end;
+ addr += PAGE_SIZE
+ ) {
+ struct vm_area_struct *vma;
+ struct page *page;
+
+ if (get_user_pages(current, current->mm, addr, 1, 0, 1,
+ &page, &vma) <= 0) {
+ DUMP_SEEK(file->f_pos + PAGE_SIZE);
+ }
+ else if (page == ZERO_PAGE(addr)) {
+ DUMP_SEEK(file->f_pos + PAGE_SIZE);
+ page_cache_release(page);
+ }
+ else {
+ void *kaddr;
+
+ flush_cache_page(vma, addr, page_to_pfn(page));
+ kaddr = kmap(page);
+ if ((*size += PAGE_SIZE) > *limit ||
+ !dump_write(file, kaddr, PAGE_SIZE)
+ ) {
+ kunmap(page);
+ page_cache_release(page);
+ return -EIO;
+ }
+ kunmap(page);
+ page_cache_release(page);
+ }
+ }
+ }
+
+ return 0;
+
+end_coredump:
+ return -EFBIG;
+}
+#endif
+
+/*
+ * dump the segments for a NOMMU process
+ */
+#ifndef CONFIG_MMU
+static int elf_fdpic_dump_segments(struct file *file, struct mm_struct *mm,
+ size_t *size, unsigned long *limit)
+{
+ struct vm_list_struct *vml;
+
+ for (vml = current->mm->context.vmlist; vml; vml = vml->next) {
+ struct vm_area_struct *vma = vml->vma;
+
+ if (!maydump(vma))
+ continue;
+
+ if ((*size += PAGE_SIZE) > *limit)
+ return -EFBIG;
+
+ if (!dump_write(file, (void *) vma->vm_start,
+ vma->vm_end - vma->vm_start))
+ return -EIO;
+ }
+
+ return 0;
+}
+#endif
+
+/*
+ * Actual dumper
+ *
+ * This is a two-pass process; first we find the offsets of the bits,
+ * and then they are actually written out. If we run out of core limit
+ * we just truncate.
+ */
+static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
+ struct file *file)
+{
+#define NUM_NOTES 6
+ int has_dumped = 0;
+ mm_segment_t fs;
+ int segs;
+ size_t size = 0;
+ int i;
+ struct vm_area_struct *vma;
+ struct elfhdr *elf = NULL;
+ loff_t offset = 0, dataoff;
+ unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
+ int numnote;
+ struct memelfnote *notes = NULL;
+ struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
+ struct elf_prpsinfo *psinfo = NULL; /* NT_PRPSINFO */
+ struct task_struct *g, *p;
+ LIST_HEAD(thread_list);
+ struct list_head *t;
+ elf_fpregset_t *fpu = NULL;
+#ifdef ELF_CORE_COPY_XFPREGS
+ elf_fpxregset_t *xfpu = NULL;
+#endif
+ int thread_status_size = 0;
+#ifndef CONFIG_MMU
+ struct vm_list_struct *vml;
+#endif
+ elf_addr_t *auxv;
+
+ /*
+ * We no longer stop all VM operations.
+ *
+ * This is because those proceses that could possibly change map_count
+ * or the mmap / vma pages are now blocked in do_exit on current
+ * finishing this core dump.
+ *
+ * Only ptrace can touch these memory addresses, but it doesn't change
+ * the map_count or the pages allocated. So no possibility of crashing
+ * exists while dumping the mm->vm_next areas to the core file.
+ */
+
+ /* alloc memory for large data structures: too large to be on stack */
+ elf = kmalloc(sizeof(*elf), GFP_KERNEL);
+ if (!elf)
+ goto cleanup;
+ prstatus = kzalloc(sizeof(*prstatus), GFP_KERNEL);
+ if (!prstatus)
+ goto cleanup;
+ psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
+ if (!psinfo)
+ goto cleanup;
+ notes = kmalloc(NUM_NOTES * sizeof(struct memelfnote), GFP_KERNEL);
+ if (!notes)
+ goto cleanup;
+ fpu = kmalloc(sizeof(*fpu), GFP_KERNEL);
+ if (!fpu)
+ goto cleanup;
+#ifdef ELF_CORE_COPY_XFPREGS
+ xfpu = kmalloc(sizeof(*xfpu), GFP_KERNEL);
+ if (!xfpu)
+ goto cleanup;
+#endif
+
+ if (signr) {
+ struct elf_thread_status *tmp;
+ read_lock(&tasklist_lock);
+ do_each_thread(g,p)
+ if (current->mm == p->mm && current != p) {
+ tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
+ if (!tmp) {
+ read_unlock(&tasklist_lock);
+ goto cleanup;
+ }
+ INIT_LIST_HEAD(&tmp->list);
+ tmp->thread = p;
+ list_add(&tmp->list, &thread_list);
+ }
+ while_each_thread(g,p);
+ read_unlock(&tasklist_lock);
+ list_for_each(t, &thread_list) {
+ struct elf_thread_status *tmp;
+ int sz;
+
+ tmp = list_entry(t, struct elf_thread_status, list);
+ sz = elf_dump_thread_status(signr, tmp);
+ thread_status_size += sz;
+ }
+ }
+
+ /* now collect the dump for the current */
+ fill_prstatus(prstatus, current, signr);
+ elf_core_copy_regs(&prstatus->pr_reg, regs);
+
+#ifdef CONFIG_MMU
+ segs = current->mm->map_count;
+#else
+ segs = 0;
+ for (vml = current->mm->context.vmlist; vml; vml = vml->next)
+ segs++;
+#endif
+#ifdef ELF_CORE_EXTRA_PHDRS
+ segs += ELF_CORE_EXTRA_PHDRS;
+#endif
+
+ /* Set up header */
+ fill_elf_fdpic_header(elf, segs + 1); /* including notes section */
+
+ has_dumped = 1;
+ current->flags |= PF_DUMPCORE;
+
+ /*
+ * Set up the notes in similar form to SVR4 core dumps made
+ * with info from their /proc.
+ */
+
+ fill_note(notes + 0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus);
+ fill_psinfo(psinfo, current->group_leader, current->mm);
+ fill_note(notes + 1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
+
+ numnote = 2;
+
+ auxv = (elf_addr_t *) current->mm->saved_auxv;
+
+ i = 0;
+ do
+ i += 2;
+ while (auxv[i - 2] != AT_NULL);
+ fill_note(¬es[numnote++], "CORE", NT_AUXV,
+ i * sizeof(elf_addr_t), auxv);
+
+ /* Try to dump the FPU. */
+ if ((prstatus->pr_fpvalid =
+ elf_core_copy_task_fpregs(current, regs, fpu)))
+ fill_note(notes + numnote++,
+ "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
+#ifdef ELF_CORE_COPY_XFPREGS
+ if (elf_core_copy_task_xfpregs(current, xfpu))
+ fill_note(notes + numnote++,
+ "LINUX", NT_PRXFPREG, sizeof(*xfpu), xfpu);
+#endif
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ DUMP_WRITE(elf, sizeof(*elf));
+ offset += sizeof(*elf); /* Elf header */
+ offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */
+
+ /* Write notes phdr entry */
+ {
+ struct elf_phdr phdr;
+ int sz = 0;
+
+ for (i = 0; i < numnote; i++)
+ sz += notesize(notes + i);
+
+ sz += thread_status_size;
+
+ fill_elf_note_phdr(&phdr, sz, offset);
+ offset += sz;
+ DUMP_WRITE(&phdr, sizeof(phdr));
+ }
+
+ /* Page-align dumped data */
+ dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
+
+ /* write program headers for segments dump */
+ for (
+#ifdef CONFIG_MMU
+ vma = current->mm->mmap; vma; vma = vma->vm_next
+#else
+ vml = current->mm->context.vmlist; vml; vml = vml->next
+#endif
+ ) {
+ struct elf_phdr phdr;
+ size_t sz;
+
+#ifndef CONFIG_MMU
+ vma = vml->vma;
+#endif
+
+ sz = vma->vm_end - vma->vm_start;
+
+ phdr.p_type = PT_LOAD;
+ phdr.p_offset = offset;
+ phdr.p_vaddr = vma->vm_start;
+ phdr.p_paddr = 0;
+ phdr.p_filesz = maydump(vma) ? sz : 0;
+ phdr.p_memsz = sz;
+ offset += phdr.p_filesz;
+ phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
+ if (vma->vm_flags & VM_WRITE)
+ phdr.p_flags |= PF_W;
+ if (vma->vm_flags & VM_EXEC)
+ phdr.p_flags |= PF_X;
+ phdr.p_align = ELF_EXEC_PAGESIZE;
+
+ DUMP_WRITE(&phdr, sizeof(phdr));
+ }
+
+#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
+ ELF_CORE_WRITE_EXTRA_PHDRS;
+#endif
+
+ /* write out the notes section */
+ for (i = 0; i < numnote; i++)
+ if (!writenote(notes + i, file))
+ goto end_coredump;
+
+ /* write out the thread status notes section */
+ list_for_each(t, &thread_list) {
+ struct elf_thread_status *tmp =
+ list_entry(t, struct elf_thread_status, list);
+
+ for (i = 0; i < tmp->num_notes; i++)
+ if (!writenote(&tmp->notes[i], file))
+ goto end_coredump;
+ }
+
+ DUMP_SEEK(dataoff);
+
+ if (elf_fdpic_dump_segments(file, current->mm, &size, &limit) < 0)
+ goto end_coredump;
+
+#ifdef ELF_CORE_WRITE_EXTRA_DATA
+ ELF_CORE_WRITE_EXTRA_DATA;
+#endif
+
+ if (file->f_pos != offset) {
+ /* Sanity check */
+ printk(KERN_WARNING
+ "elf_core_dump: file->f_pos (%lld) != offset (%lld)\n",
+ file->f_pos, offset);
+ }
+
+end_coredump:
+ set_fs(fs);
+
+cleanup:
+ while (!list_empty(&thread_list)) {
+ struct list_head *tmp = thread_list.next;
+ list_del(tmp);
+ kfree(list_entry(tmp, struct elf_thread_status, list));
+ }
+
+ kfree(elf);
+ kfree(prstatus);
+ kfree(psinfo);
+ kfree(notes);
+ kfree(fpu);
+#ifdef ELF_CORE_COPY_XFPREGS
+ kfree(xfpu);
+#endif
+ return has_dumped;
+#undef NUM_NOTES
+}
+
+#endif /* USE_ELF_CORE_DUMP */
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index 92d50b5..0d1e627 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -62,9 +62,6 @@
extern int ext3_acl_chmod (struct inode *);
extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
-extern int init_ext3_acl(void);
-extern void exit_ext3_acl(void);
-
#else /* CONFIG_EXT3_FS_POSIX_ACL */
#include <linux/sched.h>
#define ext3_permission NULL
diff --git a/fs/file.c b/fs/file.c
index 55f4e70..3f35608 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -240,13 +240,9 @@
if (!fdt)
goto out;
- nfds = 8 * L1_CACHE_BYTES;
- /* Expand to the max in easy steps */
- while (nfds <= nr) {
- nfds = nfds * 2;
- if (nfds > NR_OPEN)
- nfds = NR_OPEN;
- }
+ nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nfds));
+ if (nfds > NR_OPEN)
+ nfds = NR_OPEN;
new_openset = alloc_fdset(nfds);
new_execset = alloc_fdset(nfds);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 6449cb6..c3920c9 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -83,8 +83,6 @@
ret = -ENOMEM;
len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
- if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size)
- goto out;
if (vma->vm_flags & VM_MAYSHARE &&
hugetlb_reserve_pages(inode, vma->vm_pgoff >> (HPAGE_SHIFT-PAGE_SHIFT),
@@ -93,7 +91,7 @@
ret = 0;
hugetlb_prefault_arch_hook(vma->vm_mm);
- if (inode->i_size < len)
+ if (vma->vm_flags & VM_WRITE && inode->i_size < len)
inode->i_size = len;
out:
mutex_unlock(&inode->i_mutex);
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index b0e095e..ee4eff2 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -721,6 +721,12 @@
return nfs_ok;
}
+static inline void nfsd4_increment_op_stats(u32 opnum)
+{
+ if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP)
+ nfsdstats.nfs4_opcount[opnum]++;
+}
+
/*
* COMPOUND call.
@@ -930,6 +936,8 @@
/* XXX Ugh, we need to get rid of this kind of special case: */
if (op->opnum == OP_READ && op->u.read.rd_filp)
fput(op->u.read.rd_filp);
+
+ nfsd4_increment_op_stats(op->opnum);
}
out:
diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c
index 57265d5..71944cd 100644
--- a/fs/nfsd/stats.c
+++ b/fs/nfsd/stats.c
@@ -72,6 +72,16 @@
/* show my rpc info */
svc_seq_show(seq, &nfsd_svcstats);
+#ifdef CONFIG_NFSD_V4
+ /* Show count for individual nfsv4 operations */
+ /* Writing operation numbers 0 1 2 also for maintaining uniformity */
+ seq_printf(seq,"proc4ops %u", LAST_NFS4_OP + 1);
+ for (i = 0; i <= LAST_NFS4_OP; i++)
+ seq_printf(seq, " %u", nfsdstats.nfs4_opcount[i]);
+
+ seq_putc(seq, '\n');
+#endif
+
return 0;
}
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 8396340..51c6a74 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -339,6 +339,7 @@
p->start_sect = start;
p->nr_sects = len;
p->partno = part;
+ p->policy = disk->policy;
if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1]))
snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part);
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 036d14d8..8d6d85d 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -42,8 +42,6 @@
#define kc_offset_to_vaddr(o) ((o) + PAGE_OFFSET)
#endif
-#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-
/* An ELF note in memory */
struct memelfnote
{
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 99fffc9..677139b 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -283,9 +283,9 @@
/*****************************************************************************/
/*
- * set up a mapping
+ * set up a mapping for shared memory segments
*/
int ramfs_nommu_mmap(struct file *file, struct vm_area_struct *vma)
{
- return 0;
+ return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
}
diff --git a/fs/read_write.c b/fs/read_write.c
index 5bc0e92..d4cb318 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -436,7 +436,7 @@
return seg;
}
-EXPORT_SYMBOL(iov_shorten);
+EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */
/* A write operation does a read from user space and vice versa */
#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 752cea1..f318b58 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -860,8 +860,12 @@
// this sets the proper flags for O_SYNC to trigger a commit
mark_inode_dirty(inode);
reiserfs_write_unlock(inode->i_sb);
- } else
+ } else {
+ reiserfs_write_lock(inode->i_sb);
+ reiserfs_update_inode_transaction(inode);
mark_inode_dirty(inode);
+ reiserfs_write_unlock(inode->i_sb);
+ }
sd_update = 1;
}
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 8c021dc..a13f75c 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -215,7 +215,6 @@
#define MIN(a,b) (min(a,b))
#define MAX(a,b) (max(a,b))
#define howmany(x, y) (((x)+((y)-1))/(y))
-#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
/*
* Various platform dependent calls that don't fit anywhere else
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index b492857..9e6c23c 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -63,7 +63,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20060623
+#define ACPI_CA_VERSION 0x20060707
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index 216339a..91586d0 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -53,10 +53,14 @@
#define ACPI_EXD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_exdump_info))
/*
- * If possible, pack the following structure to byte alignment, since we
- * don't care about performance for debug output
+ * If possible, pack the following structures to byte alignment, since we
+ * don't care about performance for debug output. Two cases where we cannot
+ * pack the structures:
+ *
+ * 1) Hardware does not support misaligned memory transfers
+ * 2) Compiler does not support pointers within packed structures
*/
-#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#if (!defined(ACPI_MISALIGNMENT_NOT_SUPPORTED) && !defined(ACPI_PACKED_POINTERS_NOT_SUPPORTED))
#pragma pack(1)
#endif
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
index 56b8024..a4d0e73 100644
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -127,7 +127,7 @@
/* This Thread ID means that the mutex is not in use (unlocked) */
-#define ACPI_MUTEX_NOT_ACQUIRED (u32) -1
+#define ACPI_MUTEX_NOT_ACQUIRED (acpi_thread_id) 0
/* Table for the global mutexes */
@@ -204,7 +204,7 @@
/* Namespace Node flags */
#define ANOBJ_END_OF_PEER_LIST 0x01 /* End-of-list, Peer field points to parent */
-#define ANOBJ_DATA_WIDTH_32 0x02 /* Parent table uses 32-bit math */
+#define ANOBJ_RESERVED 0x02 /* Available for future use */
#define ANOBJ_METHOD_ARG 0x04 /* Node is a method argument */
#define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */
#define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index f1ac610..192fa095 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -724,9 +724,15 @@
/* Memory allocation */
+#ifndef ACPI_ALLOCATE
#define ACPI_ALLOCATE(a) acpi_ut_allocate((acpi_size)(a),_COMPONENT,_acpi_module_name,__LINE__)
+#endif
+#ifndef ACPI_ALLOCATE_ZEROED
#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed((acpi_size)(a), _COMPONENT,_acpi_module_name,__LINE__)
-#define ACPI_FREE(a) kfree(a)
+#endif
+#ifndef ACPI_FREE
+#define ACPI_FREE(a) acpio_os_free(a)
+#endif
#define ACPI_MEM_TRACKING(a)
#else
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a2b3e39..f338e40 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -334,7 +334,7 @@
acpi_handle handle, int type);
int acpi_bus_trim(struct acpi_device *start, int rmdevice);
int acpi_bus_start(struct acpi_device *device);
-
+acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd);
int acpi_match_ids(struct acpi_device *device, char *ids);
int acpi_create_dir(struct acpi_device *);
void acpi_remove_dir(struct acpi_device *);
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index b425f9b..6a5bdce 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -110,4 +110,21 @@
extern int acpi_specific_hotkey_enabled;
+/*--------------------------------------------------------------------------
+ Dock Station
+ -------------------------------------------------------------------------- */
+#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
+extern int is_dock_device(acpi_handle handle);
+extern int register_dock_notifier(struct notifier_block *nb);
+extern void unregister_dock_notifier(struct notifier_block *nb);
+extern int register_hotplug_dock_device(acpi_handle handle,
+ acpi_notify_handler handler, void *context);
+extern void unregister_hotplug_dock_device(acpi_handle handle);
+#else
+#define is_dock_device(h) (0)
+#define register_dock_notifier(nb) (-ENODEV)
+#define unregister_dock_notifier(nb) do { } while(0)
+#define register_hotplug_dock_device(h1, h2, c) (-ENODEV)
+#define unregister_hotplug_dock_device(h) do { } while(0)
+#endif
#endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h
index ad11fc1..80a3b33 100644
--- a/include/acpi/acresrc.h
+++ b/include/acpi/acresrc.h
@@ -50,9 +50,13 @@
/*
* If possible, pack the following structures to byte alignment, since we
- * don't care about performance for debug output
+ * don't care about performance for debug output. Two cases where we cannot
+ * pack the structures:
+ *
+ * 1) Hardware does not support misaligned memory transfers
+ * 2) Compiler does not support pointers within packed structures
*/
-#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#if (!defined(ACPI_MISALIGNMENT_NOT_SUPPORTED) && !defined(ACPI_PACKED_POINTERS_NOT_SUPPORTED))
#pragma pack(1)
#endif
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 3f853ca..47faf27 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -59,6 +59,7 @@
#include <asm/acpi.h>
#include <linux/slab.h>
#include <linux/spinlock_types.h>
+#include <asm/current.h>
/* Host-dependent types and defines */
@@ -100,8 +101,30 @@
#define acpi_cpu_flags unsigned long
-#define acpi_thread_id u32
+#define acpi_thread_id struct task_struct *
-static inline acpi_thread_id acpi_os_get_thread_id(void) { return 0; }
+static inline acpi_thread_id acpi_os_get_thread_id(void) { return current; }
+
+/*
+ * The irqs_disabled() check is for resume from RAM.
+ * Interrupts are off during resume, just like they are for boot.
+ * However, boot has (system_state != SYSTEM_RUNNING)
+ * to quiet __might_sleep() in kmalloc() and resume does not.
+ */
+#include <acpi/actypes.h>
+static inline void *acpi_os_allocate(acpi_size size) {
+ return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+}
+static inline void *acpi_os_allocate_zeroed(acpi_size size) {
+ return kzalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+}
+
+static inline void *acpi_os_acquire_object(acpi_cache_t * cache) {
+ return kmem_cache_zalloc(cache, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+}
+
+#define ACPI_ALLOCATE(a) acpi_os_allocate(a)
+#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a)
+#define ACPI_FREE(a) kfree(a)
#endif /* __ACLINUX_H__ */
diff --git a/include/asm-frv/elf.h b/include/asm-frv/elf.h
index 38656da..7df58a3 100644
--- a/include/asm-frv/elf.h
+++ b/include/asm-frv/elf.h
@@ -64,7 +64,7 @@
#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-typedef struct fpmedia_struct elf_fpregset_t;
+typedef struct user_fpmedia_regs elf_fpregset_t;
/*
* This is used to ensure we don't load something for the wrong architecture.
@@ -116,6 +116,7 @@
} while(0)
#define USE_ELF_CORE_DUMP
+#define ELF_FDPIC_CORE_EFLAGS EF_FRV_FDPIC
#define ELF_EXEC_PAGESIZE 16384
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
@@ -125,9 +126,6 @@
#define ELF_ET_DYN_BASE 0x08000000UL
-#define ELF_CORE_COPY_REGS(pr_reg, regs) \
- memcpy(&pr_reg[0], ®s->sp, 31 * sizeof(uint32_t));
-
/* This yields a mask that user programs can use to figure out what
instruction set this cpu supports. */
diff --git a/include/asm-frv/gdb-stub.h b/include/asm-frv/gdb-stub.h
index c58479a..24f9738 100644
--- a/include/asm-frv/gdb-stub.h
+++ b/include/asm-frv/gdb-stub.h
@@ -89,6 +89,7 @@
extern asmlinkage void __debug_stub_init_break(void);
extern asmlinkage void __break_hijack_kernel_event(void);
+extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
extern asmlinkage void start_kernel(void);
extern asmlinkage void gdbstub_rx_handler(void);
@@ -114,5 +115,26 @@
#define gdbstub_proto(FMT,...) ({ 0; })
#endif
+/*
+ * we dedicate GR31 to keeping a pointer to the gdbstub exception frame
+ * - gr31 is destroyed on entry to the gdbstub if !MMU
+ * - gr31 is saved in scr3 on entry to the gdbstub if in !MMU
+ */
+register struct frv_frame0 *__debug_frame0 asm("gr31");
+
+#define __debug_frame (&__debug_frame0->regs)
+#define __debug_user_context (&__debug_frame0->uc)
+#define __debug_regs (&__debug_frame0->debug)
+#define __debug_reg(X) ((unsigned long *) ((unsigned long) &__debug_frame0 + (X)))
+
+struct frv_debug_status {
+ unsigned long bpsr;
+ unsigned long dcr;
+ unsigned long brr;
+ unsigned long nmar;
+};
+
+extern struct frv_debug_status __debug_status;
+
#endif /* _LANGUAGE_ASSEMBLY */
#endif /* __ASM_GDB_STUB_H */
diff --git a/include/asm-frv/ptrace.h b/include/asm-frv/ptrace.h
index b2cce071..7ff5251 100644
--- a/include/asm-frv/ptrace.h
+++ b/include/asm-frv/ptrace.h
@@ -62,18 +62,10 @@
#ifndef __ASSEMBLY__
/*
- * dedicate GR28; to keeping the a pointer to the current exception frame
+ * we dedicate GR28 to keeping a pointer to the current exception frame
+ * - gr28 is destroyed on entry to the kernel from userspace
*/
register struct pt_regs *__frame asm("gr28");
-register struct pt_regs *__debug_frame asm("gr31");
-
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-#define __debug_regs container_of(__debug_frame, struct pt_debug_regs, normal_regs)
#define user_mode(regs) (!((regs)->psr & PSR_S))
#define instruction_pointer(regs) ((regs)->pc)
diff --git a/include/asm-frv/registers.h b/include/asm-frv/registers.h
index fccfd95..9666119 100644
--- a/include/asm-frv/registers.h
+++ b/include/asm-frv/registers.h
@@ -23,7 +23,13 @@
*
* +0x2000 +----------------------
* | union {
- * | struct user_context
+ * | struct frv_frame0 {
+ * | struct user_context {
+ * | struct user_int_regs
+ * | struct user_fpmedia_regs
+ * | }
+ * | struct frv_debug_regs
+ * | }
* | struct pt_regs [user exception]
* | }
* +---------------------- <-- __kernel_frame0_ptr (maybe GR28)
@@ -51,11 +57,11 @@
#define _ASM_REGISTERS_H
#ifndef __ASSEMBLY__
-#define __OFFSET(X) (X)
+#define __OFFSET(X,N) ((X)+(N)*4)
#define __OFFSETC(X,N) xxxxxxxxxxxxxxxxxxxxxxxx
#else
-#define __OFFSET(X) ((X)*4)
-#define __OFFSETC(X,N) ((X)*4+(N))
+#define __OFFSET(X,N) ((X)+(N)*4)
+#define __OFFSETC(X,N) ((X)+(N))
#endif
/*****************************************************************************/
@@ -117,30 +123,13 @@
#endif
-#define REG_PSR __OFFSET( 0) /* Processor Status Register */
-#define REG_ISR __OFFSET( 1) /* Integer Status Register */
-#define REG_CCR __OFFSET( 2) /* Condition Code Register */
-#define REG_CCCR __OFFSET( 3) /* Condition Code for Conditional Insns Register */
-#define REG_LR __OFFSET( 4) /* Link Register */
-#define REG_LCR __OFFSET( 5) /* Loop Count Register */
-#define REG_PC __OFFSET( 6) /* Program Counter */
-
-#define REG__STATUS __OFFSET( 7) /* exception status */
#define REG__STATUS_STEP 0x00000001 /* - reenable single stepping on return */
#define REG__STATUS_STEPPED 0x00000002 /* - single step caused exception */
#define REG__STATUS_BROKE 0x00000004 /* - BREAK insn caused exception */
#define REG__STATUS_SYSC_ENTRY 0x40000000 /* - T on syscall entry (ptrace.c only) */
#define REG__STATUS_SYSC_EXIT 0x80000000 /* - T on syscall exit (ptrace.c only) */
-#define REG_SYSCALLNO __OFFSET( 8) /* syscall number or -1 */
-#define REG_ORIG_GR8 __OFFSET( 9) /* saved GR8 for signal handling */
-#define REG_GNER0 __OFFSET(10)
-#define REG_GNER1 __OFFSET(11)
-#define REG_IACC0 __OFFSET(12)
-
-#define REG_TBR __OFFSET(14) /* Trap Vector Register */
-#define REG_GR(R) __OFFSET((14+(R)))
-#define REG__END REG_GR(32)
+#define REG_GR(R) __OFFSET(REG_GR0, (R))
#define REG_SP REG_GR(1)
#define REG_FP REG_GR(2)
@@ -149,27 +138,21 @@
/*****************************************************************************/
/*
- * extension tacked in front of the exception frame in debug mode
+ * debugging registers
*/
#ifndef __ASSEMBLY__
-struct pt_debug_regs
+struct frv_debug_regs
{
- unsigned long bpsr;
unsigned long dcr;
- unsigned long brr;
- unsigned long nmar;
- struct pt_regs normal_regs;
+ unsigned long ibar[4] __attribute__((aligned(8)));
+ unsigned long dbar[4] __attribute__((aligned(8)));
+ unsigned long dbdr[4][4] __attribute__((aligned(8)));
+ unsigned long dbmr[4][4] __attribute__((aligned(8)));
} __attribute__((aligned(8)));
#endif
-#define REG_NMAR __OFFSET(-1)
-#define REG_BRR __OFFSET(-2)
-#define REG_DCR __OFFSET(-3)
-#define REG_BPSR __OFFSET(-4)
-#define REG__DEBUG_XTRA __OFFSET(4)
-
/*****************************************************************************/
/*
* userspace registers
@@ -223,33 +206,27 @@
void *extension;
} __attribute__((aligned(8)));
+struct frv_frame0 {
+ union {
+ struct pt_regs regs;
+ struct user_context uc;
+ };
+
+ struct frv_debug_regs debug;
+
+} __attribute__((aligned(32)));
+
#endif
-#define NR_USER_INT_REGS (14 + 64)
-#define NR_USER_FPMEDIA_REGS (64 + 2 + 2 + 8 + 8/4 + 1)
-#define NR_USER_CONTEXT (NR_USER_INT_REGS + NR_USER_FPMEDIA_REGS + 1)
+#define __INT_GR(R) __OFFSET(__INT_GR0, (R))
-#define USER_CONTEXT_SIZE (((NR_USER_CONTEXT + 1) & ~1) * 4)
+#define __FPMEDIA_FR(R) __OFFSET(__FPMEDIA_FR0, (R))
+#define __FPMEDIA_FNER(R) __OFFSET(__FPMEDIA_FNER0, (R))
+#define __FPMEDIA_MSR(R) __OFFSET(__FPMEDIA_MSR0, (R))
+#define __FPMEDIA_ACC(R) __OFFSET(__FPMEDIA_ACC0, (R))
+#define __FPMEDIA_ACCG(R) __OFFSETC(__FPMEDIA_ACCG0, (R))
+#define __FPMEDIA_FSR(R) __OFFSET(__FPMEDIA_FSR0, (R))
-#define __THREAD_FRAME __OFFSET(0)
-#define __THREAD_CURR __OFFSET(1)
-#define __THREAD_SP __OFFSET(2)
-#define __THREAD_FP __OFFSET(3)
-#define __THREAD_LR __OFFSET(4)
-#define __THREAD_PC __OFFSET(5)
-#define __THREAD_GR(R) __OFFSET(6 + (R) - 16)
-#define __THREAD_FRAME0 __OFFSET(19)
-#define __THREAD_USER __OFFSET(19)
-
-#define __USER_INT __OFFSET(0)
-#define __INT_GR(R) __OFFSET(14 + (R))
-
-#define __USER_FPMEDIA __OFFSET(NR_USER_INT_REGS)
-#define __FPMEDIA_FR(R) __OFFSET(NR_USER_INT_REGS + (R))
-#define __FPMEDIA_FNER(R) __OFFSET(NR_USER_INT_REGS + 64 + (R))
-#define __FPMEDIA_MSR(R) __OFFSET(NR_USER_INT_REGS + 66 + (R))
-#define __FPMEDIA_ACC(R) __OFFSET(NR_USER_INT_REGS + 68 + (R))
-#define __FPMEDIA_ACCG(R) __OFFSETC(NR_USER_INT_REGS + 76, (R))
-#define __FPMEDIA_FSR(R) __OFFSET(NR_USER_INT_REGS + 78 + (R))
+#define __THREAD_GR(R) __OFFSET(__THREAD_GR16, (R) - 16)
#endif /* _ASM_REGISTERS_H */
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
index ea426ab..d66c48e 100644
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -19,6 +19,8 @@
#include <asm/processor.h>
#endif
+#define THREAD_SIZE 8192
+
/*
* low level task data that entry.S needs immediate access to
* - this struct should fit entirely inside of one cache line
@@ -46,15 +48,7 @@
#else /* !__ASSEMBLY__ */
-/* offsets into the thread_info struct for assembly code access */
-#define TI_TASK 0x00000000
-#define TI_EXEC_DOMAIN 0x00000004
-#define TI_FLAGS 0x00000008
-#define TI_STATUS 0x0000000C
-#define TI_CPU 0x00000010
-#define TI_PRE_COUNT 0x00000014
-#define TI_ADDR_LIMIT 0x00000018
-#define TI_RESTART_BLOCK 0x0000001C
+#include <asm/asm-offsets.h>
#endif
@@ -83,12 +77,6 @@
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
-#ifdef CONFIG_SMALL_TASKS
-#define THREAD_SIZE 4096
-#else
-#define THREAD_SIZE 8192
-#endif
-
/* how to get the thread information struct from C */
register struct thread_info *__current_thread_info asm("gr15");
@@ -111,11 +99,7 @@
#define free_thread_info(info) kfree(info)
-#else /* !__ASSEMBLY__ */
-
-#define THREAD_SIZE 8192
-
-#endif
+#endif /* __ASSEMBLY__ */
/*
* thread information flags
diff --git a/include/asm-h8300/page.h b/include/asm-h8300/page.h
index f9f9d3e..d673077 100644
--- a/include/asm-h8300/page.h
+++ b/include/asm-h8300/page.h
@@ -66,7 +66,6 @@
#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
-#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
#define pfn_valid(page) (page < max_mapnr)
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
index 781ee2c..43bfff6 100644
--- a/include/asm-ia64/io.h
+++ b/include/asm-ia64/io.h
@@ -90,7 +90,7 @@
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
extern u64 kern_mem_attribute (unsigned long phys_addr, unsigned long size);
extern int valid_phys_addr_range (unsigned long addr, size_t count); /* efi.c */
-extern int valid_mmap_phys_addr_range (unsigned long addr, size_t count);
+extern int valid_mmap_phys_addr_range (unsigned long pfn, size_t count);
/*
* The following two macros are deprecated and scheduled for removal.
diff --git a/include/asm-mips/mach-dec/mc146818rtc.h b/include/asm-mips/mach-dec/mc146818rtc.h
index 6d37a56..6724e99 100644
--- a/include/asm-mips/mach-dec/mc146818rtc.h
+++ b/include/asm-mips/mach-dec/mc146818rtc.h
@@ -19,6 +19,8 @@
extern volatile u8 *dec_rtc_base;
+#define ARCH_RTC_LOCATION
+
#define RTC_PORT(x) CPHYSADDR((long)dec_rtc_base)
#define RTC_IO_EXTENT dec_kn_slot_size
#define RTC_IOMAPPED 0
diff --git a/include/asm-powerpc/backlight.h b/include/asm-powerpc/backlight.h
index a5e9e65..58d4b6f 100644
--- a/include/asm-powerpc/backlight.h
+++ b/include/asm-powerpc/backlight.h
@@ -16,13 +16,19 @@
extern struct backlight_device *pmac_backlight;
extern struct mutex pmac_backlight_mutex;
-extern void pmac_backlight_calc_curve(struct fb_info*);
extern int pmac_backlight_curve_lookup(struct fb_info *info, int value);
extern int pmac_has_backlight_type(const char *type);
-extern void pmac_backlight_key_up(void);
-extern void pmac_backlight_key_down(void);
+extern void pmac_backlight_key(int direction);
+static inline void pmac_backlight_key_up(void)
+{
+ pmac_backlight_key(0);
+}
+static inline void pmac_backlight_key_down(void)
+{
+ pmac_backlight_key(1);
+}
extern int pmac_backlight_set_legacy_brightness(int brightness);
extern int pmac_backlight_get_legacy_brightness(void);
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index e057547..d903a62 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -83,25 +83,24 @@
int (*match)(struct irq_host *h, struct device_node *node);
/* Create or update a mapping between a virtual irq number and a hw
- * irq number. This can be called several times for the same mapping
- * but with different flags, though unmap shall always be called
- * before the virq->hw mapping is changed.
+ * irq number. This is called only once for a given mapping.
*/
- int (*map)(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags);
+ int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
/* Dispose of such a mapping */
void (*unmap)(struct irq_host *h, unsigned int virq);
/* Translate device-tree interrupt specifier from raw format coming
* from the firmware to a irq_hw_number_t (interrupt line number) and
- * trigger flags that can be passed to irq_create_mapping().
- * If no translation is provided, raw format is assumed to be one cell
- * for interrupt line and default sense.
+ * type (sense) that can be passed to set_irq_type(). In the absence
+ * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
+ * will return the hw number in the first cell and IRQ_TYPE_NONE for
+ * the type (which amount to keeping whatever default value the
+ * interrupt controller has for that line)
*/
int (*xlate)(struct irq_host *h, struct device_node *ctrler,
u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_flags);
+ irq_hw_number_t *out_hwirq, unsigned int *out_type);
};
struct irq_host {
@@ -193,25 +192,14 @@
* irq_create_mapping - Map a hardware interrupt into linux virq space
* @host: host owning this hardware interrupt or NULL for default host
* @hwirq: hardware irq number in that host space
- * @flags: flags passed to the controller. contains the trigger type among
- * others. Use IRQ_TYPE_* defined in include/linux/irq.h
*
* Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number. The flags can be used to provide sense information to the
- * controller (typically extracted from the device-tree). If no information
- * is passed, the controller defaults will apply (for example, xics can only
- * do edge so flags are irrelevant for some pseries specific irqs).
- *
- * The device-tree generally contains the trigger info in an encoding that is
- * specific to a given type of controller. In that case, you can directly use
- * host->ops->trigger_xlate() to translate that.
- *
- * It is recommended that new PICs that don't have existing OF bindings chose
- * to use a representation of triggers identical to linux.
+ * virq number.
+ * If the sense/trigger is to be specified, set_irq_type() should be called
+ * on the number returned from that call.
*/
extern unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq,
- unsigned int flags);
+ irq_hw_number_t hwirq);
/***
@@ -295,7 +283,7 @@
*
* This function is identical to irq_create_mapping except that it takes
* as input informations straight from the device-tree (typically the results
- * of the of_irq_map_*() functions
+ * of the of_irq_map_*() functions.
*/
extern unsigned int irq_create_of_mapping(struct device_node *controller,
u32 *intspec, unsigned int intsize);
diff --git a/include/asm-x86_64/calgary.h b/include/asm-x86_64/calgary.h
index 6e1654f..fbfb501 100644
--- a/include/asm-x86_64/calgary.h
+++ b/include/asm-x86_64/calgary.h
@@ -1,8 +1,10 @@
/*
* Derived from include/asm-powerpc/iommu.h
*
- * Copyright (C) 2006 Jon Mason <jdmason@us.ibm.com>, IBM Corporation
- * Copyright (C) 2006 Muli Ben-Yehuda <muli@il.ibm.com>, IBM Corporation
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Jon Mason <jdmason@us.ibm.com>
+ * Author: Muli Ben-Yehuda <muli@il.ibm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/include/asm-x86_64/tce.h b/include/asm-x86_64/tce.h
index ee51d31..53e9a68 100644
--- a/include/asm-x86_64/tce.h
+++ b/include/asm-x86_64/tce.h
@@ -1,9 +1,11 @@
/*
- * Copyright (C) 2006 Muli Ben-Yehuda <muli@il.ibm.com>, IBM Corporation
- * Copyright (C) 2006 Jon Mason <jdmason@us.ibm.com>, IBM Corporation
- *
* This file is derived from asm-powerpc/tce.h.
*
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Muli Ben-Yehuda <muli@il.ibm.com>
+ * Author: Jon Mason <jdmason@us.ibm.com>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 22866fa..1021f50 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -91,7 +91,7 @@
}
#endif
-extern unsigned long nr_kernel_pages;
+extern unsigned long __meminitdata nr_kernel_pages;
extern unsigned long nr_all_pages;
extern void *__init alloc_large_system_hash(const char *tablename,
diff --git a/include/linux/completion.h b/include/linux/completion.h
index 251c41e..268c5a4a 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -18,6 +18,9 @@
#define COMPLETION_INITIALIZER(work) \
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
+#define COMPLETION_INITIALIZER_ONSTACK(work) \
+ ({ init_completion(&work); work; })
+
#define DECLARE_COMPLETION(work) \
struct completion work = COMPLETION_INITIALIZER(work)
@@ -28,7 +31,7 @@
*/
#ifdef CONFIG_LOCKDEP
# define DECLARE_COMPLETION_ONSTACK(work) \
- struct completion work = ({ init_completion(&work); work; })
+ struct completion work = COMPLETION_INITIALIZER_ONSTACK(work)
#else
# define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
#endif
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index f8e5587..25423f7 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -9,6 +9,7 @@
* to achieve effects such as fast scrolling by changing the origin.
*/
+#include <linux/wait.h>
#include <linux/vt.h>
struct vt_struct;
diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
index 0cf0bea..9631ddd 100644
--- a/include/linux/elfcore.h
+++ b/include/linux/elfcore.h
@@ -60,6 +60,16 @@
long pr_instr; /* Current instruction */
#endif
elf_gregset_t pr_reg; /* GP registers */
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ /* When using FDPIC, the loadmap addresses need to be communicated
+ * to GDB in order for GDB to do the necessary relocations. The
+ * fields (below) used to communicate this information are placed
+ * immediately after ``pr_reg'', so that the loadmap addresses may
+ * be viewed as part of the register set if so desired.
+ */
+ unsigned long pr_exec_fdpic_loadmap;
+ unsigned long pr_interp_fdpic_loadmap;
+#endif
int pr_fpvalid; /* True if math co-processor being used. */
};
diff --git a/include/linux/fb.h b/include/linux/fb.h
index ffefeee..405f44e 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -377,7 +377,6 @@
#include <linux/fs.h>
#include <linux/init.h>
-#include <linux/tty.h>
#include <linux/device.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 43aef9b..2561020 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -27,6 +27,10 @@
#define BLOCK_SIZE_BITS 10
#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
+#define SEEK_SET 0 /* seek relative to beginning of file */
+#define SEEK_CUR 1 /* seek relative to current file position */
+#define SEEK_END 2 /* seek relative to end of file */
+
/* And dynamically-tunable limits and defaults: */
struct files_stat_struct {
int nr_files; /* read only */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5c1ec1f..181c69c 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -33,6 +33,7 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 316e0fb..c040a8c 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -120,7 +120,7 @@
*/
struct lockdep_map {
struct lock_class_key *key;
- struct lock_class *class[MAX_LOCKDEP_SUBCLASSES];
+ struct lock_class *class_cache;
const char *name;
};
diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
index bbc93ae..432b2fa 100644
--- a/include/linux/mc146818rtc.h
+++ b/include/linux/mc146818rtc.h
@@ -89,4 +89,11 @@
# define RTC_VRT 0x80 /* valid RAM and time */
/**********************************************************************/
+#ifndef ARCH_RTC_LOCATION /* Override by <asm/mc146818rtc.h>? */
+
+#define RTC_IO_EXTENT 0x8
+#define RTC_IOMAPPED 1 /* Default to I/O mapping. */
+
+#endif /* ARCH_RTC_LOCATION */
+
#endif /* _MC146818RTC_H */
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 5f681d5..db05182 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -157,6 +157,12 @@
OP_ILLEGAL = 10044,
};
+/*Defining first and last NFS4 operations implemented.
+Needs to be updated if more operations are defined in future.*/
+
+#define FIRST_NFS4_OP OP_ACCESS
+#define LAST_NFS4_OP OP_RELEASE_LOCKOWNER
+
enum nfsstat4 {
NFS4_OK = 0,
NFS4ERR_PERM = 1,
diff --git a/include/linux/nfsd/stats.h b/include/linux/nfsd/stats.h
index b6f1e0c..28a82fd 100644
--- a/include/linux/nfsd/stats.h
+++ b/include/linux/nfsd/stats.h
@@ -9,6 +9,8 @@
#ifndef LINUX_NFSD_STATS_H
#define LINUX_NFSD_STATS_H
+#include <linux/nfs4.h>
+
struct nfsd_stats {
unsigned int rchits; /* repcache hits */
unsigned int rcmisses; /* repcache hits */
@@ -27,6 +29,10 @@
unsigned int ra_size; /* size of ra cache */
unsigned int ra_depth[11]; /* number of times ra entry was found that deep
* in the cache (10percentiles). [10] = not found */
+#ifdef CONFIG_NFSD_V4
+ unsigned int nfs4_opcount[LAST_NFS4_OP + 1]; /* count of individual nfsv4 operations */
+#endif
+
};
/* thread usage wraps very million seconds (approx one fortnight) */
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index c1e0ac5..d288902 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -148,9 +148,10 @@
struct mdk_thread_s *thread; /* management thread */
struct mdk_thread_s *sync_thread; /* doing resync or reconstruct */
- sector_t curr_resync; /* blocks scheduled */
+ sector_t curr_resync; /* last block scheduled */
unsigned long resync_mark; /* a recent timestamp */
sector_t resync_mark_cnt;/* blocks written at resync_mark */
+ sector_t curr_mark_cnt; /* blocks scheduled now */
sector_t resync_max_sectors; /* may be set by personality */
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h
index 658afb3..7b524b4 100644
--- a/include/linux/rwsem.h
+++ b/include/linux/rwsem.h
@@ -61,12 +61,25 @@
#ifdef CONFIG_DEBUG_LOCK_ALLOC
/*
- * nested locking:
+ * nested locking. NOTE: rwsems are not allowed to recurse
+ * (which occurs if the same task tries to acquire the same
+ * lock instance multiple times), but multiple locks of the
+ * same lock class might be taken, if the order of the locks
+ * is always the same. This ordering rule can be expressed
+ * to lockdep via the _nested() APIs, but enumerating the
+ * subclasses that are used. (If the nesting relationship is
+ * static then another method for expressing nested locking is
+ * the explicit definition of lock class keys and the use of
+ * lockdep_set_class() at lock initialization time.
+ * See Documentation/lockdep-design.txt for more details.)
*/
extern void down_read_nested(struct rw_semaphore *sem, int subclass);
extern void down_write_nested(struct rw_semaphore *sem, int subclass);
/*
- * Take/release a lock when not the owner will release it:
+ * Take/release a lock when not the owner will release it.
+ *
+ * [ This API should be avoided as much as possible - the
+ * proper abstraction for this case is completions. ]
*/
extern void down_read_non_owner(struct rw_semaphore *sem);
extern void up_read_non_owner(struct rw_semaphore *sem);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index b3b807e..e421d5e 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -5,16 +5,6 @@
* 'tty.h' defines some structures used by tty_io.c and some defines.
*/
-/*
- * These constants are also useful for user-level apps (e.g., VC
- * resizing).
- */
-#define MIN_NR_CONSOLES 1 /* must be at least 1 */
-#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
-#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
- /* Note: the ioctl VT_GETSTATE does not work for
- consoles 16 and higher (since it returns a short) */
-
#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/major.h>
@@ -22,7 +12,6 @@
#include <linux/workqueue.h>
#include <linux/tty_driver.h>
#include <linux/tty_ldisc.h>
-#include <linux/screen_info.h>
#include <linux/mutex.h>
#include <asm/system.h>
@@ -270,7 +259,6 @@
extern void tty_write_flush(struct tty_struct *);
extern struct termios tty_std_termios;
-extern int fg_console, last_console, want_console;
extern int kmsg_redirect;
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 3e0daf5..1ab806c 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -57,7 +57,7 @@
static inline void count_vm_events(enum vm_event_item item, long delta)
{
- get_cpu_var(vm_event_states.event[item])++;
+ get_cpu_var(vm_event_states.event[item]) += delta;
put_cpu();
}
@@ -186,11 +186,16 @@
zone_page_state_add(delta, zone, item);
}
+static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
+{
+ atomic_long_inc(&zone->vm_stat[item]);
+ atomic_long_inc(&vm_stat[item]);
+}
+
static inline void __inc_zone_page_state(struct page *page,
enum zone_stat_item item)
{
- atomic_long_inc(&page_zone(page)->vm_stat[item]);
- atomic_long_inc(&vm_stat[item]);
+ __inc_zone_state(page_zone(page), item);
}
static inline void __dec_zone_page_state(struct page *page,
diff --git a/include/linux/vt.h b/include/linux/vt.h
index 9f95b0b..8ab334a 100644
--- a/include/linux/vt.h
+++ b/include/linux/vt.h
@@ -1,6 +1,16 @@
#ifndef _LINUX_VT_H
#define _LINUX_VT_H
+/*
+ * These constants are also useful for user-level apps (e.g., VC
+ * resizing).
+ */
+#define MIN_NR_CONSOLES 1 /* must be at least 1 */
+#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
+#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
+ /* Note: the ioctl VT_GETSTATE does not work for
+ consoles 16 and higher (since it returns a short) */
+
/* 0x56 is 'V', to avoid collision with termios and kd */
#define VT_OPENQRY 0x5600 /* find available vt */
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 940d026..918a297 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -26,6 +26,7 @@
extern void kd_mksound(unsigned int hz, unsigned int ticks);
extern int kbd_rate(struct kbd_repeat *rep);
+extern int fg_console, last_console, want_console;
/* console.c */
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 794be7a..b3b9048 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -77,17 +77,7 @@
#define __WAIT_BIT_KEY_INITIALIZER(word, bit) \
{ .flags = word, .bit_nr = bit, }
-/*
- * lockdep: we want one lock-class for all waitqueue locks.
- */
-extern struct lock_class_key waitqueue_lock_key;
-
-static inline void init_waitqueue_head(wait_queue_head_t *q)
-{
- spin_lock_init(&q->lock);
- lockdep_set_class(&q->lock, &waitqueue_lock_key);
- INIT_LIST_HEAD(&q->task_list);
-}
+extern void init_waitqueue_head(wait_queue_head_t *q);
static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
{
diff --git a/kernel/fork.c b/kernel/fork.c
index 56e4e07..926e5a6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -61,9 +61,7 @@
DEFINE_PER_CPU(unsigned long, process_counts) = 0;
- __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
-
-EXPORT_SYMBOL(tasklist_lock);
+__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
int nr_processes(void)
{
diff --git a/kernel/futex.c b/kernel/futex.c
index 1dc98e4..cf0c8e2 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -476,6 +476,12 @@
* the refcount and return its pi_state:
*/
pi_state = this->pi_state;
+ /*
+ * Userspace might have messed up non PI and PI futexes
+ */
+ if (unlikely(!pi_state))
+ return -EINVAL;
+
atomic_inc(&pi_state->refcount);
me->pi_state = pi_state;
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index f32ca78..9bad178 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -169,22 +169,17 @@
*/
static int class_filter(struct lock_class *class)
{
+#if 0
+ /* Example */
if (class->name_version == 1 &&
- !strcmp(class->name, "&rl->lock"))
+ !strcmp(class->name, "lockname"))
return 1;
if (class->name_version == 1 &&
- !strcmp(class->name, "&ni->mrec_lock"))
+ !strcmp(class->name, "&struct->lockfield"))
return 1;
- if (class->name_version == 1 &&
- !strcmp(class->name, "mft_ni_runlist_lock"))
- return 1;
- if (class->name_version == 1 &&
- !strcmp(class->name, "mft_ni_mrec_lock"))
- return 1;
- if (class->name_version == 1 &&
- !strcmp(class->name, "&vol->lcnbmp_lock"))
- return 1;
- return 0;
+#endif
+ /* Allow everything else. 0 would be filter everything else */
+ return 1;
}
#endif
@@ -408,23 +403,12 @@
print_lock(curr->held_locks + i);
}
}
-/*
- * Helper to print a nice hierarchy of lock dependencies:
- */
-static void print_spaces(int nr)
-{
- int i;
-
- for (i = 0; i < nr; i++)
- printk(" ");
-}
static void print_lock_class_header(struct lock_class *class, int depth)
{
int bit;
- print_spaces(depth);
- printk("->");
+ printk("%*s->", depth, "");
print_lock_name(class);
printk(" ops: %lu", class->ops);
printk(" {\n");
@@ -433,17 +417,14 @@
if (class->usage_mask & (1 << bit)) {
int len = depth;
- print_spaces(depth);
- len += printk(" %s", usage_str[bit]);
+ len += printk("%*s %s", depth, "", usage_str[bit]);
len += printk(" at:\n");
print_stack_trace(class->usage_traces + bit, len);
}
}
- print_spaces(depth);
- printk(" }\n");
+ printk("%*s }\n", depth, "");
- print_spaces(depth);
- printk(" ... key at: ");
+ printk("%*s ... key at: ",depth,"");
print_ip_sym((unsigned long)class->key);
}
@@ -463,8 +444,7 @@
DEBUG_LOCKS_WARN_ON(!entry->class);
print_lock_dependencies(entry->class, depth + 1);
- print_spaces(depth);
- printk(" ... acquired at:\n");
+ printk("%*s ... acquired at:\n",depth,"");
print_stack_trace(&entry->trace, 2);
printk("\n");
}
@@ -1124,7 +1104,7 @@
* itself, so actual lookup of the hash should be once per lock object.
*/
static inline struct lock_class *
-register_lock_class(struct lockdep_map *lock, unsigned int subclass)
+look_up_lock_class(struct lockdep_map *lock, unsigned int subclass)
{
struct lockdep_subclass_key *key;
struct list_head *hash_head;
@@ -1168,7 +1148,26 @@
*/
list_for_each_entry(class, hash_head, hash_entry)
if (class->key == key)
- goto out_set;
+ return class;
+
+ return NULL;
+}
+
+/*
+ * Register a lock's class in the hash-table, if the class is not present
+ * yet. Otherwise we look it up. We cache the result in the lock object
+ * itself, so actual lookup of the hash should be once per lock object.
+ */
+static inline struct lock_class *
+register_lock_class(struct lockdep_map *lock, unsigned int subclass)
+{
+ struct lockdep_subclass_key *key;
+ struct list_head *hash_head;
+ struct lock_class *class;
+
+ class = look_up_lock_class(lock, subclass);
+ if (likely(class))
+ return class;
/*
* Debug-check: all keys must be persistent!
@@ -1183,6 +1182,9 @@
return NULL;
}
+ key = lock->key->subkeys + subclass;
+ hash_head = classhashentry(key);
+
__raw_spin_lock(&hash_lock);
/*
* We have to do the hash-walk again, to avoid races
@@ -1229,8 +1231,8 @@
out_unlock_set:
__raw_spin_unlock(&hash_lock);
-out_set:
- lock->class[subclass] = class;
+ if (!subclass)
+ lock->class_cache = class;
DEBUG_LOCKS_WARN_ON(class->subclass != subclass);
@@ -1934,7 +1936,7 @@
}
lock->name = name;
lock->key = key;
- memset(lock->class, 0, sizeof(lock->class[0])*MAX_LOCKDEP_SUBCLASSES);
+ lock->class_cache = NULL;
}
EXPORT_SYMBOL_GPL(lockdep_init_map);
@@ -1948,8 +1950,8 @@
unsigned long ip)
{
struct task_struct *curr = current;
+ struct lock_class *class = NULL;
struct held_lock *hlock;
- struct lock_class *class;
unsigned int depth, id;
int chain_head = 0;
u64 chain_key;
@@ -1967,8 +1969,11 @@
return 0;
}
- class = lock->class[subclass];
- /* not cached yet? */
+ if (!subclass)
+ class = lock->class_cache;
+ /*
+ * Not cached yet or subclass?
+ */
if (unlikely(!class)) {
class = register_lock_class(lock, subclass);
if (!class)
@@ -2469,48 +2474,44 @@
void lockdep_reset_lock(struct lockdep_map *lock)
{
- struct lock_class *class, *next, *entry;
+ struct lock_class *class, *next;
struct list_head *head;
unsigned long flags;
int i, j;
raw_local_irq_save(flags);
- __raw_spin_lock(&hash_lock);
/*
- * Remove all classes this lock has:
+ * Remove all classes this lock might have:
*/
+ for (j = 0; j < MAX_LOCKDEP_SUBCLASSES; j++) {
+ /*
+ * If the class exists we look it up and zap it:
+ */
+ class = look_up_lock_class(lock, j);
+ if (class)
+ zap_class(class);
+ }
+ /*
+ * Debug check: in the end all mapped classes should
+ * be gone.
+ */
+ __raw_spin_lock(&hash_lock);
for (i = 0; i < CLASSHASH_SIZE; i++) {
head = classhash_table + i;
if (list_empty(head))
continue;
list_for_each_entry_safe(class, next, head, hash_entry) {
- for (j = 0; j < MAX_LOCKDEP_SUBCLASSES; j++) {
- entry = lock->class[j];
- if (class == entry) {
- zap_class(class);
- lock->class[j] = NULL;
- break;
- }
+ if (unlikely(class == lock->class_cache)) {
+ __raw_spin_unlock(&hash_lock);
+ DEBUG_LOCKS_WARN_ON(1);
+ goto out_restore;
}
}
}
-
- /*
- * Debug check: in the end all mapped classes should
- * be gone.
- */
- for (j = 0; j < MAX_LOCKDEP_SUBCLASSES; j++) {
- entry = lock->class[j];
- if (!entry)
- continue;
- __raw_spin_unlock(&hash_lock);
- DEBUG_LOCKS_WARN_ON(1);
- raw_local_irq_restore(flags);
- return;
- }
-
__raw_spin_unlock(&hash_lock);
+
+out_restore:
raw_local_irq_restore(flags);
}
@@ -2571,7 +2572,7 @@
static void
print_freed_lock_bug(struct task_struct *curr, const void *mem_from,
- const void *mem_to)
+ const void *mem_to, struct held_lock *hlock)
{
if (!debug_locks_off())
return;
@@ -2583,6 +2584,7 @@
printk( "-------------------------\n");
printk("%s/%d is freeing memory %p-%p, with a lock still held there!\n",
curr->comm, curr->pid, mem_from, mem_to-1);
+ print_lock(hlock);
lockdep_print_held_locks(curr);
printk("\nstack backtrace:\n");
@@ -2616,7 +2618,7 @@
!in_range(mem_from, lock_to, mem_to))
continue;
- print_freed_lock_bug(curr, mem_from, mem_to);
+ print_freed_lock_bug(curr, mem_from, mem_to, hlock);
break;
}
local_irq_restore(flags);
diff --git a/kernel/panic.c b/kernel/panic.c
index ab13f0f..d8a0bca 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -172,6 +172,7 @@
void add_taint(unsigned flag)
{
+ debug_locks_off(); /* can't trust the integrity of the kernel anymore */
tainted |= flag;
}
EXPORT_SYMBOL(add_taint);
@@ -256,6 +257,7 @@
*/
void oops_enter(void)
{
+ debug_locks_off(); /* can't trust the integrity of the kernel anymore */
do_oops_enter_exit();
}
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 24c96f3..75d4886 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -227,11 +227,17 @@
for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
if (saveable(zone, &zone_pfn)) {
struct page *page;
+ long *src, *dst;
+ int n;
+
page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
BUG_ON(!pbe);
pbe->orig_address = (unsigned long)page_address(page);
- /* copy_page is not usable for copying task structs. */
- memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
+ /* copy_page and memcpy are not usable for copying task structs. */
+ dst = (long *)pbe->address;
+ src = (long *)pbe->orig_address;
+ for (n = PAGE_SIZE / sizeof(long); n; n--)
+ *dst++ = *src++;
pbe = pbe->next;
}
}
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 044b8e0..f1dd146b 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -263,7 +263,6 @@
struct swap_map_handle handle;
struct snapshot_handle snapshot;
struct swsusp_info *header;
- unsigned long start;
int error;
if ((error = swsusp_swap_check())) {
@@ -281,16 +280,17 @@
}
error = get_swap_writer(&handle);
if (!error) {
- start = handle.cur_swap;
+ unsigned long start = handle.cur_swap;
error = swap_write_page(&handle, header);
- }
- if (!error)
- error = save_image(&handle, &snapshot, header->pages - 1);
- if (!error) {
- flush_swap_writer(&handle);
- printk("S");
- error = mark_swapfiles(swp_entry(root_swap, start));
- printk("|\n");
+ if (!error)
+ error = save_image(&handle, &snapshot,
+ header->pages - 1);
+ if (!error) {
+ flush_swap_writer(&handle);
+ printk("S");
+ error = mark_swapfiles(swp_entry(root_swap, start));
+ printk("|\n");
+ }
}
if (error)
free_all_swap_pages(root_swap, handle.bitmap);
@@ -311,8 +311,10 @@
static int end_io(struct bio *bio, unsigned int num, int err)
{
- if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
- panic("I/O error reading memory image");
+ if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+ printk(KERN_ERR "I/O error reading swsusp image.\n");
+ return -EIO;
+ }
atomic_set(&io_done, 0);
return 0;
}
diff --git a/kernel/printk.c b/kernel/printk.c
index bdba5d8..65ca068 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -52,7 +52,7 @@
DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */
};
-EXPORT_SYMBOL(console_printk);
+EXPORT_UNUSED_SYMBOL(console_printk); /* June 2006 */
/*
* Low lever drivers may need that to know if they can schedule in
@@ -773,7 +773,7 @@
{
return console_locked;
}
-EXPORT_SYMBOL(is_console_locked);
+EXPORT_UNUSED_SYMBOL(is_console_locked); /* June 2006 */
/**
* release_console_sem - unlock the console system
diff --git a/kernel/sched.c b/kernel/sched.c
index 4ee400f..d714611 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3384,7 +3384,7 @@
#ifdef CONFIG_PREEMPT
/*
- * this is is the entry point to schedule() from in-kernel preemption
+ * this is the entry point to schedule() from in-kernel preemption
* off of preempt_enable. Kernel preemptions off return from interrupt
* occur there and call schedule directly.
*/
@@ -3427,7 +3427,7 @@
EXPORT_SYMBOL(preempt_schedule);
/*
- * this is is the entry point to schedule() from kernel preemption
+ * this is the entry point to schedule() from kernel preemption
* off of irq context.
* Note, that this is called and return with irqs disabled. This will
* protect us against recursive calling from irq.
@@ -3439,7 +3439,7 @@
struct task_struct *task = current;
int saved_lock_depth;
#endif
- /* Catch callers which need to be fixed*/
+ /* Catch callers which need to be fixed */
BUG_ON(ti->preempt_count || !irqs_disabled());
need_resched:
@@ -4650,7 +4650,7 @@
return list_entry(p->sibling.next,struct task_struct,sibling);
}
-static const char *stat_nam[] = { "R", "S", "D", "T", "t", "Z", "X" };
+static const char stat_nam[] = "RSDTtZX";
static void show_task(struct task_struct *p)
{
@@ -4658,12 +4658,9 @@
unsigned long free = 0;
unsigned state;
- printk("%-13.13s ", p->comm);
state = p->state ? __ffs(p->state) + 1 : 0;
- if (state < ARRAY_SIZE(stat_nam))
- printk(stat_nam[state]);
- else
- printk("?");
+ printk("%-13.13s %c", p->comm,
+ state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
#if (BITS_PER_LONG == 32)
if (state == TASK_RUNNING)
printk(" running ");
@@ -4877,7 +4874,7 @@
p->timestamp = p->timestamp - rq_src->timestamp_last_tick
+ rq_dest->timestamp_last_tick;
deactivate_task(p, rq_src);
- activate_task(p, rq_dest, 0);
+ __activate_task(p, rq_dest);
if (TASK_PREEMPTS_CURR(p, rq_dest))
resched_task(rq_dest->curr);
}
@@ -5776,7 +5773,7 @@
cache = vmalloc(max_size);
if (!cache) {
printk("could not vmalloc %d bytes for cache!\n", 2*max_size);
- return 1000000; // return 1 msec on very small boxen
+ return 1000000; /* return 1 msec on very small boxen */
}
while (size <= max_size) {
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 215541e..fd12f25 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -311,7 +311,7 @@
softirq_vec[nr].action = action;
}
-EXPORT_SYMBOL(open_softirq);
+EXPORT_UNUSED_SYMBOL(open_softirq); /* June 2006 */
/* Tasklets */
struct tasklet_head
diff --git a/kernel/timer.c b/kernel/timer.c
index 396a3c0..2a87430 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -891,6 +891,7 @@
set_normalized_timespec(&xtime, sec, nsec);
set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+ clock->error = 0;
ntp_clear();
write_sequnlock_irqrestore(&xtime_lock, flags);
@@ -1008,52 +1009,52 @@
device_initcall(timekeeping_init_device);
/*
- * If the error is already larger, we look ahead another tick,
+ * If the error is already larger, we look ahead even further
* to compensate for late or lost adjustments.
*/
-static __always_inline int clocksource_bigadjust(int sign, s64 error, s64 *interval, s64 *offset)
+static __always_inline int clocksource_bigadjust(s64 error, s64 *interval, s64 *offset)
{
- int adj;
+ s64 tick_error, i;
+ u32 look_ahead, adj;
+ s32 error2, mult;
/*
- * As soon as the machine is synchronized to the external time
- * source this should be the common case.
+ * Use the current error value to determine how much to look ahead.
+ * The larger the error the slower we adjust for it to avoid problems
+ * with losing too many ticks, otherwise we would overadjust and
+ * produce an even larger error. The smaller the adjustment the
+ * faster we try to adjust for it, as lost ticks can do less harm
+ * here. This is tuned so that an error of about 1 msec is adusted
+ * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
*/
- error >>= 2;
- if (likely(sign > 0 ? error <= *interval : error >= *interval))
- return sign;
+ error2 = clock->error >> (TICK_LENGTH_SHIFT + 22 - 2 * SHIFT_HZ);
+ error2 = abs(error2);
+ for (look_ahead = 0; error2 > 0; look_ahead++)
+ error2 >>= 2;
/*
- * An extra look ahead dampens the effect of the current error,
- * which can grow quite large with continously late updates, as
- * it would dominate the adjustment value and can lead to
- * oscillation.
+ * Now calculate the error in (1 << look_ahead) ticks, but first
+ * remove the single look ahead already included in the error.
*/
- error += current_tick_length() >> (TICK_LENGTH_SHIFT - clock->shift + 1);
- error -= clock->xtime_interval >> 1;
+ tick_error = current_tick_length() >> (TICK_LENGTH_SHIFT - clock->shift + 1);
+ tick_error -= clock->xtime_interval >> 1;
+ error = ((error - tick_error) >> look_ahead) + tick_error;
- adj = 0;
- while (1) {
- error >>= 1;
- if (sign > 0 ? error <= *interval : error >= *interval)
- break;
- adj++;
+ /* Finally calculate the adjustment shift value. */
+ i = *interval;
+ mult = 1;
+ if (error < 0) {
+ error = -error;
+ *interval = -*interval;
+ *offset = -*offset;
+ mult = -1;
}
-
- /*
- * Add the current adjustments to the error and take the offset
- * into account, the latter can cause the error to be hardly
- * reduced at the next tick. Check the error again if there's
- * room for another adjustment, thus further reducing the error
- * which otherwise had to be corrected at the next update.
- */
- error = (error << 1) - *interval + *offset;
- if (sign > 0 ? error > *interval : error < *interval)
- adj++;
+ for (adj = 0; error > i; adj++)
+ error >>= 1;
*interval <<= adj;
*offset <<= adj;
- return sign << adj;
+ return mult << adj;
}
/*
@@ -1068,11 +1069,19 @@
error = clock->error >> (TICK_LENGTH_SHIFT - clock->shift - 1);
if (error > interval) {
- adj = clocksource_bigadjust(1, error, &interval, &offset);
+ error >>= 2;
+ if (likely(error <= interval))
+ adj = 1;
+ else
+ adj = clocksource_bigadjust(error, &interval, &offset);
} else if (error < -interval) {
- interval = -interval;
- offset = -offset;
- adj = clocksource_bigadjust(-1, error, &interval, &offset);
+ error >>= 2;
+ if (likely(error >= -interval)) {
+ adj = -1;
+ interval = -interval;
+ offset = -offset;
+ } else
+ adj = clocksource_bigadjust(error, &interval, &offset);
} else
return;
@@ -1129,7 +1138,7 @@
clocksource_adjust(clock, offset);
/* store full nanoseconds into xtime */
- xtime.tv_nsec = clock->xtime_nsec >> clock->shift;
+ xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
/* check to see if there is a new clocksource to use */
diff --git a/kernel/wait.c b/kernel/wait.c
index a1d57ae..59a82f6 100644
--- a/kernel/wait.c
+++ b/kernel/wait.c
@@ -10,9 +10,13 @@
#include <linux/wait.h>
#include <linux/hash.h>
-struct lock_class_key waitqueue_lock_key;
+void init_waitqueue_head(wait_queue_head_t *q)
+{
+ spin_lock_init(&q->lock);
+ INIT_LIST_HEAD(&q->task_list);
+}
-EXPORT_SYMBOL(waitqueue_lock_key);
+EXPORT_SYMBOL(init_waitqueue_head);
void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
{
diff --git a/mm/bootmem.c b/mm/bootmem.c
index d213fed..50353e0 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -29,9 +29,7 @@
unsigned long min_low_pfn;
unsigned long max_pfn;
-EXPORT_SYMBOL(max_pfn); /* This is exported so
- * dma_get_required_mask(), which uses
- * it, can be an inline function */
+EXPORT_UNUSED_SYMBOL(max_pfn); /* June 2006 */
static LIST_HEAD(bdata_list);
#ifdef CONFIG_CRASH_DUMP
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 0a03357..60a5d55 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -23,18 +23,6 @@
/*
* POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
* deactivate the pages and clear PG_Referenced.
- *
- * LINUX_FADV_ASYNC_WRITE: start async writeout of any dirty pages between file
- * offsets `offset' and `offset+len' inclusive. Any pages which are currently
- * under writeout are skipped, whether or not they are dirty.
- *
- * LINUX_FADV_WRITE_WAIT: wait upon writeout of any dirty pages between file
- * offsets `offset' and `offset+len'.
- *
- * By combining these two operations the application may do several things:
- *
- * LINUX_FADV_ASYNC_WRITE: push some or all of the dirty pages at the disk.
- *
*/
asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
{
diff --git a/mm/memory.c b/mm/memory.c
index c1e14c9..dc0d82c 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1853,7 +1853,7 @@
return 0;
}
-EXPORT_SYMBOL(vmtruncate_range);
+EXPORT_UNUSED_SYMBOL(vmtruncate_range); /* June 2006 */
/*
* Primitive swap readahead code. We simply read an aligned block of
diff --git a/mm/mmzone.c b/mm/mmzone.c
index 0959ee1..febea1c 100644
--- a/mm/mmzone.c
+++ b/mm/mmzone.c
@@ -14,7 +14,7 @@
return NODE_DATA(first_online_node);
}
-EXPORT_SYMBOL(first_online_pgdat);
+EXPORT_UNUSED_SYMBOL(first_online_pgdat); /* June 2006 */
struct pglist_data *next_online_pgdat(struct pglist_data *pgdat)
{
@@ -24,7 +24,7 @@
return NULL;
return NODE_DATA(nid);
}
-EXPORT_SYMBOL(next_online_pgdat);
+EXPORT_UNUSED_SYMBOL(next_online_pgdat); /* June 2006 */
/*
@@ -45,5 +45,5 @@
}
return zone;
}
-EXPORT_SYMBOL(next_zone);
+EXPORT_UNUSED_SYMBOL(next_zone); /* June 2006 */
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 73b83d6..dfdf241 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -81,6 +81,7 @@
{
sum_vm_events(ret, &cpu_online_map);
}
+EXPORT_SYMBOL_GPL(all_vm_events);
#ifdef CONFIG_HOTPLUG
/*
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index 4cf8754..e9d9429 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -102,8 +102,8 @@
int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
{
int (*func)(struct sk_buff *, ax25_cb *);
- volatile int queued = 0;
unsigned char pid;
+ int queued = 0;
if (skb == NULL) return 0;
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index f4f0627..6f14bb5 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -484,7 +484,7 @@
err = -EINVAL;
else
err = dccp_setsockopt_change(sk, DCCPO_CHANGE_L,
- (struct dccp_so_feat *)
+ (struct dccp_so_feat __user *)
optval);
break;
@@ -493,7 +493,7 @@
err = -EINVAL;
else
err = dccp_setsockopt_change(sk, DCCPO_CHANGE_R,
- (struct dccp_so_feat *)
+ (struct dccp_so_feat __user *)
optval);
break;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index da33393..8514106 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -572,16 +572,6 @@
loss packets.
See http://www.ntu.edu.sg/home5/ZHOU0022/papers/CPFu03a.pdf
-config TCP_CONG_COMPOUND
- tristate "TCP Compound"
- depends on EXPERIMENTAL
- default n
- ---help---
- TCP Compound is a sender-side only change to TCP that uses
- a mixed Reno/Vegas approach to calculate the cwnd.
- For further details look here:
- ftp://ftp.research.microsoft.com/pub/tr/TR-2005-86.pdf
-
endmenu
config TCP_CONG_BIC
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 38b8039..4878fc5 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -47,7 +47,6 @@
obj-$(CONFIG_TCP_CONG_VENO) += tcp_veno.o
obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
-obj-$(CONFIG_TCP_CONG_COMPOUND) += tcp_compound.o
obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
xfrm4_output.o
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 2160874..03ff62e 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -86,7 +86,7 @@
static DEFINE_RWLOCK(peer_pool_lock);
#define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */
-static volatile int peer_total;
+static int peer_total;
/* Exported for sysctl_net_ipv4. */
int inet_peer_threshold = 65536 + 128; /* start to throw entries more
* aggressively at this stage */
diff --git a/net/ipv4/tcp_compound.c b/net/ipv4/tcp_compound.c
deleted file mode 100644
index bc54f7e..0000000
--- a/net/ipv4/tcp_compound.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * TCP Vegas congestion control
- *
- * This is based on the congestion detection/avoidance scheme described in
- * Lawrence S. Brakmo and Larry L. Peterson.
- * "TCP Vegas: End to end congestion avoidance on a global internet."
- * IEEE Journal on Selected Areas in Communication, 13(8):1465--1480,
- * October 1995. Available from:
- * ftp://ftp.cs.arizona.edu/xkernel/Papers/jsac.ps
- *
- * See http://www.cs.arizona.edu/xkernel/ for their implementation.
- * The main aspects that distinguish this implementation from the
- * Arizona Vegas implementation are:
- * o We do not change the loss detection or recovery mechanisms of
- * Linux in any way. Linux already recovers from losses quite well,
- * using fine-grained timers, NewReno, and FACK.
- * o To avoid the performance penalty imposed by increasing cwnd
- * only every-other RTT during slow start, we increase during
- * every RTT during slow start, just like Reno.
- * o Largely to allow continuous cwnd growth during slow start,
- * we use the rate at which ACKs come back as the "actual"
- * rate, rather than the rate at which data is sent.
- * o To speed convergence to the right rate, we set the cwnd
- * to achieve the right ("actual") rate when we exit slow start.
- * o To filter out the noise caused by delayed ACKs, we use the
- * minimum RTT sample observed during the last RTT to calculate
- * the actual rate.
- * o When the sender re-starts from idle, it waits until it has
- * received ACKs for an entire flight of new data before making
- * a cwnd adjustment decision. The original Vegas implementation
- * assumed senders never went idle.
- *
- *
- * TCP Compound based on TCP Vegas
- *
- * further details can be found here:
- * ftp://ftp.research.microsoft.com/pub/tr/TR-2005-86.pdf
- */
-
-#include <linux/config.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/inet_diag.h>
-
-#include <net/tcp.h>
-
-/* Default values of the Vegas variables, in fixed-point representation
- * with V_PARAM_SHIFT bits to the right of the binary point.
- */
-#define V_PARAM_SHIFT 1
-
-#define TCP_COMPOUND_ALPHA 3U
-#define TCP_COMPOUND_BETA 1U
-#define TCP_COMPOUND_GAMMA 30
-#define TCP_COMPOUND_ZETA 1
-
-/* TCP compound variables */
-struct compound {
- u32 beg_snd_nxt; /* right edge during last RTT */
- u32 beg_snd_una; /* left edge during last RTT */
- u32 beg_snd_cwnd; /* saves the size of the cwnd */
- u8 doing_vegas_now; /* if true, do vegas for this RTT */
- u16 cntRTT; /* # of RTTs measured within last RTT */
- u32 minRTT; /* min of RTTs measured within last RTT (in usec) */
- u32 baseRTT; /* the min of all Vegas RTT measurements seen (in usec) */
-
- u32 cwnd;
- u32 dwnd;
-};
-
-/* There are several situations when we must "re-start" Vegas:
- *
- * o when a connection is established
- * o after an RTO
- * o after fast recovery
- * o when we send a packet and there is no outstanding
- * unacknowledged data (restarting an idle connection)
- *
- * In these circumstances we cannot do a Vegas calculation at the
- * end of the first RTT, because any calculation we do is using
- * stale info -- both the saved cwnd and congestion feedback are
- * stale.
- *
- * Instead we must wait until the completion of an RTT during
- * which we actually receive ACKs.
- */
-static inline void vegas_enable(struct sock *sk)
-{
- const struct tcp_sock *tp = tcp_sk(sk);
- struct compound *vegas = inet_csk_ca(sk);
-
- /* Begin taking Vegas samples next time we send something. */
- vegas->doing_vegas_now = 1;
-
- /* Set the beginning of the next send window. */
- vegas->beg_snd_nxt = tp->snd_nxt;
-
- vegas->cntRTT = 0;
- vegas->minRTT = 0x7fffffff;
-}
-
-/* Stop taking Vegas samples for now. */
-static inline void vegas_disable(struct sock *sk)
-{
- struct compound *vegas = inet_csk_ca(sk);
-
- vegas->doing_vegas_now = 0;
-}
-
-static void tcp_compound_init(struct sock *sk)
-{
- struct compound *vegas = inet_csk_ca(sk);
- const struct tcp_sock *tp = tcp_sk(sk);
-
- vegas->baseRTT = 0x7fffffff;
- vegas_enable(sk);
-
- vegas->dwnd = 0;
- vegas->cwnd = tp->snd_cwnd;
-}
-
-/* Do RTT sampling needed for Vegas.
- * Basically we:
- * o min-filter RTT samples from within an RTT to get the current
- * propagation delay + queuing delay (we are min-filtering to try to
- * avoid the effects of delayed ACKs)
- * o min-filter RTT samples from a much longer window (forever for now)
- * to find the propagation delay (baseRTT)
- */
-static void tcp_compound_rtt_calc(struct sock *sk, u32 usrtt)
-{
- struct compound *vegas = inet_csk_ca(sk);
- u32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */
-
- /* Filter to find propagation delay: */
- if (vrtt < vegas->baseRTT)
- vegas->baseRTT = vrtt;
-
- /* Find the min RTT during the last RTT to find
- * the current prop. delay + queuing delay:
- */
-
- vegas->minRTT = min(vegas->minRTT, vrtt);
- vegas->cntRTT++;
-}
-
-static void tcp_compound_state(struct sock *sk, u8 ca_state)
-{
-
- if (ca_state == TCP_CA_Open)
- vegas_enable(sk);
- else
- vegas_disable(sk);
-}
-
-
-/* 64bit divisor, dividend and result. dynamic precision */
-static inline u64 div64_64(u64 dividend, u64 divisor)
-{
- u32 d = divisor;
-
- if (divisor > 0xffffffffULL) {
- unsigned int shift = fls(divisor >> 32);
-
- d = divisor >> shift;
- dividend >>= shift;
- }
-
- /* avoid 64 bit division if possible */
- if (dividend >> 32)
- do_div(dividend, d);
- else
- dividend = (u32) dividend / d;
-
- return dividend;
-}
-
-/* calculate the quartic root of "a" using Newton-Raphson */
-static u32 qroot(u64 a)
-{
- u32 x, x1;
-
- /* Initial estimate is based on:
- * qrt(x) = exp(log(x) / 4)
- */
- x = 1u << (fls64(a) >> 2);
-
- /*
- * Iteration based on:
- * 3
- * x = ( 3 * x + a / x ) / 4
- * k+1 k k
- */
- do {
- u64 x3 = x;
-
- x1 = x;
- x3 *= x;
- x3 *= x;
-
- x = (3 * x + (u32) div64_64(a, x3)) / 4;
- } while (abs(x1 - x) > 1);
-
- return x;
-}
-
-
-/*
- * If the connection is idle and we are restarting,
- * then we don't want to do any Vegas calculations
- * until we get fresh RTT samples. So when we
- * restart, we reset our Vegas state to a clean
- * slate. After we get acks for this flight of
- * packets, _then_ we can make Vegas calculations
- * again.
- */
-static void tcp_compound_cwnd_event(struct sock *sk, enum tcp_ca_event event)
-{
- if (event == CA_EVENT_CWND_RESTART || event == CA_EVENT_TX_START)
- tcp_compound_init(sk);
-}
-
-static void tcp_compound_cong_avoid(struct sock *sk, u32 ack,
- u32 seq_rtt, u32 in_flight, int flag)
-{
- struct tcp_sock *tp = tcp_sk(sk);
- struct compound *vegas = inet_csk_ca(sk);
- u8 inc = 0;
-
- if (vegas->cwnd + vegas->dwnd > tp->snd_cwnd) {
- if (vegas->cwnd > tp->snd_cwnd || vegas->dwnd > tp->snd_cwnd) {
- vegas->cwnd = tp->snd_cwnd;
- vegas->dwnd = 0;
- } else
- vegas->cwnd = tp->snd_cwnd - vegas->dwnd;
-
- }
-
- if (!tcp_is_cwnd_limited(sk, in_flight))
- return;
-
- if (vegas->cwnd <= tp->snd_ssthresh)
- inc = 1;
- else if (tp->snd_cwnd_cnt < tp->snd_cwnd)
- tp->snd_cwnd_cnt++;
-
- if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
- inc = 1;
- tp->snd_cwnd_cnt = 0;
- }
-
- if (inc && tp->snd_cwnd < tp->snd_cwnd_clamp)
- vegas->cwnd++;
-
- /* The key players are v_beg_snd_una and v_beg_snd_nxt.
- *
- * These are so named because they represent the approximate values
- * of snd_una and snd_nxt at the beginning of the current RTT. More
- * precisely, they represent the amount of data sent during the RTT.
- * At the end of the RTT, when we receive an ACK for v_beg_snd_nxt,
- * we will calculate that (v_beg_snd_nxt - v_beg_snd_una) outstanding
- * bytes of data have been ACKed during the course of the RTT, giving
- * an "actual" rate of:
- *
- * (v_beg_snd_nxt - v_beg_snd_una) / (rtt duration)
- *
- * Unfortunately, v_beg_snd_una is not exactly equal to snd_una,
- * because delayed ACKs can cover more than one segment, so they
- * don't line up nicely with the boundaries of RTTs.
- *
- * Another unfortunate fact of life is that delayed ACKs delay the
- * advance of the left edge of our send window, so that the number
- * of bytes we send in an RTT is often less than our cwnd will allow.
- * So we keep track of our cwnd separately, in v_beg_snd_cwnd.
- */
-
- if (after(ack, vegas->beg_snd_nxt)) {
- /* Do the Vegas once-per-RTT cwnd adjustment. */
- u32 old_wnd, old_snd_cwnd;
-
- /* Here old_wnd is essentially the window of data that was
- * sent during the previous RTT, and has all
- * been acknowledged in the course of the RTT that ended
- * with the ACK we just received. Likewise, old_snd_cwnd
- * is the cwnd during the previous RTT.
- */
- if (!tp->mss_cache)
- return;
-
- old_wnd = (vegas->beg_snd_nxt - vegas->beg_snd_una) /
- tp->mss_cache;
- old_snd_cwnd = vegas->beg_snd_cwnd;
-
- /* Save the extent of the current window so we can use this
- * at the end of the next RTT.
- */
- vegas->beg_snd_una = vegas->beg_snd_nxt;
- vegas->beg_snd_nxt = tp->snd_nxt;
- vegas->beg_snd_cwnd = tp->snd_cwnd;
-
- /* We do the Vegas calculations only if we got enough RTT
- * samples that we can be reasonably sure that we got
- * at least one RTT sample that wasn't from a delayed ACK.
- * If we only had 2 samples total,
- * then that means we're getting only 1 ACK per RTT, which
- * means they're almost certainly delayed ACKs.
- * If we have 3 samples, we should be OK.
- */
-
- if (vegas->cntRTT > 2) {
- u32 rtt, target_cwnd, diff;
- u32 brtt, dwnd;
-
- /* We have enough RTT samples, so, using the Vegas
- * algorithm, we determine if we should increase or
- * decrease cwnd, and by how much.
- */
-
- /* Pluck out the RTT we are using for the Vegas
- * calculations. This is the min RTT seen during the
- * last RTT. Taking the min filters out the effects
- * of delayed ACKs, at the cost of noticing congestion
- * a bit later.
- */
- rtt = vegas->minRTT;
-
- /* Calculate the cwnd we should have, if we weren't
- * going too fast.
- *
- * This is:
- * (actual rate in segments) * baseRTT
- * We keep it as a fixed point number with
- * V_PARAM_SHIFT bits to the right of the binary point.
- */
- if (!rtt)
- return;
-
- brtt = vegas->baseRTT;
- target_cwnd = ((old_wnd * brtt)
- << V_PARAM_SHIFT) / rtt;
-
- /* Calculate the difference between the window we had,
- * and the window we would like to have. This quantity
- * is the "Diff" from the Arizona Vegas papers.
- *
- * Again, this is a fixed point number with
- * V_PARAM_SHIFT bits to the right of the binary
- * point.
- */
-
- diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
-
- dwnd = vegas->dwnd;
-
- if (diff < (TCP_COMPOUND_GAMMA << V_PARAM_SHIFT)) {
- u64 v;
- u32 x;
-
- /*
- * The TCP Compound paper describes the choice
- * of "k" determines the agressiveness,
- * ie. slope of the response function.
- *
- * For same value as HSTCP would be 0.8
- * but for computaional reasons, both the
- * original authors and this implementation
- * use 0.75.
- */
- v = old_wnd;
- x = qroot(v * v * v) >> TCP_COMPOUND_ALPHA;
- if (x > 1)
- dwnd = x - 1;
- else
- dwnd = 0;
-
- dwnd += vegas->dwnd;
-
- } else if ((dwnd << V_PARAM_SHIFT) <
- (diff * TCP_COMPOUND_BETA))
- dwnd = 0;
- else
- dwnd =
- ((dwnd << V_PARAM_SHIFT) -
- (diff *
- TCP_COMPOUND_BETA)) >> V_PARAM_SHIFT;
-
- vegas->dwnd = dwnd;
-
- }
-
- /* Wipe the slate clean for the next RTT. */
- vegas->cntRTT = 0;
- vegas->minRTT = 0x7fffffff;
- }
-
- tp->snd_cwnd = vegas->cwnd + vegas->dwnd;
-}
-
-/* Extract info for Tcp socket info provided via netlink. */
-static void tcp_compound_get_info(struct sock *sk, u32 ext, struct sk_buff *skb)
-{
- const struct compound *ca = inet_csk_ca(sk);
- if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
- struct tcpvegas_info *info;
-
- info = RTA_DATA(__RTA_PUT(skb, INET_DIAG_VEGASINFO,
- sizeof(*info)));
-
- info->tcpv_enabled = ca->doing_vegas_now;
- info->tcpv_rttcnt = ca->cntRTT;
- info->tcpv_rtt = ca->baseRTT;
- info->tcpv_minrtt = ca->minRTT;
- rtattr_failure:;
- }
-}
-
-static struct tcp_congestion_ops tcp_compound = {
- .init = tcp_compound_init,
- .ssthresh = tcp_reno_ssthresh,
- .cong_avoid = tcp_compound_cong_avoid,
- .rtt_sample = tcp_compound_rtt_calc,
- .set_state = tcp_compound_state,
- .cwnd_event = tcp_compound_cwnd_event,
- .get_info = tcp_compound_get_info,
-
- .owner = THIS_MODULE,
- .name = "compound",
-};
-
-static int __init tcp_compound_register(void)
-{
- BUG_ON(sizeof(struct compound) > ICSK_CA_PRIV_SIZE);
- tcp_register_congestion_control(&tcp_compound);
- return 0;
-}
-
-static void __exit tcp_compound_unregister(void)
-{
- tcp_unregister_congestion_control(&tcp_compound);
-}
-
-module_init(tcp_compound_register);
-module_exit(tcp_compound_unregister);
-
-MODULE_AUTHOR("Angelo P. Castellani, Stephen Hemminger");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("TCP Compound");
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 24caaee..2e8b4df 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -246,6 +246,7 @@
sbsec->sb = sb;
sbsec->sid = SECINITSID_UNLABELED;
sbsec->def_sid = SECINITSID_FILE;
+ sbsec->mntpoint_sid = SECINITSID_UNLABELED;
sb->s_security = sbsec;
return 0;
@@ -319,19 +320,53 @@
Opt_context = 1,
Opt_fscontext = 2,
Opt_defcontext = 4,
+ Opt_rootcontext = 8,
};
static match_table_t tokens = {
{Opt_context, "context=%s"},
{Opt_fscontext, "fscontext=%s"},
{Opt_defcontext, "defcontext=%s"},
+ {Opt_rootcontext, "rootcontext=%s"},
};
#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
+static int may_context_mount_sb_relabel(u32 sid,
+ struct superblock_security_struct *sbsec,
+ struct task_security_struct *tsec)
+{
+ int rc;
+
+ rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+ FILESYSTEM__RELABELFROM, NULL);
+ if (rc)
+ return rc;
+
+ rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
+ FILESYSTEM__RELABELTO, NULL);
+ return rc;
+}
+
+static int may_context_mount_inode_relabel(u32 sid,
+ struct superblock_security_struct *sbsec,
+ struct task_security_struct *tsec)
+{
+ int rc;
+ rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+ FILESYSTEM__RELABELFROM, NULL);
+ if (rc)
+ return rc;
+
+ rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
+ FILESYSTEM__ASSOCIATE, NULL);
+ return rc;
+}
+
static int try_context_mount(struct super_block *sb, void *data)
{
char *context = NULL, *defcontext = NULL;
+ char *fscontext = NULL, *rootcontext = NULL;
const char *name;
u32 sid;
int alloc = 0, rc = 0, seen = 0;
@@ -374,7 +409,7 @@
switch (token) {
case Opt_context:
- if (seen) {
+ if (seen & (Opt_context|Opt_defcontext)) {
rc = -EINVAL;
printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
goto out_free;
@@ -390,13 +425,13 @@
break;
case Opt_fscontext:
- if (seen & (Opt_context|Opt_fscontext)) {
+ if (seen & Opt_fscontext) {
rc = -EINVAL;
printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
goto out_free;
}
- context = match_strdup(&args[0]);
- if (!context) {
+ fscontext = match_strdup(&args[0]);
+ if (!fscontext) {
rc = -ENOMEM;
goto out_free;
}
@@ -405,6 +440,22 @@
seen |= Opt_fscontext;
break;
+ case Opt_rootcontext:
+ if (seen & Opt_rootcontext) {
+ rc = -EINVAL;
+ printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
+ goto out_free;
+ }
+ rootcontext = match_strdup(&args[0]);
+ if (!rootcontext) {
+ rc = -ENOMEM;
+ goto out_free;
+ }
+ if (!alloc)
+ alloc = 1;
+ seen |= Opt_rootcontext;
+ break;
+
case Opt_defcontext:
if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
rc = -EINVAL;
@@ -441,6 +492,28 @@
if (!seen)
goto out;
+ /* sets the context of the superblock for the fs being mounted. */
+ if (fscontext) {
+ rc = security_context_to_sid(fscontext, strlen(fscontext), &sid);
+ if (rc) {
+ printk(KERN_WARNING "SELinux: security_context_to_sid"
+ "(%s) failed for (dev %s, type %s) errno=%d\n",
+ fscontext, sb->s_id, name, rc);
+ goto out_free;
+ }
+
+ rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
+ if (rc)
+ goto out_free;
+
+ sbsec->sid = sid;
+ }
+
+ /*
+ * Switch to using mount point labeling behavior.
+ * sets the label used on all file below the mountpoint, and will set
+ * the superblock context if not already set.
+ */
if (context) {
rc = security_context_to_sid(context, strlen(context), &sid);
if (rc) {
@@ -450,20 +523,34 @@
goto out_free;
}
- rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
- FILESYSTEM__RELABELFROM, NULL);
+ rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
if (rc)
goto out_free;
- rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
- FILESYSTEM__RELABELTO, NULL);
+ if (!fscontext)
+ sbsec->sid = sid;
+ sbsec->mntpoint_sid = sid;
+
+ sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
+ }
+
+ if (rootcontext) {
+ struct inode *inode = sb->s_root->d_inode;
+ struct inode_security_struct *isec = inode->i_security;
+ rc = security_context_to_sid(rootcontext, strlen(rootcontext), &sid);
+ if (rc) {
+ printk(KERN_WARNING "SELinux: security_context_to_sid"
+ "(%s) failed for (dev %s, type %s) errno=%d\n",
+ rootcontext, sb->s_id, name, rc);
+ goto out_free;
+ }
+
+ rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
if (rc)
goto out_free;
- sbsec->sid = sid;
-
- if (seen & Opt_context)
- sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
+ isec->sid = sid;
+ isec->initialized = 1;
}
if (defcontext) {
@@ -478,13 +565,7 @@
if (sid == sbsec->def_sid)
goto out_free;
- rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
- FILESYSTEM__RELABELFROM, NULL);
- if (rc)
- goto out_free;
-
- rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
- FILESYSTEM__ASSOCIATE, NULL);
+ rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
if (rc)
goto out_free;
@@ -495,6 +576,8 @@
if (alloc) {
kfree(context);
kfree(defcontext);
+ kfree(fscontext);
+ kfree(rootcontext);
}
out:
return rc;
@@ -876,8 +959,11 @@
goto out;
isec->sid = sid;
break;
+ case SECURITY_FS_USE_MNTPOINT:
+ isec->sid = sbsec->mntpoint_sid;
+ break;
default:
- /* Default to the fs SID. */
+ /* Default to the fs superblock SID. */
isec->sid = sbsec->sid;
if (sbsec->proc) {
@@ -1843,7 +1929,8 @@
{
return (match_prefix("context=", sizeof("context=")-1, option, len) ||
match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) ||
- match_prefix("defcontext=", sizeof("defcontext=")-1, option, len));
+ match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) ||
+ match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len));
}
static inline void take_option(char **to, char *from, int *first, int len)
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index cf54a30..9401788 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -57,8 +57,9 @@
struct superblock_security_struct {
struct super_block *sb; /* back pointer to sb object */
struct list_head list; /* list of superblock_security_struct */
- u32 sid; /* SID of file system */
+ u32 sid; /* SID of file system superblock */
u32 def_sid; /* default SID for labeling */
+ u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
unsigned int behavior; /* labeling behavior */
unsigned char initialized; /* initialization flag */
unsigned char proc; /* proc fs */
diff --git a/sound/aoa/Makefile b/sound/aoa/Makefile
index d8de3e7..a8c037f 100644
--- a/sound/aoa/Makefile
+++ b/sound/aoa/Makefile
@@ -1,4 +1,4 @@
obj-$(CONFIG_SND_AOA) += core/
-obj-$(CONFIG_SND_AOA) += codecs/
-obj-$(CONFIG_SND_AOA) += fabrics/
obj-$(CONFIG_SND_AOA_SOUNDBUS) += soundbus/
+obj-$(CONFIG_SND_AOA) += fabrics/
+obj-$(CONFIG_SND_AOA) += codecs/
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
new file mode 100644
index 0000000..69b6113
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
@@ -0,0 +1,134 @@
+/*
+ * This file is only included exactly once!
+ *
+ * The tables here are derived from the tas3004 datasheet,
+ * modulo typo corrections and some smoothing...
+ */
+
+#define TAS3004_TREBLE_MIN 0
+#define TAS3004_TREBLE_MAX 72
+#define TAS3004_BASS_MIN 0
+#define TAS3004_BASS_MAX 72
+#define TAS3004_TREBLE_ZERO 36
+#define TAS3004_BASS_ZERO 36
+
+static u8 tas3004_treble_table[] = {
+ 150, /* -18 dB */
+ 149,
+ 148,
+ 147,
+ 146,
+ 145,
+ 144,
+ 143,
+ 142,
+ 141,
+ 140,
+ 139,
+ 138,
+ 137,
+ 136,
+ 135,
+ 134,
+ 133,
+ 132,
+ 131,
+ 130,
+ 129,
+ 128,
+ 127,
+ 126,
+ 125,
+ 124,
+ 123,
+ 122,
+ 121,
+ 120,
+ 119,
+ 118,
+ 117,
+ 116,
+ 115,
+ 114, /* 0 dB */
+ 113,
+ 112,
+ 111,
+ 109,
+ 108,
+ 107,
+ 105,
+ 104,
+ 103,
+ 101,
+ 99,
+ 98,
+ 96,
+ 93,
+ 91,
+ 89,
+ 86,
+ 83,
+ 81,
+ 77,
+ 74,
+ 71,
+ 67,
+ 63,
+ 59,
+ 54,
+ 49,
+ 44,
+ 38,
+ 32,
+ 26,
+ 19,
+ 10,
+ 4,
+ 2,
+ 1, /* +18 dB */
+};
+
+static inline u8 tas3004_treble(int idx)
+{
+ return tas3004_treble_table[idx];
+}
+
+/* I only save the difference here to the treble table
+ * so that the binary is smaller...
+ * I have also ignored completely differences of
+ * +/- 1
+ */
+static s8 tas3004_bass_diff_to_treble[] = {
+ 2, /* 7 dB, offset 50 */
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 4,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 14,
+ 13,
+ 8,
+ 1, /* 18 dB */
+};
+
+static inline u8 tas3004_bass(int idx)
+{
+ u8 result = tas3004_treble_table[idx];
+
+ if (idx >= 50)
+ result += tas3004_bass_diff_to_treble[idx-50];
+ return result;
+}
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index 2e39ff6..16c0b6b 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -72,22 +72,29 @@
#include "snd-aoa-codec-tas.h"
#include "snd-aoa-codec-tas-gain-table.h"
+#include "snd-aoa-codec-tas-basstreble.h"
#include "../aoa.h"
#include "../soundbus/soundbus.h"
-
#define PFX "snd-aoa-codec-tas: "
+
struct tas {
struct aoa_codec codec;
struct i2c_client i2c;
- u32 muted_l:1, muted_r:1,
- controls_created:1;
+ u32 mute_l:1, mute_r:1 ,
+ controls_created:1 ,
+ drc_enabled:1,
+ hw_enabled:1;
u8 cached_volume_l, cached_volume_r;
u8 mixer_l[3], mixer_r[3];
+ u8 bass, treble;
u8 acr;
+ int drc_range;
};
+static int tas_reset_init(struct tas *tas);
+
static struct tas *codec_to_tas(struct aoa_codec *codec)
{
return container_of(codec, struct tas, codec);
@@ -101,6 +108,44 @@
return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data);
}
+static void tas3004_set_drc(struct tas *tas)
+{
+ unsigned char val[6];
+
+ if (tas->drc_enabled)
+ val[0] = 0x50; /* 3:1 above threshold */
+ else
+ val[0] = 0x51; /* disabled */
+ val[1] = 0x02; /* 1:1 below threshold */
+ if (tas->drc_range > 0xef)
+ val[2] = 0xef;
+ else if (tas->drc_range < 0)
+ val[2] = 0x00;
+ else
+ val[2] = tas->drc_range;
+ val[3] = 0xb0;
+ val[4] = 0x60;
+ val[5] = 0xa0;
+
+ tas_write_reg(tas, TAS_REG_DRC, 6, val);
+}
+
+static void tas_set_treble(struct tas *tas)
+{
+ u8 tmp;
+
+ tmp = tas3004_treble(tas->treble);
+ tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp);
+}
+
+static void tas_set_bass(struct tas *tas)
+{
+ u8 tmp;
+
+ tmp = tas3004_bass(tas->bass);
+ tas_write_reg(tas, TAS_REG_BASS, 1, &tmp);
+}
+
static void tas_set_volume(struct tas *tas)
{
u8 block[6];
@@ -113,8 +158,8 @@
if (left > 177) left = 177;
if (right > 177) right = 177;
- if (tas->muted_l) left = 0;
- if (tas->muted_r) right = 0;
+ if (tas->mute_l) left = 0;
+ if (tas->mute_r) right = 0;
/* analysing the volume and mixer tables shows
* that they are similar enough when we shift
@@ -202,7 +247,8 @@
tas->cached_volume_l = ucontrol->value.integer.value[0];
tas->cached_volume_r = ucontrol->value.integer.value[1];
- tas_set_volume(tas);
+ if (tas->hw_enabled)
+ tas_set_volume(tas);
return 1;
}
@@ -230,8 +276,8 @@
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = !tas->muted_l;
- ucontrol->value.integer.value[1] = !tas->muted_r;
+ ucontrol->value.integer.value[0] = !tas->mute_l;
+ ucontrol->value.integer.value[1] = !tas->mute_r;
return 0;
}
@@ -240,13 +286,14 @@
{
struct tas *tas = snd_kcontrol_chip(kcontrol);
- if (tas->muted_l == !ucontrol->value.integer.value[0]
- && tas->muted_r == !ucontrol->value.integer.value[1])
+ if (tas->mute_l == !ucontrol->value.integer.value[0]
+ && tas->mute_r == !ucontrol->value.integer.value[1])
return 0;
- tas->muted_l = !ucontrol->value.integer.value[0];
- tas->muted_r = !ucontrol->value.integer.value[1];
- tas_set_volume(tas);
+ tas->mute_l = !ucontrol->value.integer.value[0];
+ tas->mute_r = !ucontrol->value.integer.value[1];
+ if (tas->hw_enabled)
+ tas_set_volume(tas);
return 1;
}
@@ -294,7 +341,8 @@
tas->mixer_l[idx] = ucontrol->value.integer.value[0];
tas->mixer_r[idx] = ucontrol->value.integer.value[1];
- tas_set_mixer(tas);
+ if (tas->hw_enabled)
+ tas_set_mixer(tas);
return 1;
}
@@ -309,9 +357,93 @@
.private_value = idx, \
}
-MIXER_CONTROL(pcm1, "PCM1", 0);
+MIXER_CONTROL(pcm1, "PCM", 0);
MIXER_CONTROL(monitor, "Monitor", 2);
+static int tas_snd_drc_range_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = TAS3004_DRC_MAX;
+ return 0;
+}
+
+static int tas_snd_drc_range_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = tas->drc_range;
+ return 0;
+}
+
+static int tas_snd_drc_range_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ if (tas->drc_range == ucontrol->value.integer.value[0])
+ return 0;
+
+ tas->drc_range = ucontrol->value.integer.value[0];
+ if (tas->hw_enabled)
+ tas3004_set_drc(tas);
+ return 1;
+}
+
+static struct snd_kcontrol_new drc_range_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "DRC Range",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = tas_snd_drc_range_info,
+ .get = tas_snd_drc_range_get,
+ .put = tas_snd_drc_range_put,
+};
+
+static int tas_snd_drc_switch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+static int tas_snd_drc_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = tas->drc_enabled;
+ return 0;
+}
+
+static int tas_snd_drc_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ if (tas->drc_enabled == ucontrol->value.integer.value[0])
+ return 0;
+
+ tas->drc_enabled = ucontrol->value.integer.value[0];
+ if (tas->hw_enabled)
+ tas3004_set_drc(tas);
+ return 1;
+}
+
+static struct snd_kcontrol_new drc_switch_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "DRC Range Switch",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = tas_snd_drc_switch_info,
+ .get = tas_snd_drc_switch_get,
+ .put = tas_snd_drc_switch_put,
+};
+
static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
@@ -346,7 +478,8 @@
tas->acr |= TAS_ACR_INPUT_B;
if (oldacr == tas->acr)
return 0;
- tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
+ if (tas->hw_enabled)
+ tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
return 1;
}
@@ -370,6 +503,89 @@
.put = tas_snd_capture_source_put,
};
+static int tas_snd_treble_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = TAS3004_TREBLE_MIN;
+ uinfo->value.integer.max = TAS3004_TREBLE_MAX;
+ return 0;
+}
+
+static int tas_snd_treble_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = tas->treble;
+ return 0;
+}
+
+static int tas_snd_treble_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ if (tas->treble == ucontrol->value.integer.value[0])
+ return 0;
+
+ tas->treble = ucontrol->value.integer.value[0];
+ if (tas->hw_enabled)
+ tas_set_treble(tas);
+ return 1;
+}
+
+static struct snd_kcontrol_new treble_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Treble",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = tas_snd_treble_info,
+ .get = tas_snd_treble_get,
+ .put = tas_snd_treble_put,
+};
+
+static int tas_snd_bass_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = TAS3004_BASS_MIN;
+ uinfo->value.integer.max = TAS3004_BASS_MAX;
+ return 0;
+}
+
+static int tas_snd_bass_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] = tas->bass;
+ return 0;
+}
+
+static int tas_snd_bass_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+ if (tas->bass == ucontrol->value.integer.value[0])
+ return 0;
+
+ tas->bass = ucontrol->value.integer.value[0];
+ if (tas->hw_enabled)
+ tas_set_bass(tas);
+ return 1;
+}
+
+static struct snd_kcontrol_new bass_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Bass",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = tas_snd_bass_info,
+ .get = tas_snd_bass_get,
+ .put = tas_snd_bass_put,
+};
static struct transfer_info tas_transfers[] = {
{
@@ -399,26 +615,67 @@
static int tas_reset_init(struct tas *tas)
{
u8 tmp;
- tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
- msleep(1);
- tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1);
- msleep(1);
- tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
- msleep(1);
- tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
- tas->acr |= TAS_ACR_B_MONAUREAL | TAS_ACR_B_MON_SEL_RIGHT;
- if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
- return -ENODEV;
+ tas->codec.gpio->methods->all_amps_off(tas->codec.gpio);
+ msleep(5);
+ tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
+ msleep(5);
+ tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1);
+ msleep(20);
+ tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
+ msleep(10);
+ tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio);
tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT;
if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp))
return -ENODEV;
+ tas->acr |= TAS_ACR_ANALOG_PDOWN | TAS_ACR_B_MONAUREAL |
+ TAS_ACR_B_MON_SEL_RIGHT;
+ if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
+ return -ENODEV;
+
tmp = 0;
if (tas_write_reg(tas, TAS_REG_MCS2, 1, &tmp))
return -ENODEV;
+ tas3004_set_drc(tas);
+
+ /* Set treble & bass to 0dB */
+ tas->treble = TAS3004_TREBLE_ZERO;
+ tas->bass = TAS3004_BASS_ZERO;
+ tas_set_treble(tas);
+ tas_set_bass(tas);
+
+ tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
+ if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock)
+{
+ struct tas *tas = cii->codec_data;
+
+ switch(clock) {
+ case CLOCK_SWITCH_PREPARE_SLAVE:
+ /* Clocks are going away, mute mute mute */
+ tas->codec.gpio->methods->all_amps_off(tas->codec.gpio);
+ tas->hw_enabled = 0;
+ break;
+ case CLOCK_SWITCH_SLAVE:
+ /* Clocks are back, re-init the codec */
+ tas_reset_init(tas);
+ tas_set_volume(tas);
+ tas_set_mixer(tas);
+ tas->hw_enabled = 1;
+ tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio);
+ break;
+ default:
+ /* doesn't happen as of now */
+ return -EINVAL;
+ }
return 0;
}
@@ -427,6 +684,7 @@
* our i2c device is suspended, and then take note of that! */
static int tas_suspend(struct tas *tas)
{
+ tas->hw_enabled = 0;
tas->acr |= TAS_ACR_ANALOG_PDOWN;
tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
return 0;
@@ -438,6 +696,7 @@
tas_reset_init(tas);
tas_set_volume(tas);
tas_set_mixer(tas);
+ tas->hw_enabled = 1;
return 0;
}
@@ -463,6 +722,7 @@
.bus_factor = 64,
.owner = THIS_MODULE,
.usable = tas_usable,
+ .switch_clock = tas_switch_clock,
#ifdef CONFIG_PM
.suspend = _tas_suspend,
.resume = _tas_resume,
@@ -483,6 +743,7 @@
printk(KERN_ERR PFX "tas failed to initialise\n");
return -ENXIO;
}
+ tas->hw_enabled = 1;
if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev,
aoa_get_card(),
@@ -515,6 +776,22 @@
if (err)
goto error;
+ err = aoa_snd_ctl_add(snd_ctl_new1(&drc_range_control, tas));
+ if (err)
+ goto error;
+
+ err = aoa_snd_ctl_add(snd_ctl_new1(&drc_switch_control, tas));
+ if (err)
+ goto error;
+
+ err = aoa_snd_ctl_add(snd_ctl_new1(&treble_control, tas));
+ if (err)
+ goto error;
+
+ err = aoa_snd_ctl_add(snd_ctl_new1(&bass_control, tas));
+ if (err)
+ goto error;
+
return 0;
error:
tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
@@ -548,6 +825,8 @@
tas->i2c.driver = &tas_driver;
tas->i2c.adapter = adapter;
tas->i2c.addr = addr;
+ /* seems that half is a saner default */
+ tas->drc_range = TAS3004_DRC_MAX / 2;
strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
if (i2c_attach_client(&tas->i2c)) {
@@ -564,7 +843,9 @@
if (aoa_codec_register(&tas->codec)) {
goto detach;
}
- printk(KERN_DEBUG "snd-aoa-codec-tas: created and attached tas instance\n");
+ printk(KERN_DEBUG
+ "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n",
+ addr, node->full_name);
return 0;
detach:
i2c_detach_client(&tas->i2c);
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.h b/sound/aoa/codecs/snd-aoa-codec-tas.h
index daf81f4..ae177e3 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.h
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.h
@@ -44,4 +44,12 @@
#define TAS_REG_LEFT_BIQUAD6 0x10
#define TAS_REG_RIGHT_BIQUAD6 0x19
+#define TAS_REG_LEFT_LOUDNESS 0x21
+#define TAS_REG_RIGHT_LOUDNESS 0x22
+#define TAS_REG_LEFT_LOUDNESS_GAIN 0x23
+#define TAS_REG_RIGHT_LOUDNESS_GAIN 0x24
+
+#define TAS3001_DRC_MAX 0x5f
+#define TAS3004_DRC_MAX 0xef
+
#endif /* __SND_AOA_CODECTASH */
diff --git a/sound/aoa/core/snd-aoa-gpio-pmf.c b/sound/aoa/core/snd-aoa-gpio-pmf.c
index 0e9b9bb..3d57fd1 100644
--- a/sound/aoa/core/snd-aoa-gpio-pmf.c
+++ b/sound/aoa/core/snd-aoa-gpio-pmf.c
@@ -14,9 +14,13 @@
static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\
{ \
struct pmf_args args = { .count = 1, .u[0].v = !on }; \
- \
+ int rc; \
+ \
if (unlikely(!rt)) return; \
- pmf_call_function(rt->node, #name "-mute", &args); \
+ rc = pmf_call_function(rt->node, #name "-mute", &args); \
+ if (rc) \
+ printk(KERN_WARNING "pmf_gpio_set_" #name \
+ " failed, rc: %d\n", rc); \
rt->implementation_private &= ~(1<<bit); \
rt->implementation_private |= (!!on << bit); \
} \
@@ -33,9 +37,13 @@
static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
{
struct pmf_args args = { .count = 1, .u[0].v = !!on };
+ int rc;
if (unlikely(!rt)) return;
- pmf_call_function(rt->node, "hw-reset", &args);
+ rc = pmf_call_function(rt->node, "hw-reset", &args);
+ if (rc)
+ printk(KERN_WARNING "pmf_gpio_set_hw_reset"
+ " failed, rc: %d\n", rc);
}
static void pmf_gpio_all_amps_off(struct gpio_runtime *rt)
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
index cbc8a3b..172eb95 100644
--- a/sound/aoa/fabrics/snd-aoa-fabric-layout.c
+++ b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
@@ -77,24 +77,39 @@
int pcmid;
};
+MODULE_ALIAS("sound-layout-36");
MODULE_ALIAS("sound-layout-41");
MODULE_ALIAS("sound-layout-45");
+MODULE_ALIAS("sound-layout-47");
+MODULE_ALIAS("sound-layout-48");
+MODULE_ALIAS("sound-layout-49");
+MODULE_ALIAS("sound-layout-50");
MODULE_ALIAS("sound-layout-51");
+MODULE_ALIAS("sound-layout-56");
+MODULE_ALIAS("sound-layout-57");
MODULE_ALIAS("sound-layout-58");
MODULE_ALIAS("sound-layout-60");
MODULE_ALIAS("sound-layout-61");
+MODULE_ALIAS("sound-layout-62");
MODULE_ALIAS("sound-layout-64");
MODULE_ALIAS("sound-layout-65");
+MODULE_ALIAS("sound-layout-66");
+MODULE_ALIAS("sound-layout-67");
MODULE_ALIAS("sound-layout-68");
MODULE_ALIAS("sound-layout-69");
MODULE_ALIAS("sound-layout-70");
MODULE_ALIAS("sound-layout-72");
+MODULE_ALIAS("sound-layout-76");
MODULE_ALIAS("sound-layout-80");
MODULE_ALIAS("sound-layout-82");
MODULE_ALIAS("sound-layout-84");
MODULE_ALIAS("sound-layout-86");
+MODULE_ALIAS("sound-layout-90");
MODULE_ALIAS("sound-layout-92");
+MODULE_ALIAS("sound-layout-94");
MODULE_ALIAS("sound-layout-96");
+MODULE_ALIAS("sound-layout-98");
+MODULE_ALIAS("sound-layout-100");
/* onyx with all but microphone connected */
static struct codec_connection onyx_connections_nomic[] = {
@@ -950,11 +965,12 @@
layout_id = (unsigned int *) get_property(sound, "layout-id", NULL);
if (!layout_id)
goto outnodev;
- printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d ", *layout_id);
+ printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d\n",
+ *layout_id);
layout = find_layout_by_id(*layout_id);
if (!layout) {
- printk("(no idea how to handle)\n");
+ printk(KERN_ERR "snd-aoa-fabric-layout: unknown layout\n");
goto outnodev;
}
@@ -972,15 +988,17 @@
case 51: /* PowerBook5,4 */
case 58: /* Mac Mini */
ldev->gpio.methods = ftr_gpio_methods;
+ printk(KERN_DEBUG
+ "snd-aoa-fabric-layout: Using direct GPIOs\n");
break;
default:
ldev->gpio.methods = pmf_gpio_methods;
+ printk(KERN_DEBUG
+ "snd-aoa-fabric-layout: Using PMF GPIOs\n");
}
ldev->selfptr_headphone.ptr = ldev;
ldev->selfptr_lineout.ptr = ldev;
sdev->ofdev.dev.driver_data = ldev;
-
- printk("(using)\n");
list_add(&ldev->list, &layouts_list);
layouts_list_items++;
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index abe84a7..47b3e37 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -194,16 +194,6 @@
.dev_attrs = soundbus_dev_attrs,
};
-static int __init soundbus_init(void)
-{
- return bus_register(&soundbus_bus_type);
-}
-
-static void __exit soundbus_exit(void)
-{
- bus_unregister(&soundbus_bus_type);
-}
-
int soundbus_add_one(struct soundbus_dev *dev)
{
static int devcount;
@@ -246,5 +236,15 @@
}
EXPORT_SYMBOL_GPL(soundbus_unregister_driver);
-module_init(soundbus_init);
+static int __init soundbus_init(void)
+{
+ return bus_register(&soundbus_bus_type);
+}
+
+static void __exit soundbus_exit(void)
+{
+ bus_unregister(&soundbus_bus_type);
+}
+
+subsys_initcall(soundbus_init);
module_exit(soundbus_exit);
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.c b/sound/aoa/soundbus/i2sbus/i2sbus-control.c
index f504079..87beb4a 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-control.c
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-control.c
@@ -6,12 +6,16 @@
* GPL v2, can be found in COPYING.
*/
-#include <asm/io.h>
+#include <linux/kernel.h>
#include <linux/delay.h>
+
+#include <asm/io.h>
#include <asm/prom.h>
#include <asm/macio.h>
#include <asm/pmac_feature.h>
#include <asm/pmac_pfunc.h>
+#include <asm/keylargo.h>
+
#include "i2sbus.h"
int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
@@ -22,26 +26,12 @@
INIT_LIST_HEAD(&(*c)->list);
- if (of_address_to_resource(dev->ofdev.node, 0, &(*c)->rsrc))
- goto err;
- /* we really should be using feature calls instead of mapping
- * these registers. It's safe for now since no one else is
- * touching them... */
- (*c)->controlregs = ioremap((*c)->rsrc.start,
- sizeof(struct i2s_control_regs));
- if (!(*c)->controlregs)
- goto err;
-
+ (*c)->macio = dev->bus->chip;
return 0;
- err:
- kfree(*c);
- *c = NULL;
- return -ENODEV;
}
void i2sbus_control_destroy(struct i2sbus_control *c)
{
- iounmap(c->controlregs);
kfree(c);
}
@@ -93,19 +83,22 @@
struct i2sbus_dev *i2sdev)
{
struct pmf_args args = { .count = 0 };
- int cc;
+ struct macio_chip *macio = c->macio;
if (i2sdev->enable)
return pmf_call_one(i2sdev->enable, &args);
+ if (macio == NULL || macio->base == NULL)
+ return -ENODEV;
+
switch (i2sdev->bus_number) {
case 0:
- cc = in_le32(&c->controlregs->cell_control);
- out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_0_ENABLE);
+ /* these need to be locked or done through
+ * newly created feature calls! */
+ MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
break;
case 1:
- cc = in_le32(&c->controlregs->cell_control);
- out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_1_ENABLE);
+ MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_ENABLE);
break;
default:
return -ENODEV;
@@ -118,7 +111,7 @@
int enable)
{
struct pmf_args args = { .count = 0 };
- int cc;
+ struct macio_chip *macio = c->macio;
switch (enable) {
case 0:
@@ -133,18 +126,22 @@
printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
return -ENODEV;
}
+
+ if (macio == NULL || macio->base == NULL)
+ return -ENODEV;
+
switch (i2sdev->bus_number) {
case 0:
- cc = in_le32(&c->controlregs->cell_control);
- cc &= ~CTRL_CLOCK_CELL_0_ENABLE;
- cc |= enable * CTRL_CLOCK_CELL_0_ENABLE;
- out_le32(&c->controlregs->cell_control, cc);
+ if (enable)
+ MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
+ else
+ MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
break;
case 1:
- cc = in_le32(&c->controlregs->cell_control);
- cc &= ~CTRL_CLOCK_CELL_1_ENABLE;
- cc |= enable * CTRL_CLOCK_CELL_1_ENABLE;
- out_le32(&c->controlregs->cell_control, cc);
+ if (enable)
+ MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
+ else
+ MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
break;
default:
return -ENODEV;
@@ -157,7 +154,7 @@
int enable)
{
struct pmf_args args = { .count = 0 };
- int cc;
+ struct macio_chip *macio = c->macio;
switch (enable) {
case 0:
@@ -172,18 +169,22 @@
printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
return -ENODEV;
}
+
+ if (macio == NULL || macio->base == NULL)
+ return -ENODEV;
+
switch (i2sdev->bus_number) {
case 0:
- cc = in_le32(&c->controlregs->cell_control);
- cc &= ~CTRL_CLOCK_CLOCK_0_ENABLE;
- cc |= enable * CTRL_CLOCK_CLOCK_0_ENABLE;
- out_le32(&c->controlregs->cell_control, cc);
+ if (enable)
+ MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
+ else
+ MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
break;
case 1:
- cc = in_le32(&c->controlregs->cell_control);
- cc &= ~CTRL_CLOCK_CLOCK_1_ENABLE;
- cc |= enable * CTRL_CLOCK_CLOCK_1_ENABLE;
- out_le32(&c->controlregs->cell_control, cc);
+ if (enable)
+ MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
+ else
+ MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
break;
default:
return -ENODEV;
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.h b/sound/aoa/soundbus/i2sbus/i2sbus-control.h
deleted file mode 100644
index bb05550..0000000
--- a/sound/aoa/soundbus/i2sbus/i2sbus-control.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * i2sbus driver -- bus register definitions
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-#ifndef __I2SBUS_CONTROLREGS_H
-#define __I2SBUS_CONTROLREGS_H
-
-/* i2s control registers, at least what we know about them */
-
-#define __PAD(m,n) u8 __pad##m[n]
-#define _PAD(line, n) __PAD(line, n)
-#define PAD(n) _PAD(__LINE__, (n))
-struct i2s_control_regs {
- PAD(0x38);
- __le32 fcr0; /* 0x38 (unknown) */
- __le32 cell_control; /* 0x3c (fcr1) */
- __le32 fcr2; /* 0x40 (unknown) */
- __le32 fcr3; /* 0x44 (fcr3) */
- __le32 clock_control; /* 0x48 (unknown) */
- PAD(4);
- /* total size: 0x50 bytes */
-} __attribute__((__packed__));
-
-#define CTRL_CLOCK_CELL_0_ENABLE (1<<10)
-#define CTRL_CLOCK_CLOCK_0_ENABLE (1<<12)
-#define CTRL_CLOCK_SWRESET_0 (1<<11)
-#define CTRL_CLOCK_INTF_0_ENABLE (1<<13)
-
-#define CTRL_CLOCK_CELL_1_ENABLE (1<<17)
-#define CTRL_CLOCK_CLOCK_1_ENABLE (1<<18)
-#define CTRL_CLOCK_SWRESET_1 (1<<19)
-#define CTRL_CLOCK_INTF_1_ENABLE (1<<20)
-
-#endif /* __I2SBUS_CONTROLREGS_H */
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
index 01c0724..23190aa 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
@@ -7,13 +7,16 @@
*/
#include <linux/module.h>
-#include <asm/macio.h>
-#include <asm/dbdma.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
#include <sound/driver.h>
#include <sound/core.h>
-#include <linux/dma-mapping.h>
+
+#include <asm/macio.h>
+#include <asm/dbdma.h>
+
#include "../soundbus.h"
#include "i2sbus.h"
@@ -24,6 +27,11 @@
* string that macio puts into the relevant device */
MODULE_ALIAS("of:Ni2sTi2sC");
+static int force;
+module_param(force, int, 0444);
+MODULE_PARM_DESC(force, "Force loading i2sbus even when"
+ " no layout-id property is present");
+
static struct of_device_id i2sbus_match[] = {
{ .name = "i2s" },
{ }
@@ -73,12 +81,12 @@
if (i2sdev->intfregs) iounmap(i2sdev->intfregs);
if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma);
if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma);
- for (i=0;i<3;i++)
+ for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
if (i2sdev->allocated_resource[i])
release_and_free_resource(i2sdev->allocated_resource[i]);
free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring);
free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring);
- for (i=0;i<3;i++)
+ for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
free_irq(i2sdev->interrupts[i], i2sdev);
i2sbus_control_remove_dev(i2sdev->control, i2sdev);
mutex_destroy(&i2sdev->lock);
@@ -101,10 +109,49 @@
return IRQ_HANDLED;
}
-static int force;
-module_param(force, int, 0444);
-MODULE_PARM_DESC(force, "Force loading i2sbus even when"
- " no layout-id property is present");
+
+/*
+ * XXX FIXME: We test the layout_id's here to get the proper way of
+ * mapping in various registers, thanks to bugs in Apple device-trees.
+ * We could instead key off the machine model and the name of the i2s
+ * node (i2s-a). This we'll do when we move it all to macio_asic.c
+ * and have that export items for each sub-node too.
+ */
+static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
+ int layout, struct resource *res)
+{
+ struct device_node *parent;
+ int pindex, rc = -ENXIO;
+ u32 *reg;
+
+ /* Machines with layout 76 and 36 (K2 based) have a weird device
+ * tree what we need to special case.
+ * Normal machines just fetch the resource from the i2s-X node.
+ * Darwin further divides normal machines into old and new layouts
+ * with a subtely different code path but that doesn't seem necessary
+ * in practice, they just bloated it. In addition, even on our K2
+ * case the i2s-modem node, if we ever want to handle it, uses the
+ * normal layout
+ */
+ if (layout != 76 && layout != 36)
+ return of_address_to_resource(np, index, res);
+
+ parent = of_get_parent(np);
+ pindex = (index == aoa_resource_i2smmio) ? 0 : 1;
+ rc = of_address_to_resource(parent, pindex, res);
+ if (rc)
+ goto bail;
+ reg = (u32 *)get_property(np, "reg", NULL);
+ if (reg == NULL) {
+ rc = -ENXIO;
+ goto bail;
+ }
+ res->start += reg[index * 2];
+ res->end = res->start + reg[index * 2 + 1] - 1;
+ bail:
+ of_node_put(parent);
+ return rc;
+}
/* FIXME: look at device node refcounting */
static int i2sbus_add_dev(struct macio_dev *macio,
@@ -113,7 +160,8 @@
{
struct i2sbus_dev *dev;
struct device_node *child = NULL, *sound = NULL;
- int i;
+ struct resource *r;
+ int i, layout = 0, rlen;
static const char *rnames[] = { "i2sbus: %s (control)",
"i2sbus: %s (tx)",
"i2sbus: %s (rx)" };
@@ -129,9 +177,6 @@
if (strncmp(np->name, "i2s-", 4))
return 0;
- if (macio_irq_count(macio) != 3)
- return 0;
-
dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL);
if (!dev)
return 0;
@@ -147,8 +192,9 @@
u32 *layout_id;
layout_id = (u32*) get_property(sound, "layout-id", NULL);
if (layout_id) {
+ layout = *layout_id;
snprintf(dev->sound.modalias, 32,
- "sound-layout-%d", *layout_id);
+ "sound-layout-%d", layout);
force = 1;
}
}
@@ -178,23 +224,32 @@
dev->bus_number = np->name[4] - 'a';
INIT_LIST_HEAD(&dev->sound.codec_list);
- for (i=0;i<3;i++) {
+ for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
dev->interrupts[i] = -1;
- snprintf(dev->rnames[i], sizeof(dev->rnames[i]), rnames[i], np->name);
+ snprintf(dev->rnames[i], sizeof(dev->rnames[i]),
+ rnames[i], np->name);
}
- for (i=0;i<3;i++) {
- if (request_irq(macio_irq(macio, i), ints[i], 0,
- dev->rnames[i], dev))
+ for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
+ int irq = irq_of_parse_and_map(np, i);
+ if (request_irq(irq, ints[i], 0, dev->rnames[i], dev))
goto err;
- dev->interrupts[i] = macio_irq(macio, i);
+ dev->interrupts[i] = irq;
}
- for (i=0;i<3;i++) {
- if (of_address_to_resource(np, i, &dev->resources[i]))
+
+ /* Resource handling is problematic as some device-trees contain
+ * useless crap (ugh ugh ugh). We work around that here by calling
+ * specific functions for calculating the appropriate resources.
+ *
+ * This will all be moved to macio_asic.c at one point
+ */
+ for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
+ if (i2sbus_get_and_fixup_rsrc(np,i,layout,&dev->resources[i]))
goto err;
- /* if only we could use our resource dev->resources[i]...
+ /* If only we could use our resource dev->resources[i]...
* but request_resource doesn't know about parents and
- * contained resources... */
+ * contained resources...
+ */
dev->allocated_resource[i] =
request_mem_region(dev->resources[i].start,
dev->resources[i].end -
@@ -205,13 +260,25 @@
goto err;
}
}
- /* should do sanity checking here about length of them */
- dev->intfregs = ioremap(dev->resources[0].start,
- dev->resources[0].end-dev->resources[0].start+1);
- dev->out.dbdma = ioremap(dev->resources[1].start,
- dev->resources[1].end-dev->resources[1].start+1);
- dev->in.dbdma = ioremap(dev->resources[2].start,
- dev->resources[2].end-dev->resources[2].start+1);
+
+ r = &dev->resources[aoa_resource_i2smmio];
+ rlen = r->end - r->start + 1;
+ if (rlen < sizeof(struct i2s_interface_regs))
+ goto err;
+ dev->intfregs = ioremap(r->start, rlen);
+
+ r = &dev->resources[aoa_resource_txdbdma];
+ rlen = r->end - r->start + 1;
+ if (rlen < sizeof(struct dbdma_regs))
+ goto err;
+ dev->out.dbdma = ioremap(r->start, rlen);
+
+ r = &dev->resources[aoa_resource_rxdbdma];
+ rlen = r->end - r->start + 1;
+ if (rlen < sizeof(struct dbdma_regs))
+ goto err;
+ dev->in.dbdma = ioremap(r->start, rlen);
+
if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma)
goto err;
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus.h b/sound/aoa/soundbus/i2sbus/i2sbus.h
index cfa5162..0c69d20 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus.h
+++ b/sound/aoa/soundbus/i2sbus/i2sbus.h
@@ -7,20 +7,22 @@
*/
#ifndef __I2SBUS_H
#define __I2SBUS_H
-#include <asm/dbdma.h>
#include <linux/interrupt.h>
-#include <sound/pcm.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
+
+#include <sound/pcm.h>
+
#include <asm/prom.h>
+#include <asm/pmac_feature.h>
+#include <asm/dbdma.h>
+
#include "i2sbus-interface.h"
-#include "i2sbus-control.h"
#include "../soundbus.h"
struct i2sbus_control {
- volatile struct i2s_control_regs __iomem *controlregs;
- struct resource rsrc;
struct list_head list;
+ struct macio_chip *macio;
};
#define MAX_DBDMA_COMMANDS 32
@@ -45,6 +47,12 @@
volatile struct dbdma_regs __iomem *dbdma;
};
+enum {
+ aoa_resource_i2smmio = 0,
+ aoa_resource_txdbdma,
+ aoa_resource_rxdbdma,
+};
+
struct i2sbus_dev {
struct soundbus_dev sound;
struct macio_dev *macio;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index fb4bed0..ea99083 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -351,6 +351,7 @@
[STAC_REF] = ref922x_pin_configs,
[STAC_D945GTP3] = d945gtp3_pin_configs,
[STAC_D945GTP5] = d945gtp5_pin_configs,
+ [STAC_MACMINI] = d945gtp5_pin_configs,
[STAC_D965_2112] = d965_2112_pin_configs,
};