Merge branch 'akpm' (patches from Andrew Morton)

Merge second patch-bomb from Andrew Morton:
 - a few hotfixes
 - drivers/dma updates
 - MAINTAINERS updates
 - Quite a lot of lib/ updates
 - checkpatch updates
 - binfmt updates
 - autofs4
 - drivers/rtc/
 - various small tweaks to less used filesystems
 - ipc/ updates
 - kernel/watchdog.c changes

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (135 commits)
  mm: softdirty: enable write notifications on VMAs after VM_SOFTDIRTY cleared
  kernel/param: consolidate __{start,stop}___param[] in <linux/moduleparam.h>
  ia64: remove duplicate declarations of __per_cpu_start[] and __per_cpu_end[]
  frv: remove unused declarations of __start___ex_table and __stop___ex_table
  kvm: ensure hard lockup detection is disabled by default
  kernel/watchdog.c: control hard lockup detection default
  staging: rtl8192u: use %*pEn to escape buffer
  staging: rtl8192e: use %*pEn to escape buffer
  staging: wlan-ng: use %*pEhp to print SN
  lib80211: remove unused print_ssid()
  wireless: hostap: proc: print properly escaped SSID
  wireless: ipw2x00: print SSID via %*pE
  wireless: libertas: print esaped string via %*pE
  lib/vsprintf: add %*pE[achnops] format specifier
  lib / string_helpers: introduce string_escape_mem()
  lib / string_helpers: refactoring the test suite
  lib / string_helpers: move documentation to c-file
  include/linux: remove strict_strto* definitions
  arch/x86/mm/numa.c: fix boot failure when all nodes are hotpluggable
  fs: check bh blocknr earlier when searching lru
  ...
This commit is contained in:
Linus Torvalds 2014-10-14 03:54:50 +02:00
commit dfe2c6dcc8
150 changed files with 5592 additions and 1660 deletions

View File

@ -15,39 +15,50 @@ First you must mount binfmt_misc:
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
To actually register a new binary type, you have to set up a string looking like
:name:type:offset:magic:mask:interpreter:flags (where you can choose the ':' upon
your needs) and echo it to /proc/sys/fs/binfmt_misc/register.
:name:type:offset:magic:mask:interpreter:flags (where you can choose the ':'
upon your needs) and echo it to /proc/sys/fs/binfmt_misc/register.
Here is what the fields mean:
- 'name' is an identifier string. A new /proc file will be created with this
name below /proc/sys/fs/binfmt_misc
name below /proc/sys/fs/binfmt_misc; cannot contain slashes '/' for obvious
reasons.
- 'type' is the type of recognition. Give 'M' for magic and 'E' for extension.
- 'offset' is the offset of the magic/mask in the file, counted in bytes. This
defaults to 0 if you omit it (i.e. you write ':name:type::magic...')
defaults to 0 if you omit it (i.e. you write ':name:type::magic...'). Ignored
when using filename extension matching.
- 'magic' is the byte sequence binfmt_misc is matching for. The magic string
may contain hex-encoded characters like \x0a or \xA4. In a shell environment
you will have to write \\x0a to prevent the shell from eating your \.
may contain hex-encoded characters like \x0a or \xA4. Note that you must
escape any NUL bytes; parsing halts at the first one. In a shell environment
you might have to write \\x0a to prevent the shell from eating your \.
If you chose filename extension matching, this is the extension to be
recognised (without the '.', the \x0a specials are not allowed). Extension
matching is case sensitive!
matching is case sensitive, and slashes '/' are not allowed!
- 'mask' is an (optional, defaults to all 0xff) mask. You can mask out some
bits from matching by supplying a string like magic and as long as magic.
The mask is anded with the byte sequence of the file.
The mask is anded with the byte sequence of the file. Note that you must
escape any NUL bytes; parsing halts at the first one. Ignored when using
filename extension matching.
- 'interpreter' is the program that should be invoked with the binary as first
argument (specify the full path)
- 'flags' is an optional field that controls several aspects of the invocation
of the interpreter. It is a string of capital letters, each controls a certain
aspect. The following flags are supported -
'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite the
original argv[0] with the full path to the binary. When this flag is
included, binfmt_misc will add an argument to the argument vector for
this purpose, thus preserving the original argv[0].
of the interpreter. It is a string of capital letters, each controls a
certain aspect. The following flags are supported -
'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite
the original argv[0] with the full path to the binary. When this
flag is included, binfmt_misc will add an argument to the argument
vector for this purpose, thus preserving the original argv[0].
e.g. If your interp is set to /bin/foo and you run `blah` (which is
in /usr/local/bin), then the kernel will execute /bin/foo with
argv[] set to ["/bin/foo", "/usr/local/bin/blah", "blah"]. The
interp has to be aware of this so it can execute /usr/local/bin/blah
with argv[] set to ["blah"].
'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path
of the binary to the interpreter as an argument. When this flag is
included, binfmt_misc will open the file for reading and pass its
descriptor as an argument, instead of the full path, thus allowing
the interpreter to execute non-readable binaries. This feature should
be used with care - the interpreter has to be trusted not to emit
the contents of the non-readable binary.
the interpreter to execute non-readable binaries. This feature
should be used with care - the interpreter has to be trusted not to
emit the contents of the non-readable binary.
'C' - credentials. Currently, the behavior of binfmt_misc is to calculate
the credentials and security token of the new process according to
the interpreter. When this flag is included, these attributes are
@ -58,7 +69,7 @@ Here is what the fields mean:
There are some restrictions:
- the whole register string may not exceed 255 characters
- the whole register string may not exceed 1920 characters
- the magic must reside in the first 128 bytes of the file, i.e.
offset+size(magic) has to be less than 128
- the interpreter string may not exceed 127 characters
@ -110,7 +121,4 @@ passes it the full filename (or the file descriptor) to use. Using $PATH can
cause unexpected behaviour and can be a security hazard.
There is a web page about binfmt_misc at
http://www.tat.physik.uni-tuebingen.de
Richard Günther <rguenth@tat.physik.uni-tuebingen.de>

View File

@ -0,0 +1,18 @@
* TI BQ32000 I2C Serial Real-Time Clock
Required properties:
- compatible: Should contain "ti,bq32000".
- reg: I2C address for chip
Optional properties:
- trickle-resistor-ohms : Selected resistor for trickle charger
Values usable are 1120 and 20180
Should be given if trickle charger should be enabled
- trickle-diode-disable : Do not use internal trickle charger diode
Should be given if internal trickle charger diode should be disabled
Example:
bq32000: rtc@68 {
compatible = "ti,bq32000";
trickle-resistor-ohms = <1120>;
reg = <0x68>;
};

View File

@ -35,7 +35,6 @@ catalyst,24c32 i2c serial eeprom
cirrus,cs42l51 Cirrus Logic CS42L51 audio codec
dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock
dallas,ds1338 I2C RTC with 56-Byte NV RAM
dallas,ds1339 I2C Serial Real-Time Clock
dallas,ds1340 I2C RTC with Trickle Charger
dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output
dallas,ds1631 High-Precision Digital Thermometer

View File

@ -0,0 +1,18 @@
* Dallas DS1339 I2C Serial Real-Time Clock
Required properties:
- compatible: Should contain "dallas,ds1339".
- reg: I2C address for chip
Optional properties:
- trickle-resistor-ohms : Selected resistor for trickle charger
Values usable for ds1339 are 250, 2000, 4000
Should be given if trickle charger should be enabled
- trickle-diode-disable : Do not use internal trickle charger diode
Should be given if internal trickle charger diode should be disabled
Example:
ds1339: rtc@68 {
compatible = "dallas,ds1339";
trickle-resistor-ohms = <250>;
reg = <0x68>;
};

View File

@ -3,7 +3,10 @@
Required properties:
- compatible: should be one of the following.
* "samsung,s3c2410-rtc" - for controllers compatible with s3c2410 rtc.
* "samsung,s3c2416-rtc" - for controllers compatible with s3c2416 rtc.
* "samsung,s3c2443-rtc" - for controllers compatible with s3c2443 rtc.
* "samsung,s3c6410-rtc" - for controllers compatible with s3c6410 rtc.
* "samsung,exynos3250-rtc" - for controllers compatible with exynos3250 rtc.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: Two interrupt numbers to the cpu should be specified. First

View File

@ -0,0 +1,520 @@
<head>
<style> p { max-width:50em} ol, ul {max-width: 40em}</style>
</head>
autofs - how it works
=====================
Purpose
-------
The goal of autofs is to provide on-demand mounting and race free
automatic unmounting of various other filesystems. This provides two
key advantages:
1. There is no need to delay boot until all filesystems that
might be needed are mounted. Processes that try to access those
slow filesystems might be delayed but other processes can
continue freely. This is particularly important for
network filesystems (e.g. NFS) or filesystems stored on
media with a media-changing robot.
2. The names and locations of filesystems can be stored in
a remote database and can change at any time. The content
in that data base at the time of access will be used to provide
a target for the access. The interpretation of names in the
filesystem can even be programmatic rather than database-backed,
allowing wildcards for example, and can vary based on the user who
first accessed a name.
Context
-------
The "autofs4" filesystem module is only one part of an autofs system.
There also needs to be a user-space program which looks up names
and mounts filesystems. This will often be the "automount" program,
though other tools including "systemd" can make use of "autofs4".
This document describes only the kernel module and the interactions
required with any user-space program. Subsequent text refers to this
as the "automount daemon" or simply "the daemon".
"autofs4" is a Linux kernel module with provides the "autofs"
filesystem type. Several "autofs" filesystems can be mounted and they
can each be managed separately, or all managed by the same daemon.
Content
-------
An autofs filesystem can contain 3 sorts of objects: directories,
symbolic links and mount traps. Mount traps are directories with
extra properties as described in the next section.
Objects can only be created by the automount daemon: symlinks are
created with a regular `symlink` system call, while directories and
mount traps are created with `mkdir`. The determination of whether a
directory should be a mount trap or not is quite _ad hoc_, largely for
historical reasons, and is determined in part by the
*direct*/*indirect*/*offset* mount options, and the *maxproto* mount option.
If neither the *direct* or *offset* mount options are given (so the
mount is considered to be *indirect*), then the root directory is
always a regular directory, otherwise it is a mount trap when it is
empty and a regular directory when not empty. Note that *direct* and
*offset* are treated identically so a concise summary is that the root
directory is a mount trap only if the filesystem is mounted *direct*
and the root is empty.
Directories created in the root directory are mount traps only if the
filesystem is mounted *indirect* and they are empty.
Directories further down the tree depend on the *maxproto* mount
option and particularly whether it is less than five or not.
When *maxproto* is five, no directories further down the
tree are ever mount traps, they are always regular directories. When
the *maxproto* is four (or three), these directories are mount traps
precisely when they are empty.
So: non-empty (i.e. non-leaf) directories are never mount traps. Empty
directories are sometimes mount traps, and sometimes not depending on
where in the tree they are (root, top level, or lower), the *maxproto*,
and whether the mount was *indirect* or not.
Mount Traps
---------------
A core element of the implementation of autofs is the Mount Traps
which are provided by the Linux VFS. Any directory provided by a
filesystem can be designated as a trap. This involves two separate
features that work together to allow autofs to do its job.
**DCACHE_NEED_AUTOMOUNT**
If a dentry has the DCACHE_NEED_AUTOMOUNT flag set (which gets set if
the inode has S_AUTOMOUNT set, or can be set directly) then it is
(potentially) a mount trap. Any access to this directory beyond a
"`stat`" will (normally) cause the `d_op->d_automount()` dentry operation
to be called. The task of this method is to find the filesystem that
should be mounted on the directory and to return it. The VFS is
responsible for actually mounting the root of this filesystem on the
directory.
autofs doesn't find the filesystem itself but sends a message to the
automount daemon asking it to find and mount the filesystem. The
autofs `d_automount` method then waits for the daemon to report that
everything is ready. It will then return "`NULL`" indicating that the
mount has already happened. The VFS doesn't try to mount anything but
follows down the mount that is already there.
This functionality is sufficient for some users of mount traps such
as NFS which creates traps so that mountpoints on the server can be
reflected on the client. However it is not sufficient for autofs. As
mounting onto a directory is considered to be "beyond a `stat`", the
automount daemon would not be able to mount a filesystem on the 'trap'
directory without some way to avoid getting caught in the trap. For
that purpose there is another flag.
**DCACHE_MANAGE_TRANSIT**
If a dentry has DCACHE_MANAGE_TRANSIT set then two very different but
related behaviors are invoked, both using the `d_op->d_manage()`
dentry operation.
Firstly, before checking to see if any filesystem is mounted on the
directory, d_manage() will be called with the `rcu_walk` parameter set
to `false`. It may return one of three things:
- A return value of zero indicates that there is nothing special
about this dentry and normal checks for mounts and automounts
should proceed.
autofs normally returns zero, but first waits for any
expiry (automatic unmounting of the mounted filesystem) to
complete. This avoids races.
- A return value of `-EISDIR` tells the VFS to ignore any mounts
on the directory and to not consider calling `->d_automount()`.
This effectively disables the **DCACHE_NEED_AUTOMOUNT** flag
causing the directory not be a mount trap after all.
autofs returns this if it detects that the process performing the
lookup is the automount daemon and that the mount has been
requested but has not yet completed. How it determines this is
discussed later. This allows the automount daemon not to get
caught in the mount trap.
There is a subtlety here. It is possible that a second autofs
filesystem can be mounted below the first and for both of them to
be managed by the same daemon. For the daemon to be able to mount
something on the second it must be able to "walk" down past the
first. This means that d_manage cannot *always* return -EISDIR for
the automount daemon. It must only return it when a mount has
been requested, but has not yet completed.
`d_manage` also returns `-EISDIR` if the dentry shouldn't be a
mount trap, either because it is a symbolic link or because it is
not empty.
- Any other negative value is treated as an error and returned
to the caller.
autofs can return
- -ENOENT if the automount daemon failed to mount anything,
- -ENOMEM if it ran out of memory,
- -EINTR if a signal arrived while waiting for expiry to
complete
- or any other error sent down by the automount daemon.
The second use case only occurs during an "RCU-walk" and so `rcu_walk`
will be set.
An RCU-walk is a fast and lightweight process for walking down a
filename path (i.e. it is like running on tip-toes). RCU-walk cannot
cope with all situations so when it finds a difficulty it falls back
to "REF-walk", which is slower but more robust.
RCU-walk will never call `->d_automount`; the filesystems must already
be mounted or RCU-walk cannot handle the path.
To determine if a mount-trap is safe for RCU-walk mode it calls
`->d_manage()` with `rcu_walk` set to `true`.
In this case `d_manage()` must avoid blocking and should avoid taking
spinlocks if at all possible. Its sole purpose is to determine if it
would be safe to follow down into any mounted directory and the only
reason that it might not be is if an expiry of the mount is
underway.
In the `rcu_walk` case, `d_manage()` cannot return -EISDIR to tell the
VFS that this is a directory that doesn't require d_automount. If
`rcu_walk` sees a dentry with DCACHE_NEED_AUTOMOUNT set but nothing
mounted, it *will* fall back to REF-walk. `d_manage()` cannot make the
VFS remain in RCU-walk mode, but can only tell it to get out of
RCU-walk mode by returning `-ECHILD`.
So `d_manage()`, when called with `rcu_walk` set, should either return
-ECHILD if there is any reason to believe it is unsafe to end the
mounted filesystem, and otherwise should return 0.
autofs will return `-ECHILD` if an expiry of the filesystem has been
initiated or is being considered, otherwise it returns 0.
Mountpoint expiry
-----------------
The VFS has a mechansim for automatically expiring unused mounts,
much as it can expire any unused dentry information from the dcache.
This is guided by the MNT_SHRINKABLE flag. This only applies to
mounts that were created by `d_automount()` returning a filesystem to be
mounted. As autofs doesn't return such a filesystem but leaves the
mounting to the automount daemon, it must involve the automount daemon
in unmounting as well. This also means that autofs has more control
of expiry.
The VFS also supports "expiry" of mounts using the MNT_EXPIRE flag to
the `umount` system call. Unmounting with MNT_EXPIRE will fail unless
a previous attempt had been made, and the filesystem has been inactive
and untouched since that previous attempt. autofs4 does not depend on
this but has its own internal tracking of whether filesystems were
recently used. This allows individual names in the autofs directory
to expire separately.
With version 4 of the protocol, the automount daemon can try to
unmount any filesystems mounted on the autofs filesystem or remove any
symbolic links or empty directories any time it likes. If the unmount
or removal is successful the filesystem will be returned to the state
it was before the mount or creation, so that any access of the name
will trigger normal auto-mount processing. In particlar, `rmdir` and
`unlink` do not leave negative entries in the dcache as a normal
filesystem would, so an attempt to access a recently-removed object is
passed to autofs for handling.
With version 5, this is not safe except for unmounting from top-level
directories. As lower-level directories are never mount traps, other
processes will see an empty directory as soon as the filesystem is
unmounted. So it is generally safest to use the autofs expiry
protocol described below.
Normally the daemon only wants to remove entries which haven't been
used for a while. For this purpose autofs maintains a "`last_used`"
time stamp on each directory or symlink. For symlinks it genuinely
does record the last time the symlink was "used" or followed to find
out where it points to. For directories the field is a slight
misnomer. It actually records the last time that autofs checked if
the directory or one of its descendents was busy and found that it
was. This is just as useful and doesn't require updating the field so
often.
The daemon is able to ask autofs if anything is due to be expired,
using an `ioctl` as discussed later. For a *direct* mount, autofs
considers if the entire mount-tree can be unmounted or not. For an
*indirect* mount, autofs considers each of the names in the top level
directory to determine if any of those can be unmounted and cleaned
up.
There is an option with indirect mounts to consider each of the leaves
that has been mounted on instead of considering the top-level names.
This is intended for compatability with version 4 of autofs and should
be considered as deprecated.
When autofs considers a directory it checks the `last_used` time and
compares it with the "timeout" value set when the filesystem was
mounted, though this check is ignored in some cases. It also checks if
the directory or anything below it is in use. For symbolic links,
only the `last_used` time is ever considered.
If both appear to support expiring the directory or symlink, an action
is taken.
There are two ways to ask autofs to consider expiry. The first is to
use the **AUTOFS_IOC_EXPIRE** ioctl. This only works for indirect
mounts. If it finds something in the root directory to expire it will
return the name of that thing. Once a name has been returned the
automount daemon needs to unmount any filesystems mounted below the
name normally. As described above, this is unsafe for non-toplevel
mounts in a version-5 autofs. For this reason the current `automountd`
does not use this ioctl.
The second mechanism uses either the **AUTOFS_DEV_IOCTL_EXPIRE_CMD** or
the **AUTOFS_IOC_EXPIRE_MULTI** ioctl. This will work for both direct and
indirect mounts. If it selects an object to expire, it will notify
the daemon using the notification mechanism described below. This
will block until the daemon acknowledges the expiry notification.
This implies that the "`EXPIRE`" ioctl must be sent from a different
thread than the one which handles notification.
While the ioctl is blocking, the entry is marked as "expiring" and
`d_manage` will block until the daemon affirms that the unmount has
completed (together with removing any directories that might have been
necessary), or has been aborted.
Communicating with autofs: detecting the daemon
-----------------------------------------------
There are several forms of communication between the automount daemon
and the filesystem. As we have already seen, the daemon can create and
remove directories and symlinks using normal filesystem operations.
autofs knows whether a process requesting some operation is the daemon
or not based on its process-group id number (see getpgid(1)).
When an autofs filesystem it mounted the pgid of the mounting
processes is recorded unless the "pgrp=" option is given, in which
case that number is recorded instead. Any request arriving from a
process in that process group is considered to come from the daemon.
If the daemon ever has to be stopped and restarted a new pgid can be
provided through an ioctl as will be described below.
Communicating with autofs: the event pipe
-----------------------------------------
When an autofs filesystem is mounted, the 'write' end of a pipe must
be passed using the 'fd=' mount option. autofs will write
notification messages to this pipe for the daemon to respond to.
For version 5, the format of the message is:
struct autofs_v5_packet {
int proto_version; /* Protocol version */
int type; /* Type of packet */
autofs_wqt_t wait_queue_token;
__u32 dev;
__u64 ino;
__u32 uid;
__u32 gid;
__u32 pid;
__u32 tgid;
__u32 len;
char name[NAME_MAX+1];
};
where the type is one of
autofs_ptype_missing_indirect
autofs_ptype_expire_indirect
autofs_ptype_missing_direct
autofs_ptype_expire_direct
so messages can indicate that a name is missing (something tried to
access it but it isn't there) or that it has been selected for expiry.
The pipe will be set to "packet mode" (equivalent to passing
`O_DIRECT`) to _pipe2(2)_ so that a read from the pipe will return at
most one packet, and any unread portion of a packet will be discarded.
The `wait_queue_token` is a unique number which can identify a
particular request to be acknowledged. When a message is sent over
the pipe the affected dentry is marked as either "active" or
"expiring" and other accesses to it block until the message is
acknowledged using one of the ioctls below and the relevant
`wait_queue_token`.
Communicating with autofs: root directory ioctls
------------------------------------------------
The root directory of an autofs filesystem will respond to a number of
ioctls. The process issuing the ioctl must have the CAP_SYS_ADMIN
capability, or must be the automount daemon.
The available ioctl commands are:
- **AUTOFS_IOC_READY**: a notification has been handled. The argument
to the ioctl command is the "wait_queue_token" number
corresponding to the notification being acknowledged.
- **AUTOFS_IOC_FAIL**: similar to above, but indicates failure with
the error code `ENOENT`.
- **AUTOFS_IOC_CATATONIC**: Causes the autofs to enter "catatonic"
mode meaning that it stops sending notifications to the daemon.
This mode is also entered if a write to the pipe fails.
- **AUTOFS_IOC_PROTOVER**: This returns the protocol version in use.
- **AUTOFS_IOC_PROTOSUBVER**: Returns the protocol sub-version which
is really a version number for the implementation. It is
currently 2.
- **AUTOFS_IOC_SETTIMEOUT**: This passes a pointer to an unsigned
long. The value is used to set the timeout for expiry, and
the current timeout value is stored back through the pointer.
- **AUTOFS_IOC_ASKUMOUNT**: Returns, in the pointed-to `int`, 1 if
the filesystem could be unmounted. This is only a hint as
the situation could change at any instant. This call can be
use to avoid a more expensive full unmount attempt.
- **AUTOFS_IOC_EXPIRE**: as described above, this asks if there is
anything suitable to expire. A pointer to a packet:
struct autofs_packet_expire_multi {
int proto_version; /* Protocol version */
int type; /* Type of packet */
autofs_wqt_t wait_queue_token;
int len;
char name[NAME_MAX+1];
};
is required. This is filled in with the name of something
that can be unmounted or removed. If nothing can be expired,
`errno` is set to `EAGAIN`. Even though a `wait_queue_token`
is present in the structure, no "wait queue" is established
and no acknowledgment is needed.
- **AUTOFS_IOC_EXPIRE_MULTI**: This is similar to
**AUTOFS_IOC_EXPIRE** except that it causes notification to be
sent to the daemon, and it blocks until the daemon acknowledges.
The argument is an integer which can contain two different flags.
**AUTOFS_EXP_IMMEDIATE** causes `last_used` time to be ignored
and objects are expired if the are not in use.
**AUTOFS_EXP_LEAVES** will select a leaf rather than a top-level
name to expire. This is only safe when *maxproto* is 4.
Communicating with autofs: char-device ioctls
---------------------------------------------
It is not always possible to open the root of an autofs filesystem,
particularly a *direct* mounted filesystem. If the automount daemon
is restarted there is no way for it to regain control of existing
mounts using any of the above communication channels. To address this
need there is a "miscellaneous" character device (major 10, minor 235)
which can be used to communicate directly with the autofs filesystem.
It requires CAP_SYS_ADMIN for access.
The `ioctl`s that can be used on this device are described in a separate
document `autofs4-mount-control.txt`, and are summarized briefly here.
Each ioctl is passed a pointer to an `autofs_dev_ioctl` structure:
struct autofs_dev_ioctl {
__u32 ver_major;
__u32 ver_minor;
__u32 size; /* total size of data passed in
* including this struct */
__s32 ioctlfd; /* automount command fd */
__u32 arg1; /* Command parameters */
__u32 arg2;
char path[0];
};
For the **OPEN_MOUNT** and **IS_MOUNTPOINT** commands, the target
filesystem is identified by the `path`. All other commands identify
the filesystem by the `ioctlfd` which is a file descriptor open on the
root, and which can be returned by **OPEN_MOUNT**.
The `ver_major` and `ver_minor` are in/out parameters which check that
the requested version is supported, and report the maximum version
that the kernel module can support.
Commands are:
- **AUTOFS_DEV_IOCTL_VERSION_CMD**: does nothing, except validate and
set version numbers.
- **AUTOFS_DEV_IOCTL_OPENMOUNT_CMD**: return an open file descriptor
on the root of an autofs filesystem. The filesystem is identified
by name and device number, which is stored in `arg1`. Device
numbers for existing filesystems can be found in
`/proc/self/mountinfo`.
- **AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD**: same as `close(ioctlfd)`.
- **AUTOFS_DEV_IOCTL_SETPIPEFD_CMD**: if the filesystem is in
catatonic mode, this can provide the write end of a new pipe
in `arg1` to re-establish communication with a daemon. The
process group of the calling process is used to identify the
daemon.
- **AUTOFS_DEV_IOCTL_REQUESTER_CMD**: `path` should be a
name within the filesystem that has been auto-mounted on.
arg1 is the dev number of the underlying autofs. On successful
return, `arg1` and `arg2` will be the UID and GID of the process
which triggered that mount.
- **AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD**: Check if path is a
mountpoint of a particular type - see separate documentation for
details.
- **AUTOFS_DEV_IOCTL_PROTOVER_CMD**:
- **AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD**:
- **AUTOFS_DEV_IOCTL_READY_CMD**:
- **AUTOFS_DEV_IOCTL_FAIL_CMD**:
- **AUTOFS_DEV_IOCTL_CATATONIC_CMD**:
- **AUTOFS_DEV_IOCTL_TIMEOUT_CMD**:
- **AUTOFS_DEV_IOCTL_EXPIRE_CMD**:
- **AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD**: These all have the same
function as the similarly named **AUTOFS_IOC** ioctls, except
that **FAIL** can be given an explicit error number in `arg1`
instead of assuming `ENOENT`, and this **EXPIRE** command
corresponds to **AUTOFS_IOC_EXPIRE_MULTI**.
Catatonic mode
--------------
As mentioned, an autofs mount can enter "catatonic" mode. This
happens if a write to the notification pipe fails, or if it is
explicitly requested by an `ioctl`.
When entering catatonic mode, the pipe is closed and any pending
notifications are acknowledged with the error `ENOENT`.
Once in catatonic mode attempts to access non-existing names will
result in `ENOENT` while attempts to access existing directories will
be treated in the same way as if they came from the daemon, so mount
traps will not fire.
When the filesystem is mounted a _uid_ and _gid_ can be given which
set the ownership of directories and symbolic links. When the
filesystem is in catatonic mode, any process with a matching UID can
create directories or symlinks in the root directory, but not in other
directories.
Catatonic mode can only be left via the
**AUTOFS_DEV_IOCTL_OPENMOUNT_CMD** ioctl on the `/dev/autofs`.
autofs, name spaces, and shared mounts
--------------------------------------
With bind mounts and name spaces it is possible for an autofs
filesystem to appear at multiple places in one or more filesystem
name spaces. For this to work sensibly, the autofs filesystem should
always be mounted "shared". e.g.
> `mount --make-shared /autofs/mount/point`
The automount daemon is only able to mange a single mount location for
an autofs filesystem and if mounts on that are not 'shared', other
locations will not behave as expected. In particular access to those
other locations will likely result in the `ELOOP` error
> Too many levels of symbolic links

View File

@ -70,6 +70,38 @@ DMA addresses types dma_addr_t:
For printing a dma_addr_t type which can vary based on build options,
regardless of the width of the CPU data path. Passed by reference.
Raw buffer as an escaped string:
%*pE[achnops]
For printing raw buffer as an escaped string. For the following buffer
1b 62 20 5c 43 07 22 90 0d 5d
few examples show how the conversion would be done (the result string
without surrounding quotes):
%*pE "\eb \C\a"\220\r]"
%*pEhp "\x1bb \C\x07"\x90\x0d]"
%*pEa "\e\142\040\\\103\a\042\220\r\135"
The conversion rules are applied according to an optional combination
of flags (see string_escape_mem() kernel documentation for the
details):
a - ESCAPE_ANY
c - ESCAPE_SPECIAL
h - ESCAPE_HEX
n - ESCAPE_NULL
o - ESCAPE_OCTAL
p - ESCAPE_NP
s - ESCAPE_SPACE
By default ESCAPE_ANY_NP is used.
ESCAPE_ANY_NP is the sane choice for many cases, in particularly for
printing SSIDs.
If field width is omitted the 1 byte only will be escaped.
Raw buffer as a hex string:
%*ph 00 01 02 ... 3f
%*phC 00:01:02: ... :3f

View File

@ -190,6 +190,8 @@ core_pattern is used to specify a core dumpfile pattern name.
%% output one '%'
%p pid
%P global pid (init PID namespace)
%i tid
%I global tid (init PID namespace)
%u uid
%g gid
%d dump mode, matches PR_SET_DUMPABLE and

View File

@ -1338,8 +1338,7 @@ ARM/SAMSUNG MOBILE MACHINE SUPPORT
M: Kyungmin Park <kyungmin.park@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-s5pv210/mach-aquila.c
F: arch/arm/mach-s5pv210/mach-goni.c
F: arch/arm/mach-s5pv210/
ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT
M: Kyungmin Park <kyungmin.park@samsung.com>
@ -1550,6 +1549,7 @@ T: git git://git.xilinx.com/linux-xlnx.git
S: Supported
F: arch/arm/mach-zynq/
F: drivers/cpuidle/cpuidle-zynq.c
F: drivers/block/xsysace.c
N: zynq
N: xilinx
F: drivers/clocksource/cadence_ttc_timer.c
@ -1738,6 +1738,12 @@ M: Nicolas Ferre <nicolas.ferre@atmel.com>
S: Supported
F: drivers/net/ethernet/cadence/
ATMEL NAND DRIVER
M: Josh Wu <josh.wu@atmel.com>
L: linux-mtd@lists.infradead.org
S: Supported
F: drivers/mtd/nand/atmel_nand*
ATMEL SPI DRIVER
M: Nicolas Ferre <nicolas.ferre@atmel.com>
S: Supported
@ -3048,7 +3054,7 @@ M: Sumit Semwal <sumit.semwal@linaro.org>
S: Maintained
L: linux-media@vger.kernel.org
L: dri-devel@lists.freedesktop.org
L: linaro-mm-sig@lists.linaro.org
L: linaro-mm-sig@lists.linaro.org (moderated for non-subscribers)
F: drivers/dma-buf/
F: include/linux/dma-buf*
F: include/linux/reservation.h
@ -4297,9 +4303,8 @@ S: Maintained
F: drivers/media/dvb-frontends/hd29l2*
HEWLETT-PACKARD SMART2 RAID DRIVER
M: Chirag Kantharia <chirag.kantharia@hp.com>
L: iss_storagedev@hp.com
S: Maintained
S: Orphan
F: Documentation/blockdev/cpqarray.txt
F: drivers/block/cpqarray.*
@ -5300,6 +5305,13 @@ F: include/linux/lockd/
F: include/linux/sunrpc/
F: include/uapi/linux/sunrpc/
KERNEL SELFTEST FRAMEWORK
M: Shuah Khan <shuahkh@osg.samsung.com>
L: linux-api@vger.kernel.org
T: git git://git.kernel.org/pub/scm/shuah/linux-kselftest
S: Maintained
F: tools/testing/selftests
KERNEL VIRTUAL MACHINE (KVM)
M: Gleb Natapov <gleb@kernel.org>
M: Paolo Bonzini <pbonzini@redhat.com>
@ -5746,11 +5758,8 @@ T: git git://github.com/linux-test-project/ltp.git
S: Maintained
M32R ARCHITECTURE
M: Hirokazu Takata <takata@linux-m32r.org>
L: linux-m32r@ml.linux-m32r.org (moderated for non-subscribers)
L: linux-m32r-ja@ml.linux-m32r.org (in Japanese)
W: http://www.linux-m32r.org/
S: Maintained
S: Orphan
F: arch/m32r/
M68K ARCHITECTURE
@ -7974,7 +7983,6 @@ S: Supported
F: drivers/mfd/sec*.c
F: drivers/regulator/s2m*.c
F: drivers/regulator/s5m*.c
F: drivers/rtc/rtc-sec.c
F: include/linux/mfd/samsung/
SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
@ -10315,10 +10323,6 @@ M: John Linn <John.Linn@xilinx.com>
S: Maintained
F: drivers/net/ethernet/xilinx/xilinx_axienet*
XILINX SYSTEMACE DRIVER
S: Orphan
F: drivers/block/xsysace.c
XILINX UARTLITE SERIAL DRIVER
M: Peter Korsgaard <jacmet@sunsite.dk>
L: linux-serial@vger.kernel.org

View File

@ -164,7 +164,7 @@
};
rtc: rtc@10070000 {
compatible = "samsung,s3c6410-rtc";
compatible = "samsung,exynos3250-rtc";
reg = <0x10070000 0x100>;
interrupts = <0 73 0>, <0 74 0>;
status = "disabled";

View File

@ -416,17 +416,17 @@ static struct pxafb_mach_info *lpd270_lcd_to_use;
static int __init lpd270_set_lcd(char *str)
{
if (!strnicmp(str, "lq057q3dc02", 11)) {
if (!strncasecmp(str, "lq057q3dc02", 11)) {
lpd270_lcd_to_use = &sharp_lq057q3dc02;
} else if (!strnicmp(str, "lq121s1dg31", 11)) {
} else if (!strncasecmp(str, "lq121s1dg31", 11)) {
lpd270_lcd_to_use = &sharp_lq121s1dg31;
} else if (!strnicmp(str, "lq036q1da01", 11)) {
} else if (!strncasecmp(str, "lq036q1da01", 11)) {
lpd270_lcd_to_use = &sharp_lq036q1da01;
} else if (!strnicmp(str, "lq64d343", 8)) {
} else if (!strncasecmp(str, "lq64d343", 8)) {
lpd270_lcd_to_use = &sharp_lq64d343;
} else if (!strnicmp(str, "lq10d368", 8)) {
} else if (!strncasecmp(str, "lq10d368", 8)) {
lpd270_lcd_to_use = &sharp_lq10d368;
} else if (!strnicmp(str, "lq035q7db02-20", 14)) {
} else if (!strncasecmp(str, "lq035q7db02-20", 14)) {
lpd270_lcd_to_use = &sharp_lq035q7db02_20;
} else {
printk(KERN_INFO "lpd270: unknown lcd panel [%s]\n", str);

View File

@ -6,8 +6,6 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
extern const struct exception_table_entry __attribute__((aligned(8))) __start___ex_table[];
extern const struct exception_table_entry __attribute__((aligned(8))) __stop___ex_table[];
extern const void __memset_end, __memset_user_error_lr, __memset_user_error_handler;
extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler;
extern spinlock_t modlist_lock;

View File

@ -10,7 +10,7 @@
#include <linux/uaccess.h>
#include <asm-generic/sections.h>
extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[];
extern char __phys_per_cpu_start[];
#ifdef CONFIG_SMP
extern char __cpu0_per_cpu[];
#endif

View File

@ -964,6 +964,7 @@ static void vgetcpu_set_mode(void)
vgetcpu_mode = VGETCPU_LSL;
}
#ifdef CONFIG_IA32_EMULATION
/* May not be __init: called during resume */
static void syscall32_cpu_init(void)
{
@ -975,7 +976,8 @@ static void syscall32_cpu_init(void)
wrmsrl(MSR_CSTAR, ia32_cstar_target);
}
#endif
#endif /* CONFIG_IA32_EMULATION */
#endif /* CONFIG_X86_64 */
#ifdef CONFIG_X86_32
void enable_sep_cpu(void)

View File

@ -237,7 +237,7 @@ static void fill_up_crash_elf_data(struct crash_elf_data *ced,
ced->max_nr_ranges++;
/* If crashk_low_res is not 0, another range split possible */
if (crashk_low_res.end != 0)
if (crashk_low_res.end)
ced->max_nr_ranges++;
}
@ -335,9 +335,11 @@ static int elf_header_exclude_ranges(struct crash_elf_data *ced,
if (ret)
return ret;
ret = exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
if (ret)
return ret;
if (crashk_low_res.end) {
ret = exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
if (ret)
return ret;
}
/* Exclude GART region */
if (ced->gart_end) {

View File

@ -26,6 +26,7 @@
#include <asm/setup.h>
#include <asm/crash.h>
#include <asm/efi.h>
#include <asm/kexec-bzimage64.h>
#define MAX_ELFCOREHDR_STR_LEN 30 /* elfcorehdr=0x<64bit-value> */
@ -267,7 +268,7 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
return ret;
}
int bzImage64_probe(const char *buf, unsigned long len)
static int bzImage64_probe(const char *buf, unsigned long len)
{
int ret = -ENOEXEC;
struct setup_header *header;
@ -325,10 +326,10 @@ int bzImage64_probe(const char *buf, unsigned long len)
return ret;
}
void *bzImage64_load(struct kimage *image, char *kernel,
unsigned long kernel_len, char *initrd,
unsigned long initrd_len, char *cmdline,
unsigned long cmdline_len)
static void *bzImage64_load(struct kimage *image, char *kernel,
unsigned long kernel_len, char *initrd,
unsigned long initrd_len, char *cmdline,
unsigned long cmdline_len)
{
struct setup_header *header;
@ -514,7 +515,7 @@ out_free_params:
}
/* This cleanup function is called after various segments have been loaded */
int bzImage64_cleanup(void *loader_data)
static int bzImage64_cleanup(void *loader_data)
{
struct bzimage64_data *ldata = loader_data;
@ -528,7 +529,7 @@ int bzImage64_cleanup(void *loader_data)
}
#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
{
bool trusted;
int ret;

View File

@ -35,6 +35,7 @@
#include <linux/slab.h>
#include <linux/kprobes.h>
#include <linux/debugfs.h>
#include <linux/nmi.h>
#include <asm/timer.h>
#include <asm/cpu.h>
#include <asm/traps.h>
@ -499,6 +500,13 @@ void __init kvm_guest_init(void)
#else
kvm_guest_cpu_init();
#endif
/*
* Hard lockup detection is enabled by default. Disable it, as guests
* can get false positives too easily, for example if the host is
* overcommitted.
*/
watchdog_enable_hardlockup_detector(false);
}
static noinline uint32_t __kvm_cpuid_base(void)

View File

@ -86,6 +86,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
pgprot_t prot;
int retval;
void __iomem *ret_addr;
int ram_region;
/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
@ -108,12 +109,23 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
pfn = phys_addr >> PAGE_SHIFT;
last_pfn = last_addr >> PAGE_SHIFT;
if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
__ioremap_check_ram) == 1)
/* First check if whole region can be identified as RAM or not */
ram_region = region_is_ram(phys_addr, size);
if (ram_region > 0) {
WARN_ONCE(1, "ioremap on RAM at 0x%lx - 0x%lx\n",
(unsigned long int)phys_addr,
(unsigned long int)last_addr);
return NULL;
}
/* If could not be identified(-1), check page by page */
if (ram_region < 0) {
pfn = phys_addr >> PAGE_SHIFT;
last_pfn = last_addr >> PAGE_SHIFT;
if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
__ioremap_check_ram) == 1)
return NULL;
}
/*
* Mappings have to be page-aligned
*/

View File

@ -463,6 +463,42 @@ static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
return true;
}
static void __init numa_clear_kernel_node_hotplug(void)
{
int i, nid;
nodemask_t numa_kernel_nodes = NODE_MASK_NONE;
unsigned long start, end;
struct memblock_region *r;
/*
* At this time, all memory regions reserved by memblock are
* used by the kernel. Set the nid in memblock.reserved will
* mark out all the nodes the kernel resides in.
*/
for (i = 0; i < numa_meminfo.nr_blks; i++) {
struct numa_memblk *mb = &numa_meminfo.blk[i];
memblock_set_node(mb->start, mb->end - mb->start,
&memblock.reserved, mb->nid);
}
/* Mark all kernel nodes. */
for_each_memblock(reserved, r)
node_set(r->nid, numa_kernel_nodes);
/* Clear MEMBLOCK_HOTPLUG flag for memory in kernel nodes. */
for (i = 0; i < numa_meminfo.nr_blks; i++) {
nid = numa_meminfo.blk[i].nid;
if (!node_isset(nid, numa_kernel_nodes))
continue;
start = numa_meminfo.blk[i].start;
end = numa_meminfo.blk[i].end;
memblock_clear_hotplug(start, end - start);
}
}
static int __init numa_register_memblks(struct numa_meminfo *mi)
{
unsigned long uninitialized_var(pfn_align);
@ -480,6 +516,15 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)
&memblock.memory, mb->nid);
}
/*
* At very early time, the kernel have to use some memory such as
* loading the kernel image. We cannot prevent this anyway. So any
* node the kernel resides in should be un-hotpluggable.
*
* And when we come here, alloc node data won't fail.
*/
numa_clear_kernel_node_hotplug();
/*
* If sections array is gonna be used for pfn -> nid mapping, check
* whether its granularity is fine enough.
@ -548,41 +593,6 @@ static void __init numa_init_array(void)
}
}
static void __init numa_clear_kernel_node_hotplug(void)
{
int i, nid;
nodemask_t numa_kernel_nodes = NODE_MASK_NONE;
unsigned long start, end;
struct memblock_region *r;
/*
* At this time, all memory regions reserved by memblock are
* used by the kernel. Set the nid in memblock.reserved will
* mark out all the nodes the kernel resides in.
*/
for (i = 0; i < numa_meminfo.nr_blks; i++) {
struct numa_memblk *mb = &numa_meminfo.blk[i];
memblock_set_node(mb->start, mb->end - mb->start,
&memblock.reserved, mb->nid);
}
/* Mark all kernel nodes. */
for_each_memblock(reserved, r)
node_set(r->nid, numa_kernel_nodes);
/* Clear MEMBLOCK_HOTPLUG flag for memory in kernel nodes. */
for (i = 0; i < numa_meminfo.nr_blks; i++) {
nid = numa_meminfo.blk[i].nid;
if (!node_isset(nid, numa_kernel_nodes))
continue;
start = numa_meminfo.blk[i].start;
end = numa_meminfo.blk[i].end;
memblock_clear_hotplug(start, end - start);
}
}
static int __init numa_init(int (*init_func)(void))
{
int i;
@ -637,15 +647,6 @@ static int __init numa_init(int (*init_func)(void))
}
numa_init_array();
/*
* At very early time, the kernel have to use some memory such as
* loading the kernel image. We cannot prevent this anyway. So any
* node the kernel resides in should be un-hotpluggable.
*
* And when we come here, numa_init() won't fail.
*/
numa_clear_kernel_node_hotplug();
return 0;
}

View File

@ -18,8 +18,9 @@ $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
targets += kexec-purgatory.c
CMD_BIN2C = $(objtree)/scripts/basic/bin2c
quiet_cmd_bin2c = BIN2C $@
cmd_bin2c = cat $(obj)/purgatory.ro | $(objtree)/scripts/basic/bin2c kexec_purgatory > $(obj)/kexec-purgatory.c
cmd_bin2c = $(CMD_BIN2C) kexec_purgatory < $< > $@
$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
$(call if_changed,bin2c)

View File

@ -14,11 +14,14 @@ struct dma_coherent_mem {
int size;
int flags;
unsigned long *bitmap;
spinlock_t spinlock;
};
int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
dma_addr_t device_addr, size_t size, int flags)
static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_addr,
size_t size, int flags,
struct dma_coherent_mem **mem)
{
struct dma_coherent_mem *dma_mem = NULL;
void __iomem *mem_base = NULL;
int pages = size >> PAGE_SHIFT;
int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
@ -27,40 +30,77 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
goto out;
if (!size)
goto out;
if (dev->dma_mem)
goto out;
/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
mem_base = ioremap(phys_addr, size);
if (!mem_base)
goto out;
dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
if (!dev->dma_mem)
dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
if (!dma_mem)
goto out;
dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
if (!dma_mem->bitmap)
goto out;
dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
if (!dev->dma_mem->bitmap)
goto free1_out;
dev->dma_mem->virt_base = mem_base;
dev->dma_mem->device_base = device_addr;
dev->dma_mem->pfn_base = PFN_DOWN(phys_addr);
dev->dma_mem->size = pages;
dev->dma_mem->flags = flags;
dma_mem->virt_base = mem_base;
dma_mem->device_base = device_addr;
dma_mem->pfn_base = PFN_DOWN(phys_addr);
dma_mem->size = pages;
dma_mem->flags = flags;
spin_lock_init(&dma_mem->spinlock);
*mem = dma_mem;
if (flags & DMA_MEMORY_MAP)
return DMA_MEMORY_MAP;
return DMA_MEMORY_IO;
free1_out:
kfree(dev->dma_mem);
out:
out:
kfree(dma_mem);
if (mem_base)
iounmap(mem_base);
return 0;
}
static void dma_release_coherent_memory(struct dma_coherent_mem *mem)
{
if (!mem)
return;
iounmap(mem->virt_base);
kfree(mem->bitmap);
kfree(mem);
}
static int dma_assign_coherent_memory(struct device *dev,
struct dma_coherent_mem *mem)
{
if (dev->dma_mem)
return -EBUSY;
dev->dma_mem = mem;
/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
return 0;
}
int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
dma_addr_t device_addr, size_t size, int flags)
{
struct dma_coherent_mem *mem;
int ret;
ret = dma_init_coherent_memory(phys_addr, device_addr, size, flags,
&mem);
if (ret == 0)
return 0;
if (dma_assign_coherent_memory(dev, mem) == 0)
return ret;
dma_release_coherent_memory(mem);
return 0;
}
EXPORT_SYMBOL(dma_declare_coherent_memory);
void dma_release_declared_memory(struct device *dev)
@ -69,10 +109,8 @@ void dma_release_declared_memory(struct device *dev)
if (!mem)
return;
dma_release_coherent_memory(mem);
dev->dma_mem = NULL;
iounmap(mem->virt_base);
kfree(mem->bitmap);
kfree(mem);
}
EXPORT_SYMBOL(dma_release_declared_memory);
@ -80,6 +118,7 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
dma_addr_t device_addr, size_t size)
{
struct dma_coherent_mem *mem = dev->dma_mem;
unsigned long flags;
int pos, err;
size += device_addr & ~PAGE_MASK;
@ -87,8 +126,11 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
if (!mem)
return ERR_PTR(-EINVAL);
spin_lock_irqsave(&mem->spinlock, flags);
pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
err = bitmap_allocate_region(mem->bitmap, pos, get_order(size));
spin_unlock_irqrestore(&mem->spinlock, flags);
if (err != 0)
return ERR_PTR(err);
return mem->virt_base + (pos << PAGE_SHIFT);
@ -115,6 +157,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
{
struct dma_coherent_mem *mem;
int order = get_order(size);
unsigned long flags;
int pageno;
if (!dev)
@ -124,6 +167,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
return 0;
*ret = NULL;
spin_lock_irqsave(&mem->spinlock, flags);
if (unlikely(size > (mem->size << PAGE_SHIFT)))
goto err;
@ -138,10 +182,12 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
*dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
*ret = mem->virt_base + (pageno << PAGE_SHIFT);
memset(*ret, 0, size);
spin_unlock_irqrestore(&mem->spinlock, flags);
return 1;
err:
spin_unlock_irqrestore(&mem->spinlock, flags);
/*
* In the case where the allocation can not be satisfied from the
* per-device area, try to fall back to generic memory if the
@ -171,8 +217,11 @@ int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
if (mem && vaddr >= mem->virt_base && vaddr <
(mem->virt_base + (mem->size << PAGE_SHIFT))) {
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
unsigned long flags;
spin_lock_irqsave(&mem->spinlock, flags);
bitmap_release_region(mem->bitmap, page, order);
spin_unlock_irqrestore(&mem->spinlock, flags);
return 1;
}
return 0;
@ -218,3 +267,61 @@ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
return 0;
}
EXPORT_SYMBOL(dma_mmap_from_coherent);
/*
* Support for reserved memory regions defined in device tree
*/
#ifdef CONFIG_OF_RESERVED_MEM
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_reserved_mem.h>
static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
{
struct dma_coherent_mem *mem = rmem->priv;
if (!mem &&
dma_init_coherent_memory(rmem->base, rmem->base, rmem->size,
DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE,
&mem) != DMA_MEMORY_MAP) {
pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n",
&rmem->base, (unsigned long)rmem->size / SZ_1M);
return -ENODEV;
}
rmem->priv = mem;
dma_assign_coherent_memory(dev, mem);
return 0;
}
static void rmem_dma_device_release(struct reserved_mem *rmem,
struct device *dev)
{
dev->dma_mem = NULL;
}
static const struct reserved_mem_ops rmem_dma_ops = {
.device_init = rmem_dma_device_init,
.device_release = rmem_dma_device_release,
};
static int __init rmem_dma_setup(struct reserved_mem *rmem)
{
unsigned long node = rmem->fdt_node;
if (of_get_flat_dt_prop(node, "reusable", NULL))
return -EINVAL;
#ifdef CONFIG_ARM
if (!of_get_flat_dt_prop(node, "no-map", NULL)) {
pr_err("Reserved memory: regions without no-map are not yet supported\n");
return -EINVAL;
}
#endif
rmem->ops = &rmem_dma_ops;
pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n",
&rmem->base, (unsigned long)rmem->size / SZ_1M);
return 0;
}
RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup);
#endif

View File

@ -211,3 +211,69 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
{
return cma_release(dev_get_cma_area(dev), pages, count);
}
/*
* Support for reserved memory regions defined in device tree
*/
#ifdef CONFIG_OF_RESERVED_MEM
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_reserved_mem.h>
#undef pr_fmt
#define pr_fmt(fmt) fmt
static void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
{
dev_set_cma_area(dev, rmem->priv);
}
static void rmem_cma_device_release(struct reserved_mem *rmem,
struct device *dev)
{
dev_set_cma_area(dev, NULL);
}
static const struct reserved_mem_ops rmem_cma_ops = {
.device_init = rmem_cma_device_init,
.device_release = rmem_cma_device_release,
};
static int __init rmem_cma_setup(struct reserved_mem *rmem)
{
phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
phys_addr_t mask = align - 1;
unsigned long node = rmem->fdt_node;
struct cma *cma;
int err;
if (!of_get_flat_dt_prop(node, "reusable", NULL) ||
of_get_flat_dt_prop(node, "no-map", NULL))
return -EINVAL;
if ((rmem->base & mask) || (rmem->size & mask)) {
pr_err("Reserved memory: incorrect alignment of CMA region\n");
return -EINVAL;
}
err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma);
if (err) {
pr_err("Reserved memory: unable to setup CMA region\n");
return err;
}
/* Architecture specific contiguous memory fixup. */
dma_contiguous_early_fixup(rmem->base, rmem->size);
if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
dma_contiguous_set_default(cma);
rmem->ops = &rmem_cma_ops;
rmem->priv = cma;
pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n",
&rmem->base, (unsigned long)rmem->size / SZ_1M);
return 0;
}
RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
#endif

View File

@ -38,6 +38,15 @@ config COMMON_CLK_MAX77686
---help---
This driver supports Maxim 77686 crystal oscillator clock.
config COMMON_CLK_RK808
tristate "Clock driver for RK808"
depends on MFD_RK808
---help---
This driver supports RK808 crystal oscillator clock. These
multi-function devices have two fixed-rate oscillators,
clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
by control register.
config COMMON_CLK_SI5351
tristate "Clock driver for SiLabs 5351A/B/C"
depends on I2C

View File

@ -28,6 +28,7 @@ obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o
obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o

170
drivers/clk/clk-rk808.c Normal file
View File

@ -0,0 +1,170 @@
/*
* Clkout driver for Rockchip RK808
*
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
*
* Author:Chris Zhong <zyw@rock-chips.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mfd/rk808.h>
#include <linux/i2c.h>
#define RK808_NR_OUTPUT 2
struct rk808_clkout {
struct rk808 *rk808;
struct clk_onecell_data clk_data;
struct clk_hw clkout1_hw;
struct clk_hw clkout2_hw;
};
static unsigned long rk808_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return 32768;
}
static int rk808_clkout2_enable(struct clk_hw *hw, bool enable)
{
struct rk808_clkout *rk808_clkout = container_of(hw,
struct rk808_clkout,
clkout2_hw);
struct rk808 *rk808 = rk808_clkout->rk808;
return regmap_update_bits(rk808->regmap, RK808_CLK32OUT_REG,
CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0);
}
static int rk808_clkout2_prepare(struct clk_hw *hw)
{
return rk808_clkout2_enable(hw, true);
}
static void rk808_clkout2_unprepare(struct clk_hw *hw)
{
rk808_clkout2_enable(hw, false);
}
static int rk808_clkout2_is_prepared(struct clk_hw *hw)
{
struct rk808_clkout *rk808_clkout = container_of(hw,
struct rk808_clkout,
clkout2_hw);
struct rk808 *rk808 = rk808_clkout->rk808;
uint32_t val;
int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val);
if (ret < 0)
return ret;
return (val & CLK32KOUT2_EN) ? 1 : 0;
}
static const struct clk_ops rk808_clkout1_ops = {
.recalc_rate = rk808_clkout_recalc_rate,
};
static const struct clk_ops rk808_clkout2_ops = {
.prepare = rk808_clkout2_prepare,
.unprepare = rk808_clkout2_unprepare,
.is_prepared = rk808_clkout2_is_prepared,
.recalc_rate = rk808_clkout_recalc_rate,
};
static int rk808_clkout_probe(struct platform_device *pdev)
{
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
struct i2c_client *client = rk808->i2c;
struct device_node *node = client->dev.of_node;
struct clk_init_data init = {};
struct clk **clk_table;
struct rk808_clkout *rk808_clkout;
rk808_clkout = devm_kzalloc(&client->dev,
sizeof(*rk808_clkout), GFP_KERNEL);
if (!rk808_clkout)
return -ENOMEM;
rk808_clkout->rk808 = rk808;
clk_table = devm_kcalloc(&client->dev, RK808_NR_OUTPUT,
sizeof(struct clk *), GFP_KERNEL);
if (!clk_table)
return -ENOMEM;
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;
init.num_parents = 0;
init.name = "rk808-clkout1";
init.ops = &rk808_clkout1_ops;
rk808_clkout->clkout1_hw.init = &init;
/* optional override of the clockname */
of_property_read_string_index(node, "clock-output-names",
0, &init.name);
clk_table[0] = devm_clk_register(&client->dev,
&rk808_clkout->clkout1_hw);
if (IS_ERR(clk_table[0]))
return PTR_ERR(clk_table[0]);
init.name = "rk808-clkout2";
init.ops = &rk808_clkout2_ops;
rk808_clkout->clkout2_hw.init = &init;
/* optional override of the clockname */
of_property_read_string_index(node, "clock-output-names",
1, &init.name);
clk_table[1] = devm_clk_register(&client->dev,
&rk808_clkout->clkout2_hw);
if (IS_ERR(clk_table[1]))
return PTR_ERR(clk_table[1]);
rk808_clkout->clk_data.clks = clk_table;
rk808_clkout->clk_data.clk_num = RK808_NR_OUTPUT;
return of_clk_add_provider(node, of_clk_src_onecell_get,
&rk808_clkout->clk_data);
}
static int rk808_clkout_remove(struct platform_device *pdev)
{
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
struct i2c_client *client = rk808->i2c;
struct device_node *node = client->dev.of_node;
of_clk_del_provider(node);
return 0;
}
static struct platform_driver rk808_clkout_driver = {
.probe = rk808_clkout_probe,
.remove = rk808_clkout_remove,
.driver = {
.name = "rk808-clkout",
},
};
module_platform_driver(rk808_clkout_driver);
MODULE_DESCRIPTION("Clkout driver for the rk808 series PMICs");
MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:rk808-clkout");

View File

@ -3574,7 +3574,7 @@ static int srpt_parse_i_port_id(u8 i_port_id[16], const char *name)
int ret, rc;
p = name;
if (strnicmp(p, "0x", 2) == 0)
if (strncasecmp(p, "0x", 2) == 0)
p += 2;
ret = -EINVAL;
len = strlen(p);

View File

@ -812,7 +812,7 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
/* if we find something consistent, stay with that assumption
* at least M09 won't send 3 bytes here
*/
if (!(strnicmp(rdbuf + 1, "EP0", 3))) {
if (!(strncasecmp(rdbuf + 1, "EP0", 3))) {
tsdata->version = M06;
/* remove last '$' end marker */

View File

@ -188,6 +188,7 @@ static void r592_host_reset(struct r592_device *dev)
r592_set_mode(dev, dev->parallel_mode);
}
#ifdef CONFIG_PM_SLEEP
/* Disable all hardware interrupts */
static void r592_clear_interrupts(struct r592_device *dev)
{
@ -195,6 +196,7 @@ static void r592_clear_interrupts(struct r592_device *dev)
r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_ACK_MASK);
r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_EN_MASK);
}
#endif
/* Tests if there is an CRC error */
static int r592_test_io_error(struct r592_device *dev)

View File

@ -454,7 +454,7 @@ exit_done:
name = &p[str_table + name_id];
if (strnicmp(aconf->action, name, strlen(name)) == 0) {
if (strncasecmp(aconf->action, name, strlen(name)) == 0) {
action_found = 1;
current_proc =
get_unaligned_be32(&p[action_table +
@ -2176,7 +2176,7 @@ static int altera_get_note(u8 *p, s32 program_size,
key_ptr = &p[note_strings +
get_unaligned_be32(
&p[note_table + (8 * i)])];
if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) &&
if ((strncasecmp(key, key_ptr, strlen(key_ptr)) == 0) &&
(key != NULL)) {
status = 0;

View File

@ -168,7 +168,6 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v)
local_info_t *local = m->private;
struct list_head *ptr = v;
struct hostap_bss_info *bss;
int i;
if (ptr == &local->bss_list) {
seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t"
@ -181,9 +180,7 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v)
bss->bssid, bss->last_update,
bss->count, bss->capab_info);
for (i = 0; i < bss->ssid_len; i++)
seq_putc(m,bss->ssid[i] >= 32 && bss->ssid[i] < 127 ?
bss->ssid[i] : '_');
seq_printf(m, "%*pE", (int)bss->ssid_len, bss->ssid);
seq_putc(m, '\t');
seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid);

View File

@ -2005,7 +2005,6 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
u32 chan;
char *txratename;
u8 bssid[ETH_ALEN];
DECLARE_SSID_BUF(ssid);
/*
* TBD: BSSID is usually 00:00:00:00:00:00 here and not
@ -2067,8 +2066,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
break;
}
IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID=%pM)\n",
priv->net_dev->name, print_ssid(ssid, essid, essid_len),
IPW_DEBUG_INFO("%s: Associated with '%*pE' at %s, channel %d (BSSID=%pM)\n",
priv->net_dev->name, essid_len, essid,
txratename, chan, bssid);
/* now we copy read ssid into dev */
@ -2095,9 +2094,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
.host_command_length = ssid_len
};
int err;
DECLARE_SSID_BUF(ssid);
IPW_DEBUG_HC("SSID: '%s'\n", print_ssid(ssid, essid, ssid_len));
IPW_DEBUG_HC("SSID: '%*pE'\n", ssid_len, essid);
if (ssid_len)
memcpy(cmd.host_command_parameters, essid, ssid_len);
@ -2138,11 +2136,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
{
DECLARE_SSID_BUF(ssid);
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
"disassociated: '%s' %pM\n",
print_ssid(ssid, priv->essid, priv->essid_len),
"disassociated: '%*pE' %pM\n", priv->essid_len, priv->essid,
priv->bssid);
priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
@ -6975,7 +6970,6 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
char *essid = ""; /* ANY */
int length = 0;
int err = 0;
DECLARE_SSID_BUF(ssid);
mutex_lock(&priv->action_mutex);
if (!(priv->status & STATUS_INITIALIZED)) {
@ -7005,8 +6999,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
goto done;
}
IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n",
print_ssid(ssid, essid, length), length);
IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, essid, length);
priv->essid_len = length;
memcpy(priv->essid, essid, priv->essid_len);
@ -7027,13 +7020,12 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
*/
struct ipw2100_priv *priv = libipw_priv(dev);
DECLARE_SSID_BUF(ssid);
/* If we are associated, trying to associate, or have a statically
* configured ESSID then return that; otherwise return ANY */
if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) {
IPW_DEBUG_WX("Getting essid: '%s'\n",
print_ssid(ssid, priv->essid, priv->essid_len));
IPW_DEBUG_WX("Getting essid: '%*pE'\n",
priv->essid_len, priv->essid);
memcpy(extra, priv->essid, priv->essid_len);
wrqu->essid.length = priv->essid_len;
wrqu->essid.flags = 1; /* active */

View File

@ -4496,7 +4496,6 @@ static void handle_scan_event(struct ipw_priv *priv)
static void ipw_rx_notification(struct ipw_priv *priv,
struct ipw_rx_notification *notif)
{
DECLARE_SSID_BUF(ssid);
u16 size = le16_to_cpu(notif->size);
IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);
@ -4509,9 +4508,8 @@ static void ipw_rx_notification(struct ipw_priv *priv,
case CMAS_ASSOCIATED:{
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC,
"associated: '%s' %pM\n",
print_ssid(ssid, priv->essid,
priv->essid_len),
"associated: '%*pE' %pM\n",
priv->essid_len, priv->essid,
priv->bssid);
switch (priv->ieee->iw_mode) {
@ -4585,14 +4583,9 @@ static void ipw_rx_notification(struct ipw_priv *priv,
IPW_DEBUG(IPW_DL_NOTIF |
IPW_DL_STATE |
IPW_DL_ASSOC,
"deauthenticated: '%s' "
"%pM"
": (0x%04X) - %s\n",
print_ssid(ssid,
priv->
essid,
priv->
essid_len),
"deauthenticated: '%*pE' %pM: (0x%04X) - %s\n",
priv->essid_len,
priv->essid,
priv->bssid,
le16_to_cpu(auth->status),
ipw_get_status_code
@ -4610,9 +4603,8 @@ static void ipw_rx_notification(struct ipw_priv *priv,
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC,
"authenticated: '%s' %pM\n",
print_ssid(ssid, priv->essid,
priv->essid_len),
"authenticated: '%*pE' %pM\n",
priv->essid_len, priv->essid,
priv->bssid);
break;
}
@ -4638,9 +4630,8 @@ static void ipw_rx_notification(struct ipw_priv *priv,
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC,
"disassociated: '%s' %pM\n",
print_ssid(ssid, priv->essid,
priv->essid_len),
"disassociated: '%*pE' %pM\n",
priv->essid_len, priv->essid,
priv->bssid);
priv->status &=
@ -4676,9 +4667,8 @@ static void ipw_rx_notification(struct ipw_priv *priv,
switch (auth->state) {
case CMAS_AUTHENTICATED:
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
"authenticated: '%s' %pM\n",
print_ssid(ssid, priv->essid,
priv->essid_len),
"authenticated: '%*pE' %pM\n",
priv->essid_len, priv->essid,
priv->bssid);
priv->status |= STATUS_AUTH;
break;
@ -4695,9 +4685,8 @@ static void ipw_rx_notification(struct ipw_priv *priv,
}
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC,
"deauthenticated: '%s' %pM\n",
print_ssid(ssid, priv->essid,
priv->essid_len),
"deauthenticated: '%*pE' %pM\n",
priv->essid_len, priv->essid,
priv->bssid);
priv->status &= ~(STATUS_ASSOCIATING |
@ -5516,16 +5505,13 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
int roaming)
{
struct ipw_supported_rates rates;
DECLARE_SSID_BUF(ssid);
/* Verify that this network's capability is compatible with the
* current mode (AdHoc or Infrastructure) */
if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
!(network->capability & WLAN_CAPABILITY_IBSS))) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to "
"capability mismatch.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded due to capability mismatch.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
@ -5536,10 +5522,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
if ((network->ssid_len != match->network->ssid_len) ||
memcmp(network->ssid, match->network->ssid,
network->ssid_len)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of non-network ESSID.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of non-network ESSID.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
@ -5550,17 +5534,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
((network->ssid_len != priv->essid_len) ||
memcmp(network->ssid, priv->essid,
min(network->ssid_len, priv->essid_len)))) {
char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
strlcpy(escaped,
print_ssid(ssid, network->ssid,
network->ssid_len),
sizeof(escaped));
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of ESSID mismatch: '%s'.\n",
escaped, network->bssid,
print_ssid(ssid, priv->essid,
priv->essid_len));
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n",
network->ssid_len, network->ssid,
network->bssid, priv->essid_len,
priv->essid);
return 0;
}
}
@ -5569,26 +5546,20 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
* testing everything else. */
if (network->time_stamp[0] < match->network->time_stamp[0]) {
IPW_DEBUG_MERGE("Network '%s excluded because newer than "
"current network.\n",
print_ssid(ssid, match->network->ssid,
match->network->ssid_len));
IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n",
match->network->ssid_len, match->network->ssid);
return 0;
} else if (network->time_stamp[1] < match->network->time_stamp[1]) {
IPW_DEBUG_MERGE("Network '%s excluded because newer than "
"current network.\n",
print_ssid(ssid, match->network->ssid,
match->network->ssid_len));
IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n",
match->network->ssid_len, match->network->ssid);
return 0;
}
/* Now go through and see if the requested network is valid... */
if (priv->ieee->scan_age != 0 &&
time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of age: %ums.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of age: %ums.\n",
network->ssid_len, network->ssid,
network->bssid,
jiffies_to_msecs(jiffies -
network->last_scanned));
@ -5597,10 +5568,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
if ((priv->config & CFG_STATIC_CHANNEL) &&
(network->channel != priv->channel)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of channel mismatch: %d != %d.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n",
network->ssid_len, network->ssid,
network->bssid,
network->channel, priv->channel);
return 0;
@ -5609,10 +5578,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
/* Verify privacy compatibility */
if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of privacy mismatch: %s != %s.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n",
network->ssid_len, network->ssid,
network->bssid,
priv->
capability & CAP_PRIVACY_ON ? "on" : "off",
@ -5623,22 +5590,16 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
}
if (ether_addr_equal(network->bssid, priv->bssid)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of the same BSSID match: %pM"
".\n", print_ssid(ssid, network->ssid,
network->ssid_len),
network->bssid,
priv->bssid);
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of the same BSSID match: %pM.\n",
network->ssid_len, network->ssid,
network->bssid, priv->bssid);
return 0;
}
/* Filter out any incompatible freq / mode combinations */
if (!libipw_is_valid_mode(priv->ieee, network->mode)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of invalid frequency/mode "
"combination.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
@ -5646,20 +5607,15 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
/* Ensure that the rates supported by the driver are compatible with
* this AP, including verification of basic rates (mandatory) */
if (!ipw_compatible_rates(priv, network, &rates)) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because configured rate mask excludes "
"AP mandatory rate.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
if (rates.num_rates == 0) {
IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
"because of no compatible rates.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of no compatible rates.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
@ -5671,16 +5627,14 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
/* Set up 'new' AP to this network */
ipw_copy_rates(&match->rates, &rates);
match->network = network;
IPW_DEBUG_MERGE("Network '%s (%pM)' is a viable match.\n",
print_ssid(ssid, network->ssid, network->ssid_len),
network->bssid);
IPW_DEBUG_MERGE("Network '%*pE (%pM)' is a viable match.\n",
network->ssid_len, network->ssid, network->bssid);
return 1;
}
static void ipw_merge_adhoc_network(struct work_struct *work)
{
DECLARE_SSID_BUF(ssid);
struct ipw_priv *priv =
container_of(work, struct ipw_priv, merge_networks);
struct libipw_network *network = NULL;
@ -5710,9 +5664,8 @@ static void ipw_merge_adhoc_network(struct work_struct *work)
mutex_lock(&priv->mutex);
if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
IPW_DEBUG_MERGE("remove network %s\n",
print_ssid(ssid, priv->essid,
priv->essid_len));
IPW_DEBUG_MERGE("remove network %*pE\n",
priv->essid_len, priv->essid);
ipw_remove_current_network(priv);
}
@ -5728,7 +5681,6 @@ static int ipw_best_network(struct ipw_priv *priv,
struct libipw_network *network, int roaming)
{
struct ipw_supported_rates rates;
DECLARE_SSID_BUF(ssid);
/* Verify that this network's capability is compatible with the
* current mode (AdHoc or Infrastructure) */
@ -5736,10 +5688,8 @@ static int ipw_best_network(struct ipw_priv *priv,
!(network->capability & WLAN_CAPABILITY_ESS)) ||
(priv->ieee->iw_mode == IW_MODE_ADHOC &&
!(network->capability & WLAN_CAPABILITY_IBSS))) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to "
"capability mismatch.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded due to capability mismatch.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
@ -5750,10 +5700,8 @@ static int ipw_best_network(struct ipw_priv *priv,
if ((network->ssid_len != match->network->ssid_len) ||
memcmp(network->ssid, match->network->ssid,
network->ssid_len)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of non-network ESSID.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of non-network ESSID.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
@ -5764,16 +5712,10 @@ static int ipw_best_network(struct ipw_priv *priv,
((network->ssid_len != priv->essid_len) ||
memcmp(network->ssid, priv->essid,
min(network->ssid_len, priv->essid_len)))) {
char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
strlcpy(escaped,
print_ssid(ssid, network->ssid,
network->ssid_len),
sizeof(escaped));
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of ESSID mismatch: '%s'.\n",
escaped, network->bssid,
print_ssid(ssid, priv->essid,
priv->essid_len));
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n",
network->ssid_len, network->ssid,
network->bssid, priv->essid_len,
priv->essid);
return 0;
}
}
@ -5781,16 +5723,10 @@ static int ipw_best_network(struct ipw_priv *priv,
/* If the old network rate is better than this one, don't bother
* testing everything else. */
if (match->network && match->network->stats.rssi > network->stats.rssi) {
char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
strlcpy(escaped,
print_ssid(ssid, network->ssid, network->ssid_len),
sizeof(escaped));
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
"'%s (%pM)' has a stronger signal.\n",
escaped, network->bssid,
print_ssid(ssid, match->network->ssid,
match->network->ssid_len),
match->network->bssid);
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because '%*pE (%pM)' has a stronger signal.\n",
network->ssid_len, network->ssid,
network->bssid, match->network->ssid_len,
match->network->ssid, match->network->bssid);
return 0;
}
@ -5798,11 +5734,8 @@ static int ipw_best_network(struct ipw_priv *priv,
* last 3 seconds, do not try and associate again... */
if (network->last_associate &&
time_after(network->last_associate + (HZ * 3UL), jiffies)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of storming (%ums since last "
"assoc attempt).\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of storming (%ums since last assoc attempt).\n",
network->ssid_len, network->ssid,
network->bssid,
jiffies_to_msecs(jiffies -
network->last_associate));
@ -5812,10 +5745,8 @@ static int ipw_best_network(struct ipw_priv *priv,
/* Now go through and see if the requested network is valid... */
if (priv->ieee->scan_age != 0 &&
time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of age: %ums.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of age: %ums.\n",
network->ssid_len, network->ssid,
network->bssid,
jiffies_to_msecs(jiffies -
network->last_scanned));
@ -5824,10 +5755,8 @@ static int ipw_best_network(struct ipw_priv *priv,
if ((priv->config & CFG_STATIC_CHANNEL) &&
(network->channel != priv->channel)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of channel mismatch: %d != %d.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n",
network->ssid_len, network->ssid,
network->bssid,
network->channel, priv->channel);
return 0;
@ -5836,10 +5765,8 @@ static int ipw_best_network(struct ipw_priv *priv,
/* Verify privacy compatibility */
if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of privacy mismatch: %s != %s.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n",
network->ssid_len, network->ssid,
network->bssid,
priv->capability & CAP_PRIVACY_ON ? "on" :
"off",
@ -5850,31 +5777,24 @@ static int ipw_best_network(struct ipw_priv *priv,
if ((priv->config & CFG_STATIC_BSSID) &&
!ether_addr_equal(network->bssid, priv->bssid)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of BSSID mismatch: %pM.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of BSSID mismatch: %pM.\n",
network->ssid_len, network->ssid,
network->bssid, priv->bssid);
return 0;
}
/* Filter out any incompatible freq / mode combinations */
if (!libipw_is_valid_mode(priv->ieee, network->mode)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of invalid frequency/mode "
"combination.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
/* Filter out invalid channel in current GEO */
if (!libipw_is_valid_channel(priv->ieee, network->channel)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of invalid channel in current GEO\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid channel in current GEO\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
@ -5882,20 +5802,15 @@ static int ipw_best_network(struct ipw_priv *priv,
/* Ensure that the rates supported by the driver are compatible with
* this AP, including verification of basic rates (mandatory) */
if (!ipw_compatible_rates(priv, network, &rates)) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because configured rate mask excludes "
"AP mandatory rate.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
if (rates.num_rates == 0) {
IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
"because of no compatible rates.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of no compatible rates.\n",
network->ssid_len, network->ssid,
network->bssid);
return 0;
}
@ -5908,9 +5823,8 @@ static int ipw_best_network(struct ipw_priv *priv,
ipw_copy_rates(&match->rates, &rates);
match->network = network;
IPW_DEBUG_ASSOC("Network '%s (%pM)' is a viable match.\n",
print_ssid(ssid, network->ssid, network->ssid_len),
network->bssid);
IPW_DEBUG_ASSOC("Network '%*pE (%pM)' is a viable match.\n",
network->ssid_len, network->ssid, network->bssid);
return 1;
}
@ -6152,7 +6066,6 @@ static void ipw_bg_adhoc_check(struct work_struct *work)
static void ipw_debug_config(struct ipw_priv *priv)
{
DECLARE_SSID_BUF(ssid);
IPW_DEBUG_INFO("Scan completed, no valid APs matched "
"[CFG 0x%08X]\n", priv->config);
if (priv->config & CFG_STATIC_CHANNEL)
@ -6160,8 +6073,8 @@ static void ipw_debug_config(struct ipw_priv *priv)
else
IPW_DEBUG_INFO("Channel unlocked.\n");
if (priv->config & CFG_STATIC_ESSID)
IPW_DEBUG_INFO("ESSID locked to '%s'\n",
print_ssid(ssid, priv->essid, priv->essid_len));
IPW_DEBUG_INFO("ESSID locked to '%*pE'\n",
priv->essid_len, priv->essid);
else
IPW_DEBUG_INFO("ESSID unlocked.\n");
if (priv->config & CFG_STATIC_BSSID)
@ -7385,7 +7298,6 @@ static int ipw_associate_network(struct ipw_priv *priv,
struct ipw_supported_rates *rates, int roaming)
{
int err;
DECLARE_SSID_BUF(ssid);
if (priv->config & CFG_FIXED_RATE)
ipw_set_fixed_rate(priv, network->mode);
@ -7451,10 +7363,9 @@ static int ipw_associate_network(struct ipw_priv *priv,
priv->assoc_request.capability &=
~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
IPW_DEBUG_ASSOC("%ssociation attempt: '%s', channel %d, "
"802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
IPW_DEBUG_ASSOC("%ssociation attempt: '%*pE', channel %d, 802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
roaming ? "Rea" : "A",
print_ssid(ssid, priv->essid, priv->essid_len),
priv->essid_len, priv->essid,
network->channel,
ipw_modes[priv->assoc_request.ieee_mode],
rates->num_rates,
@ -7553,9 +7464,8 @@ static int ipw_associate_network(struct ipw_priv *priv,
return err;
}
IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM\n",
print_ssid(ssid, priv->essid, priv->essid_len),
priv->bssid);
IPW_DEBUG(IPW_DL_STATE, "associating: '%*pE' %pM\n",
priv->essid_len, priv->essid, priv->bssid);
return 0;
}
@ -7645,7 +7555,6 @@ static int ipw_associate(void *data)
struct ipw_supported_rates *rates;
struct list_head *element;
unsigned long flags;
DECLARE_SSID_BUF(ssid);
if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
@ -7704,10 +7613,8 @@ static int ipw_associate(void *data)
/* If there are no more slots, expire the oldest */
list_del(&oldest->list);
target = oldest;
IPW_DEBUG_ASSOC("Expired '%s' (%pM) from "
"network list.\n",
print_ssid(ssid, target->ssid,
target->ssid_len),
IPW_DEBUG_ASSOC("Expired '%*pE' (%pM) from network list.\n",
target->ssid_len, target->ssid,
target->bssid);
list_add_tail(&target->list,
&priv->ieee->network_free_list);
@ -9093,7 +9000,6 @@ static int ipw_wx_set_essid(struct net_device *dev,
{
struct ipw_priv *priv = libipw_priv(dev);
int length;
DECLARE_SSID_BUF(ssid);
mutex_lock(&priv->mutex);
@ -9118,8 +9024,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
return 0;
}
IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n",
print_ssid(ssid, extra, length), length);
IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, extra, length);
priv->essid_len = length;
memcpy(priv->essid, extra, priv->essid_len);
@ -9138,15 +9043,14 @@ static int ipw_wx_get_essid(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = libipw_priv(dev);
DECLARE_SSID_BUF(ssid);
/* If we are associated, trying to associate, or have a statically
* configured ESSID then return that; otherwise return ANY */
mutex_lock(&priv->mutex);
if (priv->config & CFG_STATIC_ESSID ||
priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
IPW_DEBUG_WX("Getting essid: '%s'\n",
print_ssid(ssid, priv->essid, priv->essid_len));
IPW_DEBUG_WX("Getting essid: '%*pE'\n",
priv->essid_len, priv->essid);
memcpy(extra, priv->essid, priv->essid_len);
wrqu->essid.length = priv->essid_len;
wrqu->essid.flags = 1; /* active */

View File

@ -1120,7 +1120,6 @@ static int libipw_parse_info_param(struct libipw_info_element
*info_element, u16 length,
struct libipw_network *network)
{
DECLARE_SSID_BUF(ssid);
u8 i;
#ifdef CONFIG_LIBIPW_DEBUG
char rates_str[64];
@ -1151,10 +1150,9 @@ static int libipw_parse_info_param(struct libipw_info_element
memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len);
LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
network->ssid_len);
LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%*pE' len=%d.\n",
network->ssid_len, network->ssid,
network->ssid_len);
break;
case WLAN_EID_SUPP_RATES:
@ -1399,8 +1397,6 @@ static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_r
struct libipw_network *network,
struct libipw_rx_stats *stats)
{
DECLARE_SSID_BUF(ssid);
network->qos_data.active = 0;
network->qos_data.supported = 0;
network->qos_data.param_count = 0;
@ -1447,11 +1443,9 @@ static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_r
}
if (network->mode == 0) {
LIBIPW_DEBUG_SCAN("Filtered out '%s (%pM)' "
"network.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
network->bssid);
LIBIPW_DEBUG_SCAN("Filtered out '%*pE (%pM)' network.\n",
network->ssid_len, network->ssid,
network->bssid);
return 1;
}
@ -1563,11 +1557,9 @@ static void libipw_process_probe_response(struct libipw_device
struct libipw_info_element *info_element = beacon->info_element;
#endif
unsigned long flags;
DECLARE_SSID_BUF(ssid);
LIBIPW_DEBUG_SCAN("'%s' (%pM"
"): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
print_ssid(ssid, info_element->data, info_element->len),
LIBIPW_DEBUG_SCAN("'%*pE' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
info_element->len, info_element->data,
beacon->header.addr3,
(beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0',
(beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0',
@ -1587,12 +1579,11 @@ static void libipw_process_probe_response(struct libipw_device
(beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
if (libipw_network_init(ieee, beacon, &network, stats)) {
LIBIPW_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
print_ssid(ssid, info_element->data,
info_element->len),
beacon->header.addr3,
is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
LIBIPW_DEBUG_SCAN("Dropped '%*pE' (%pM) via %s.\n",
info_element->len, info_element->data,
beacon->header.addr3,
is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
return;
}
@ -1624,11 +1615,9 @@ static void libipw_process_probe_response(struct libipw_device
/* If there are no more slots, expire the oldest */
list_del(&oldest->list);
target = oldest;
LIBIPW_DEBUG_SCAN("Expired '%s' (%pM) from "
"network list.\n",
print_ssid(ssid, target->ssid,
target->ssid_len),
target->bssid);
LIBIPW_DEBUG_SCAN("Expired '%*pE' (%pM) from network list.\n",
target->ssid_len, target->ssid,
target->bssid);
libipw_network_reset(target);
} else {
/* Otherwise just pull from the free list */
@ -1638,23 +1627,21 @@ static void libipw_process_probe_response(struct libipw_device
}
#ifdef CONFIG_LIBIPW_DEBUG
LIBIPW_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
print_ssid(ssid, network.ssid,
network.ssid_len),
network.bssid,
is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
LIBIPW_DEBUG_SCAN("Adding '%*pE' (%pM) via %s.\n",
network.ssid_len, network.ssid,
network.bssid,
is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
#endif
memcpy(target, &network, sizeof(*target));
network.ibss_dfs = NULL;
list_add_tail(&target->list, &ieee->network_list);
} else {
LIBIPW_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
print_ssid(ssid, target->ssid,
target->ssid_len),
target->bssid,
is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
LIBIPW_DEBUG_SCAN("Updating '%*pE' (%pM) via %s.\n",
target->ssid_len, target->ssid,
target->bssid,
is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
update_network(target, &network);
network.ibss_dfs = NULL;
}

View File

@ -272,7 +272,6 @@ int libipw_wx_get_scan(struct libipw_device *ieee,
char *ev = extra;
char *stop = ev + wrqu->data.length;
int i = 0;
DECLARE_SSID_BUF(ssid);
LIBIPW_DEBUG_WX("Getting scan\n");
@ -290,12 +289,10 @@ int libipw_wx_get_scan(struct libipw_device *ieee,
ev = libipw_translate_scan(ieee, ev, stop, network,
info);
else {
LIBIPW_DEBUG_SCAN("Not showing network '%s ("
"%pM)' due to age (%ums).\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
network->bssid,
elapsed_jiffies_msecs(
LIBIPW_DEBUG_SCAN("Not showing network '%*pE (%pM)' due to age (%ums).\n",
network->ssid_len, network->ssid,
network->bssid,
elapsed_jiffies_msecs(
network->last_scanned));
}
}
@ -322,7 +319,6 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
int i, key, key_provided, len;
struct lib80211_crypt_data **crypt;
int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
DECLARE_SSID_BUF(ssid);
LIBIPW_DEBUG_WX("SET_ENCODE\n");
@ -417,8 +413,8 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
if (len > erq->length)
memset(sec.keys[key] + erq->length, 0,
len - erq->length);
LIBIPW_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
key, print_ssid(ssid, sec.keys[key], len),
LIBIPW_DEBUG_WX("Setting key %d to '%*pE' (%d:%d bytes)\n",
key, len, sec.keys[key],
erq->length, len);
sec.key_sizes[key] = len;
if (*crypt)

View File

@ -590,7 +590,6 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
int chan_no = -1;
const u8 *ssid = NULL;
u8 ssid_len = 0;
DECLARE_SSID_BUF(ssid_buf);
int len = get_unaligned_le16(pos);
pos += 2;
@ -644,10 +643,8 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
struct ieee80211_channel *channel =
ieee80211_get_channel(wiphy, freq);
lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, "
"%d dBm\n",
bssid, capa, chan_no,
print_ssid(ssid_buf, ssid, ssid_len),
lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %*pE, %d dBm\n",
bssid, capa, chan_no, ssid_len, ssid,
LBS_SCAN_RSSI_TO_MBM(rssi)/100);
if (channel &&
@ -1984,7 +1981,6 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
struct lbs_private *priv = wiphy_priv(wiphy);
int ret = 0;
struct cfg80211_bss *bss;
DECLARE_SSID_BUF(ssid_buf);
if (dev == priv->mesh_dev)
return -EOPNOTSUPP;

View File

@ -93,7 +93,6 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
{
struct cmd_ds_mesh_config cmd;
struct mrvl_meshie *ie;
DECLARE_SSID_BUF(ssid);
memset(&cmd, 0, sizeof(cmd));
cmd.channel = cpu_to_le16(chan);
@ -122,9 +121,9 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
default:
return -1;
}
lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
action, priv->mesh_tlv, chan,
print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
lbs_deb_cmd("mesh config action %d type %x channel %d SSID %*pE\n",
action, priv->mesh_tlv, chan, priv->mesh_ssid_len,
priv->mesh_ssid);
return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
}

View File

@ -8878,13 +8878,13 @@ static int __must_check __init get_thinkpad_model_data(
}
s = dmi_get_system_info(DMI_PRODUCT_VERSION);
if (s && !(strnicmp(s, "ThinkPad", 8) && strnicmp(s, "Lenovo", 6))) {
if (s && !(strncasecmp(s, "ThinkPad", 8) && strncasecmp(s, "Lenovo", 6))) {
tp->model_str = kstrdup(s, GFP_KERNEL);
if (!tp->model_str)
return -ENOMEM;
} else {
s = dmi_get_system_info(DMI_BIOS_VENDOR);
if (s && !(strnicmp(s, "Lenovo", 6))) {
if (s && !(strncasecmp(s, "Lenovo", 6))) {
tp->model_str = kstrdup(s, GFP_KERNEL);
if (!tp->model_str)
return -ENOMEM;

View File

@ -346,41 +346,41 @@ static ssize_t resources_store(struct device *dmdev,
}
buf = skip_spaces(buf);
if (!strnicmp(buf, "disable", 7)) {
if (!strncasecmp(buf, "disable", 7)) {
retval = pnp_disable_dev(dev);
goto done;
}
if (!strnicmp(buf, "activate", 8)) {
if (!strncasecmp(buf, "activate", 8)) {
retval = pnp_activate_dev(dev);
goto done;
}
if (!strnicmp(buf, "fill", 4)) {
if (!strncasecmp(buf, "fill", 4)) {
if (dev->active)
goto done;
retval = pnp_auto_config_dev(dev);
goto done;
}
if (!strnicmp(buf, "auto", 4)) {
if (!strncasecmp(buf, "auto", 4)) {
if (dev->active)
goto done;
pnp_init_resources(dev);
retval = pnp_auto_config_dev(dev);
goto done;
}
if (!strnicmp(buf, "clear", 5)) {
if (!strncasecmp(buf, "clear", 5)) {
if (dev->active)
goto done;
pnp_init_resources(dev);
goto done;
}
if (!strnicmp(buf, "get", 3)) {
if (!strncasecmp(buf, "get", 3)) {
mutex_lock(&pnp_res_mutex);
if (pnp_can_read(dev))
dev->protocol->get(dev);
mutex_unlock(&pnp_res_mutex);
goto done;
}
if (!strnicmp(buf, "set", 3)) {
if (!strncasecmp(buf, "set", 3)) {
resource_size_t start;
resource_size_t end;
unsigned long flags;
@ -392,31 +392,31 @@ static ssize_t resources_store(struct device *dmdev,
mutex_lock(&pnp_res_mutex);
while (1) {
buf = skip_spaces(buf);
if (!strnicmp(buf, "io", 2)) {
if (!strncasecmp(buf, "io", 2)) {
buf = pnp_get_resource_value(buf + 2,
IORESOURCE_IO,
&start, &end,
&flags);
pnp_add_io_resource(dev, start, end, flags);
} else if (!strnicmp(buf, "mem", 3)) {
} else if (!strncasecmp(buf, "mem", 3)) {
buf = pnp_get_resource_value(buf + 3,
IORESOURCE_MEM,
&start, &end,
&flags);
pnp_add_mem_resource(dev, start, end, flags);
} else if (!strnicmp(buf, "irq", 3)) {
} else if (!strncasecmp(buf, "irq", 3)) {
buf = pnp_get_resource_value(buf + 3,
IORESOURCE_IRQ,
&start, NULL,
&flags);
pnp_add_irq_resource(dev, start, flags);
} else if (!strnicmp(buf, "dma", 3)) {
} else if (!strncasecmp(buf, "dma", 3)) {
buf = pnp_get_resource_value(buf + 3,
IORESOURCE_DMA,
&start, NULL,
&flags);
pnp_add_dma_resource(dev, start, flags);
} else if (!strnicmp(buf, "bus", 3)) {
} else if (!strncasecmp(buf, "bus", 3)) {
buf = pnp_get_resource_value(buf + 3,
IORESOURCE_BUS,
&start, &end,

View File

@ -288,6 +288,26 @@ config RTC_DRV_MAX77686
This driver can also be built as a module. If so, the module
will be called rtc-max77686.
config RTC_DRV_RK808
tristate "Rockchip RK808 RTC"
depends on MFD_RK808
help
If you say yes here you will get support for the
RTC of RK808 PMIC.
This driver can also be built as a module. If so, the module
will be called rk808-rtc.
config RTC_DRV_MAX77802
tristate "Maxim 77802 RTC"
depends on MFD_MAX77686
help
If you say yes here you will get support for the
RTC of Maxim MAX77802 PMIC.
This driver can also be built as a module. If so, the module
will be called rtc-max77802.
config RTC_DRV_RS5C372
tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A"
help
@ -732,6 +752,7 @@ config RTC_DRV_DS1216
config RTC_DRV_DS1286
tristate "Dallas DS1286"
depends on HAS_IOMEM
help
If you say yes here you get support for the Dallas DS1286 RTC chips.
@ -743,6 +764,7 @@ config RTC_DRV_DS1302
config RTC_DRV_DS1511
tristate "Dallas DS1511"
depends on HAS_IOMEM
help
If you say yes here you get support for the
Dallas DS1511 timekeeping/watchdog chip.
@ -752,6 +774,7 @@ config RTC_DRV_DS1511
config RTC_DRV_DS1553
tristate "Maxim/Dallas DS1553"
depends on HAS_IOMEM
help
If you say yes here you get support for the
Maxim/Dallas DS1553 timekeeping chip.
@ -761,6 +784,7 @@ config RTC_DRV_DS1553
config RTC_DRV_DS1742
tristate "Maxim/Dallas DS1742/1743"
depends on HAS_IOMEM
help
If you say yes here you get support for the
Maxim/Dallas DS1742/1743 timekeeping chip.
@ -816,6 +840,7 @@ config RTC_DRV_EFI
config RTC_DRV_STK17TA8
tristate "Simtek STK17TA8"
depends on HAS_IOMEM
help
If you say yes here you get support for the
Simtek STK17TA8 timekeeping chip.
@ -834,6 +859,7 @@ config RTC_DRV_M48T86
config RTC_DRV_M48T35
tristate "ST M48T35"
depends on HAS_IOMEM
help
If you say Y here you will get support for the
ST M48T35 RTC chip.
@ -843,6 +869,7 @@ config RTC_DRV_M48T35
config RTC_DRV_M48T59
tristate "ST M48T59/M48T08/M48T02"
depends on HAS_IOMEM
help
If you say Y here you will get support for the
ST M48T59 RTC chip and compatible ST M48T08 and M48T02.
@ -855,6 +882,7 @@ config RTC_DRV_M48T59
config RTC_DRV_MSM6242
tristate "Oki MSM6242"
depends on HAS_IOMEM
help
If you say yes here you get support for the Oki MSM6242
timekeeping chip. It is used in some Amiga models (e.g. A2000).
@ -864,6 +892,7 @@ config RTC_DRV_MSM6242
config RTC_DRV_BQ4802
tristate "TI BQ4802"
depends on HAS_IOMEM
help
If you say Y here you will get support for the TI
BQ4802 RTC chip.
@ -873,6 +902,7 @@ config RTC_DRV_BQ4802
config RTC_DRV_RP5C01
tristate "Ricoh RP5C01"
depends on HAS_IOMEM
help
If you say yes here you get support for the Ricoh RP5C01
timekeeping chip. It is used in some Amiga models (e.g. A3000
@ -1374,6 +1404,7 @@ config RTC_DRV_MOXART
config RTC_DRV_XGENE
tristate "APM X-Gene RTC"
depends on HAS_IOMEM
help
If you say yes here you get support for the APM X-Gene SoC real time
clock.

View File

@ -85,6 +85,7 @@ obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o
obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o
obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o
obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o
obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
@ -109,6 +110,7 @@ obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o
obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o
obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o
obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o

View File

@ -2,10 +2,14 @@
* Driver for TI BQ32000 RTC.
*
* Copyright (C) 2009 Semihalf.
* Copyright (C) 2014 Pavel Machek <pavel@denx.de>
*
* 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.
*
* You can get hardware description at
* http://www.ti.com/lit/ds/symlink/bq32000.pdf
*/
#include <linux/module.h>
@ -27,6 +31,10 @@
#define BQ32K_CENT 0x40 /* Century flag */
#define BQ32K_CENT_EN 0x80 /* Century flag enable bit */
#define BQ32K_CALIBRATION 0x07 /* CAL_CFG1, calibration and control */
#define BQ32K_TCH2 0x08 /* Trickle charge enable */
#define BQ32K_CFG2 0x09 /* Trickle charger control */
struct bq32k_regs {
uint8_t seconds;
uint8_t minutes;
@ -122,6 +130,57 @@ static const struct rtc_class_ops bq32k_rtc_ops = {
.set_time = bq32k_rtc_set_time,
};
static int trickle_charger_of_init(struct device *dev, struct device_node *node)
{
unsigned char reg;
int error;
u32 ohms = 0;
if (of_property_read_u32(node, "trickle-resistor-ohms" , &ohms))
return 0;
switch (ohms) {
case 180+940:
/*
* TCHE[3:0] == 0x05, TCH2 == 1, TCFE == 0 (charging
* over diode and 940ohm resistor)
*/
if (of_property_read_bool(node, "trickle-diode-disable")) {
dev_err(dev, "diode and resistor mismatch\n");
return -EINVAL;
}
reg = 0x05;
break;
case 180+20000:
/* diode disabled */
if (!of_property_read_bool(node, "trickle-diode-disable")) {
dev_err(dev, "bq32k: diode and resistor mismatch\n");
return -EINVAL;
}
reg = 0x25;
break;
default:
dev_err(dev, "invalid resistor value (%d)\n", ohms);
return -EINVAL;
}
error = bq32k_write(dev, &reg, BQ32K_CFG2, 1);
if (error)
return error;
reg = 0x20;
error = bq32k_write(dev, &reg, BQ32K_TCH2, 1);
if (error)
return error;
dev_info(dev, "Enabled trickle RTC battery charge.\n");
return 0;
}
static int bq32k_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@ -153,6 +212,9 @@ static int bq32k_probe(struct i2c_client *client,
if (error)
return error;
if (client && client->dev.of_node)
trickle_charger_of_init(dev, client->dev.of_node);
rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name,
&bq32k_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))

View File

@ -856,7 +856,7 @@ static void __exit cmos_do_remove(struct device *dev)
cmos->dev = NULL;
}
#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_PM
static int cmos_suspend(struct device *dev)
{
@ -907,6 +907,8 @@ static inline int cmos_poweroff(struct device *dev)
return cmos_suspend(dev);
}
#ifdef CONFIG_PM_SLEEP
static int cmos_resume(struct device *dev)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
@ -954,6 +956,7 @@ static int cmos_resume(struct device *dev)
return 0;
}
#endif
#else
static inline int cmos_poweroff(struct device *dev)

View File

@ -126,9 +126,14 @@ struct chip_desc {
u16 nvram_offset;
u16 nvram_size;
u16 trickle_charger_reg;
u8 trickle_charger_setup;
u8 (*do_trickle_setup)(struct i2c_client *, uint32_t, bool);
};
static const struct chip_desc chips[last_ds_type] = {
static u8 do_trickle_setup_ds1339(struct i2c_client *,
uint32_t ohms, bool diode);
static struct chip_desc chips[last_ds_type] = {
[ds_1307] = {
.nvram_offset = 8,
.nvram_size = 56,
@ -143,6 +148,7 @@ static const struct chip_desc chips[last_ds_type] = {
[ds_1339] = {
.alarm = 1,
.trickle_charger_reg = 0x10,
.do_trickle_setup = &do_trickle_setup_ds1339,
},
[ds_1340] = {
.trickle_charger_reg = 0x08,
@ -833,15 +839,58 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,
return count;
}
/*----------------------------------------------------------------------*/
static u8 do_trickle_setup_ds1339(struct i2c_client *client,
uint32_t ohms, bool diode)
{
u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE :
DS1307_TRICKLE_CHARGER_NO_DIODE;
switch (ohms) {
case 250:
setup |= DS1307_TRICKLE_CHARGER_250_OHM;
break;
case 2000:
setup |= DS1307_TRICKLE_CHARGER_2K_OHM;
break;
case 4000:
setup |= DS1307_TRICKLE_CHARGER_4K_OHM;
break;
default:
dev_warn(&client->dev,
"Unsupported ohm value %u in dt\n", ohms);
return 0;
}
return setup;
}
static void ds1307_trickle_of_init(struct i2c_client *client,
struct chip_desc *chip)
{
uint32_t ohms = 0;
bool diode = true;
if (!chip->do_trickle_setup)
goto out;
if (of_property_read_u32(client->dev.of_node, "trickle-resistor-ohms" , &ohms))
goto out;
if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable"))
diode = false;
chip->trickle_charger_setup = chip->do_trickle_setup(client,
ohms, diode);
out:
return;
}
static int ds1307_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ds1307 *ds1307;
int err = -ENODEV;
int tmp;
const struct chip_desc *chip = &chips[id->driver_data];
struct chip_desc *chip = &chips[id->driver_data];
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
bool want_irq = false;
unsigned char *buf;
@ -866,9 +915,19 @@ static int ds1307_probe(struct i2c_client *client,
ds1307->client = client;
ds1307->type = id->driver_data;
if (pdata && pdata->trickle_charger_setup && chip->trickle_charger_reg)
if (!pdata && client->dev.of_node)
ds1307_trickle_of_init(client, chip);
else if (pdata && pdata->trickle_charger_setup)
chip->trickle_charger_setup = pdata->trickle_charger_setup;
if (chip->trickle_charger_setup && chip->trickle_charger_reg) {
dev_dbg(&client->dev, "writing trickle charger info 0x%x to 0x%x\n",
DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup,
chip->trickle_charger_reg);
i2c_smbus_write_byte_data(client, chip->trickle_charger_reg,
DS13XX_TRICKLE_CHARGER_MAGIC | pdata->trickle_charger_setup);
DS13XX_TRICKLE_CHARGER_MAGIC |
chip->trickle_charger_setup);
}
buf = ds1307->regs;
if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {

View File

@ -274,7 +274,7 @@ static int isl12022_probe(struct i2c_client *client,
}
#ifdef CONFIG_OF
static struct of_device_id isl12022_dt_match[] = {
static const struct of_device_id isl12022_dt_match[] = {
{ .compatible = "isl,isl12022" },
{ },
};

View File

@ -32,15 +32,6 @@
#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT)
#define RTC_RBUDR_SHIFT 4
#define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT)
/* WTSR and SMPL Register */
#define WTSRT_SHIFT 0
#define SMPLT_SHIFT 2
#define WTSR_EN_SHIFT 6
#define SMPL_EN_SHIFT 7
#define WTSRT_MASK (3 << WTSRT_SHIFT)
#define SMPLT_MASK (3 << SMPLT_SHIFT)
#define WTSR_EN_MASK (1 << WTSR_EN_SHIFT)
#define SMPL_EN_MASK (1 << SMPL_EN_SHIFT)
/* RTC Hour register */
#define HOUR_PM_SHIFT 6
#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT)
@ -49,7 +40,6 @@
#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT)
#define MAX77686_RTC_UPDATE_DELAY 16
#undef MAX77686_RTC_WTSR_SMPL
enum {
RTC_SEC = 0,
@ -80,16 +70,6 @@ enum MAX77686_RTC_OP {
MAX77686_RTC_READ,
};
static inline int max77686_rtc_calculate_wday(u8 shifted)
{
int counter = -1;
while (shifted) {
shifted >>= 1;
counter++;
}
return counter;
}
static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm,
int rtc_24hr_mode)
{
@ -103,7 +83,8 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm,
tm->tm_hour += 12;
}
tm->tm_wday = max77686_rtc_calculate_wday(data[RTC_WEEKDAY] & 0x7f);
/* Only a single bit is set in data[], so fls() would be equivalent */
tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f) - 1;
tm->tm_mday = data[RTC_DATE] & 0x1f;
tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100;
@ -412,64 +393,6 @@ static const struct rtc_class_ops max77686_rtc_ops = {
.alarm_irq_enable = max77686_rtc_alarm_irq_enable,
};
#ifdef MAX77686_RTC_WTSR_SMPL
static void max77686_rtc_enable_wtsr(struct max77686_rtc_info *info, bool enable)
{
int ret;
unsigned int val, mask;
if (enable)
val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT);
else
val = 0;
mask = WTSR_EN_MASK | WTSRT_MASK;
dev_info(info->dev, "%s: %s WTSR\n", __func__,
enable ? "enable" : "disable");
ret = regmap_update_bits(info->max77686->rtc_regmap,
MAX77686_WTSR_SMPL_CNTL, mask, val);
if (ret < 0) {
dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n",
__func__, ret);
return;
}
max77686_rtc_update(info, MAX77686_RTC_WRITE);
}
static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable)
{
int ret;
unsigned int val, mask;
if (enable)
val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT);
else
val = 0;
mask = SMPL_EN_MASK | SMPLT_MASK;
dev_info(info->dev, "%s: %s SMPL\n", __func__,
enable ? "enable" : "disable");
ret = regmap_update_bits(info->max77686->rtc_regmap,
MAX77686_WTSR_SMPL_CNTL, mask, val);
if (ret < 0) {
dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n",
__func__, ret);
return;
}
max77686_rtc_update(info, MAX77686_RTC_WRITE);
val = 0;
regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val);
dev_info(info->dev, "%s: WTSR_SMPL(0x%02x)\n", __func__, val);
}
#endif /* MAX77686_RTC_WTSR_SMPL */
static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
{
u8 data[2];
@ -519,19 +442,12 @@ static int max77686_rtc_probe(struct platform_device *pdev)
goto err_rtc;
}
#ifdef MAX77686_RTC_WTSR_SMPL
max77686_rtc_enable_wtsr(info, true);
max77686_rtc_enable_smpl(info, true);
#endif
device_init_wakeup(&pdev->dev, 1);
info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc",
&max77686_rtc_ops, THIS_MODULE);
if (IS_ERR(info->rtc_dev)) {
dev_info(&pdev->dev, "%s: fail\n", __func__);
ret = PTR_ERR(info->rtc_dev);
dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
if (ret == 0)
@ -539,6 +455,12 @@ static int max77686_rtc_probe(struct platform_device *pdev)
goto err_rtc;
}
if (!max77686->rtc_irq_data) {
ret = -EINVAL;
dev_err(&pdev->dev, "%s: no RTC regmap IRQ chip\n", __func__);
goto err_rtc;
}
info->virq = regmap_irq_get_virq(max77686->rtc_irq_data,
MAX77686_RTCIRQ_RTCA1);
if (!info->virq) {
@ -556,33 +478,33 @@ err_rtc:
return ret;
}
static void max77686_rtc_shutdown(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int max77686_rtc_suspend(struct device *dev)
{
#ifdef MAX77686_RTC_WTSR_SMPL
struct max77686_rtc_info *info = platform_get_drvdata(pdev);
int i;
u8 val = 0;
if (device_may_wakeup(dev)) {
struct max77686_rtc_info *info = dev_get_drvdata(dev);
for (i = 0; i < 3; i++) {
max77686_rtc_enable_wtsr(info, false);
regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val);
dev_info(info->dev, "%s: WTSR_SMPL reg(0x%02x)\n", __func__,
val);
if (val & WTSR_EN_MASK) {
dev_emerg(info->dev, "%s: fail to disable WTSR\n",
__func__);
} else {
dev_info(info->dev, "%s: success to disable WTSR\n",
__func__);
break;
}
return enable_irq_wake(info->virq);
}
/* Disable SMPL when power off */
max77686_rtc_enable_smpl(info, false);
#endif /* MAX77686_RTC_WTSR_SMPL */
return 0;
}
static int max77686_rtc_resume(struct device *dev)
{
if (device_may_wakeup(dev)) {
struct max77686_rtc_info *info = dev_get_drvdata(dev);
return disable_irq_wake(info->virq);
}
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(max77686_rtc_pm_ops,
max77686_rtc_suspend, max77686_rtc_resume);
static const struct platform_device_id rtc_id[] = {
{ "max77686-rtc", 0 },
{},
@ -592,9 +514,9 @@ static struct platform_driver max77686_rtc_driver = {
.driver = {
.name = "max77686-rtc",
.owner = THIS_MODULE,
.pm = &max77686_rtc_pm_ops,
},
.probe = max77686_rtc_probe,
.shutdown = max77686_rtc_shutdown,
.id_table = rtc_id,
};

502
drivers/rtc/rtc-max77802.c Normal file
View File

@ -0,0 +1,502 @@
/*
* RTC driver for Maxim MAX77802
*
* Copyright (C) 2013 Google, Inc
*
* Copyright (C) 2012 Samsung Electronics Co.Ltd
*
* based on rtc-max8997.c
*
* 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.
*
*/
#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mfd/max77686-private.h>
#include <linux/irqdomain.h>
#include <linux/regmap.h>
/* RTC Control Register */
#define BCD_EN_SHIFT 0
#define BCD_EN_MASK (1 << BCD_EN_SHIFT)
#define MODEL24_SHIFT 1
#define MODEL24_MASK (1 << MODEL24_SHIFT)
/* RTC Update Register1 */
#define RTC_UDR_SHIFT 0
#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT)
#define RTC_RBUDR_SHIFT 4
#define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT)
/* RTC Hour register */
#define HOUR_PM_SHIFT 6
#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT)
/* RTC Alarm Enable */
#define ALARM_ENABLE_SHIFT 7
#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT)
/* For the RTCAE1 register, we write this value to enable the alarm */
#define ALARM_ENABLE_VALUE 0x77
#define MAX77802_RTC_UPDATE_DELAY_US 200
enum {
RTC_SEC = 0,
RTC_MIN,
RTC_HOUR,
RTC_WEEKDAY,
RTC_MONTH,
RTC_YEAR,
RTC_DATE,
RTC_NR_TIME
};
struct max77802_rtc_info {
struct device *dev;
struct max77686_dev *max77802;
struct i2c_client *rtc;
struct rtc_device *rtc_dev;
struct mutex lock;
struct regmap *regmap;
int virq;
int rtc_24hr_mode;
};
enum MAX77802_RTC_OP {
MAX77802_RTC_WRITE,
MAX77802_RTC_READ,
};
static void max77802_rtc_data_to_tm(u8 *data, struct rtc_time *tm,
int rtc_24hr_mode)
{
tm->tm_sec = data[RTC_SEC] & 0xff;
tm->tm_min = data[RTC_MIN] & 0xff;
if (rtc_24hr_mode)
tm->tm_hour = data[RTC_HOUR] & 0x1f;
else {
tm->tm_hour = data[RTC_HOUR] & 0x0f;
if (data[RTC_HOUR] & HOUR_PM_MASK)
tm->tm_hour += 12;
}
/* Only a single bit is set in data[], so fls() would be equivalent */
tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0xff) - 1;
tm->tm_mday = data[RTC_DATE] & 0x1f;
tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
tm->tm_year = data[RTC_YEAR] & 0xff;
tm->tm_yday = 0;
tm->tm_isdst = 0;
}
static int max77802_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
{
data[RTC_SEC] = tm->tm_sec;
data[RTC_MIN] = tm->tm_min;
data[RTC_HOUR] = tm->tm_hour;
data[RTC_WEEKDAY] = 1 << tm->tm_wday;
data[RTC_DATE] = tm->tm_mday;
data[RTC_MONTH] = tm->tm_mon + 1;
data[RTC_YEAR] = tm->tm_year;
return 0;
}
static int max77802_rtc_update(struct max77802_rtc_info *info,
enum MAX77802_RTC_OP op)
{
int ret;
unsigned int data;
if (op == MAX77802_RTC_WRITE)
data = 1 << RTC_UDR_SHIFT;
else
data = 1 << RTC_RBUDR_SHIFT;
ret = regmap_update_bits(info->max77802->regmap,
MAX77802_RTC_UPDATE0, data, data);
if (ret < 0)
dev_err(info->dev, "%s: fail to write update reg(ret=%d, data=0x%x)\n",
__func__, ret, data);
else {
/* Minimum delay required before RTC update. */
usleep_range(MAX77802_RTC_UPDATE_DELAY_US,
MAX77802_RTC_UPDATE_DELAY_US * 2);
}
return ret;
}
static int max77802_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct max77802_rtc_info *info = dev_get_drvdata(dev);
u8 data[RTC_NR_TIME];
int ret;
mutex_lock(&info->lock);
ret = max77802_rtc_update(info, MAX77802_RTC_READ);
if (ret < 0)
goto out;
ret = regmap_bulk_read(info->max77802->regmap,
MAX77802_RTC_SEC, data, RTC_NR_TIME);
if (ret < 0) {
dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__,
ret);
goto out;
}
max77802_rtc_data_to_tm(data, tm, info->rtc_24hr_mode);
ret = rtc_valid_tm(tm);
out:
mutex_unlock(&info->lock);
return ret;
}
static int max77802_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct max77802_rtc_info *info = dev_get_drvdata(dev);
u8 data[RTC_NR_TIME];
int ret;
ret = max77802_rtc_tm_to_data(tm, data);
if (ret < 0)
return ret;
mutex_lock(&info->lock);
ret = regmap_bulk_write(info->max77802->regmap,
MAX77802_RTC_SEC, data, RTC_NR_TIME);
if (ret < 0) {
dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__,
ret);
goto out;
}
ret = max77802_rtc_update(info, MAX77802_RTC_WRITE);
out:
mutex_unlock(&info->lock);
return ret;
}
static int max77802_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct max77802_rtc_info *info = dev_get_drvdata(dev);
u8 data[RTC_NR_TIME];
unsigned int val;
int ret;
mutex_lock(&info->lock);
ret = max77802_rtc_update(info, MAX77802_RTC_READ);
if (ret < 0)
goto out;
ret = regmap_bulk_read(info->max77802->regmap,
MAX77802_ALARM1_SEC, data, RTC_NR_TIME);
if (ret < 0) {
dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n",
__func__, __LINE__, ret);
goto out;
}
max77802_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
alrm->enabled = 0;
ret = regmap_read(info->max77802->regmap,
MAX77802_RTC_AE1, &val);
if (ret < 0) {
dev_err(info->dev, "%s:%d fail to read alarm enable(%d)\n",
__func__, __LINE__, ret);
goto out;
}
if (val)
alrm->enabled = 1;
alrm->pending = 0;
ret = regmap_read(info->max77802->regmap, MAX77802_REG_STATUS2, &val);
if (ret < 0) {
dev_err(info->dev, "%s:%d fail to read status2 reg(%d)\n",
__func__, __LINE__, ret);
goto out;
}
if (val & (1 << 2)) /* RTCA1 */
alrm->pending = 1;
out:
mutex_unlock(&info->lock);
return 0;
}
static int max77802_rtc_stop_alarm(struct max77802_rtc_info *info)
{
int ret;
if (!mutex_is_locked(&info->lock))
dev_warn(info->dev, "%s: should have mutex locked\n", __func__);
ret = max77802_rtc_update(info, MAX77802_RTC_READ);
if (ret < 0)
goto out;
ret = regmap_write(info->max77802->regmap,
MAX77802_RTC_AE1, 0);
if (ret < 0) {
dev_err(info->dev, "%s: fail to write alarm reg(%d)\n",
__func__, ret);
goto out;
}
ret = max77802_rtc_update(info, MAX77802_RTC_WRITE);
out:
return ret;
}
static int max77802_rtc_start_alarm(struct max77802_rtc_info *info)
{
int ret;
if (!mutex_is_locked(&info->lock))
dev_warn(info->dev, "%s: should have mutex locked\n",
__func__);
ret = max77802_rtc_update(info, MAX77802_RTC_READ);
if (ret < 0)
goto out;
ret = regmap_write(info->max77802->regmap,
MAX77802_RTC_AE1,
ALARM_ENABLE_VALUE);
if (ret < 0) {
dev_err(info->dev, "%s: fail to read alarm reg(%d)\n",
__func__, ret);
goto out;
}
ret = max77802_rtc_update(info, MAX77802_RTC_WRITE);
out:
return ret;
}
static int max77802_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct max77802_rtc_info *info = dev_get_drvdata(dev);
u8 data[RTC_NR_TIME];
int ret;
ret = max77802_rtc_tm_to_data(&alrm->time, data);
if (ret < 0)
return ret;
mutex_lock(&info->lock);
ret = max77802_rtc_stop_alarm(info);
if (ret < 0)
goto out;
ret = regmap_bulk_write(info->max77802->regmap,
MAX77802_ALARM1_SEC, data, RTC_NR_TIME);
if (ret < 0) {
dev_err(info->dev, "%s: fail to write alarm reg(%d)\n",
__func__, ret);
goto out;
}
ret = max77802_rtc_update(info, MAX77802_RTC_WRITE);
if (ret < 0)
goto out;
if (alrm->enabled)
ret = max77802_rtc_start_alarm(info);
out:
mutex_unlock(&info->lock);
return ret;
}
static int max77802_rtc_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
struct max77802_rtc_info *info = dev_get_drvdata(dev);
int ret;
mutex_lock(&info->lock);
if (enabled)
ret = max77802_rtc_start_alarm(info);
else
ret = max77802_rtc_stop_alarm(info);
mutex_unlock(&info->lock);
return ret;
}
static irqreturn_t max77802_rtc_alarm_irq(int irq, void *data)
{
struct max77802_rtc_info *info = data;
dev_dbg(info->dev, "%s:irq(%d)\n", __func__, irq);
rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
return IRQ_HANDLED;
}
static const struct rtc_class_ops max77802_rtc_ops = {
.read_time = max77802_rtc_read_time,
.set_time = max77802_rtc_set_time,
.read_alarm = max77802_rtc_read_alarm,
.set_alarm = max77802_rtc_set_alarm,
.alarm_irq_enable = max77802_rtc_alarm_irq_enable,
};
static int max77802_rtc_init_reg(struct max77802_rtc_info *info)
{
u8 data[2];
int ret;
max77802_rtc_update(info, MAX77802_RTC_READ);
/* Set RTC control register : Binary mode, 24hour mdoe */
data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
info->rtc_24hr_mode = 1;
ret = regmap_bulk_write(info->max77802->regmap,
MAX77802_RTC_CONTROLM, data, ARRAY_SIZE(data));
if (ret < 0) {
dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
__func__, ret);
return ret;
}
ret = max77802_rtc_update(info, MAX77802_RTC_WRITE);
return ret;
}
static int max77802_rtc_probe(struct platform_device *pdev)
{
struct max77686_dev *max77802 = dev_get_drvdata(pdev->dev.parent);
struct max77802_rtc_info *info;
int ret;
dev_dbg(&pdev->dev, "%s\n", __func__);
info = devm_kzalloc(&pdev->dev, sizeof(struct max77802_rtc_info),
GFP_KERNEL);
if (!info)
return -ENOMEM;
mutex_init(&info->lock);
info->dev = &pdev->dev;
info->max77802 = max77802;
info->rtc = max77802->i2c;
platform_set_drvdata(pdev, info);
ret = max77802_rtc_init_reg(info);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret);
return ret;
}
device_init_wakeup(&pdev->dev, 1);
info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77802-rtc",
&max77802_rtc_ops, THIS_MODULE);
if (IS_ERR(info->rtc_dev)) {
ret = PTR_ERR(info->rtc_dev);
dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
if (ret == 0)
ret = -EINVAL;
return ret;
}
if (!max77802->rtc_irq_data) {
dev_err(&pdev->dev, "No RTC regmap IRQ chip\n");
return -EINVAL;
}
info->virq = regmap_irq_get_virq(max77802->rtc_irq_data,
MAX77686_RTCIRQ_RTCA1);
if (info->virq <= 0) {
dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n",
MAX77686_RTCIRQ_RTCA1);
return -EINVAL;
}
ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL,
max77802_rtc_alarm_irq, 0, "rtc-alarm1",
info);
if (ret < 0)
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
info->virq, ret);
return ret;
}
#ifdef CONFIG_PM_SLEEP
static int max77802_rtc_suspend(struct device *dev)
{
if (device_may_wakeup(dev)) {
struct max77802_rtc_info *info = dev_get_drvdata(dev);
return enable_irq_wake(info->virq);
}
return 0;
}
static int max77802_rtc_resume(struct device *dev)
{
if (device_may_wakeup(dev)) {
struct max77802_rtc_info *info = dev_get_drvdata(dev);
return disable_irq_wake(info->virq);
}
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(max77802_rtc_pm_ops,
max77802_rtc_suspend, max77802_rtc_resume);
static const struct platform_device_id rtc_id[] = {
{ "max77802-rtc", 0 },
{},
};
static struct platform_driver max77802_rtc_driver = {
.driver = {
.name = "max77802-rtc",
.owner = THIS_MODULE,
.pm = &max77802_rtc_pm_ops,
},
.probe = max77802_rtc_probe,
.id_table = rtc_id,
};
module_platform_driver(max77802_rtc_driver);
MODULE_DESCRIPTION("Maxim MAX77802 RTC driver");
MODULE_AUTHOR("Simon Glass <sjg@chromium.org>");
MODULE_LICENSE("GPL");

View File

@ -401,7 +401,7 @@ static int mpc5121_rtc_remove(struct platform_device *op)
}
#ifdef CONFIG_OF
static struct of_device_id mpc5121_rtc_match[] = {
static const struct of_device_id mpc5121_rtc_match[] = {
{ .compatible = "fsl,mpc5121-rtc", },
{ .compatible = "fsl,mpc5200-rtc", },
{},

View File

@ -167,8 +167,8 @@ static irqreturn_t pcf8563_irq(int irq, void *dev_id)
char pending;
err = pcf8563_get_alarm_mode(pcf8563->client, NULL, &pending);
if (err < 0)
return err;
if (err)
return IRQ_NONE;
if (pending) {
rtc_update_irq(pcf8563->rtc, 1, RTC_IRQF | RTC_AF);

View File

@ -176,7 +176,11 @@ static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
unsigned char ctrl, year[2];
struct rtc_mem mem = { CMOS_YEAR, sizeof(year), year };
struct rtc_mem mem = {
.loc = CMOS_YEAR,
.nr = sizeof(year),
.data = year
};
int real_year, year_offset, err;
/*
@ -222,8 +226,16 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
unsigned char year[2], chk;
struct rtc_mem cmos_year = { CMOS_YEAR, sizeof(year), year };
struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk };
struct rtc_mem cmos_year = {
.loc = CMOS_YEAR,
.nr = sizeof(year),
.data = year
};
struct rtc_mem cmos_check = {
.loc = CMOS_CHECKSUM,
.nr = 1,
.data = &chk
};
unsigned int proper_year = tm->tm_year + 1900;
int ret;

414
drivers/rtc/rtc-rk808.c Normal file
View File

@ -0,0 +1,414 @@
/*
* RTC driver for Rockchip RK808
*
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
*
* Author: Chris Zhong <zyw@rock-chips.com>
* Author: Zhang Qing <zhangqing@rock-chips.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/mfd/rk808.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
/* RTC_CTRL_REG bitfields */
#define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0)
/* RK808 has a shadowed register for saving a "frozen" RTC time.
* When user setting "GET_TIME" to 1, the time will save in this shadowed
* register. If set "READSEL" to 1, user read rtc time register, actually
* get the time of that moment. If we need the real time, clr this bit.
*/
#define BIT_RTC_CTRL_REG_RTC_GET_TIME BIT(6)
#define BIT_RTC_CTRL_REG_RTC_READSEL_M BIT(7)
#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M BIT(3)
#define RTC_STATUS_MASK 0xFE
#define SECONDS_REG_MSK 0x7F
#define MINUTES_REG_MAK 0x7F
#define HOURS_REG_MSK 0x3F
#define DAYS_REG_MSK 0x3F
#define MONTHS_REG_MSK 0x1F
#define YEARS_REG_MSK 0xFF
#define WEEKS_REG_MSK 0x7
/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
#define NUM_TIME_REGS (RK808_WEEKS_REG - RK808_SECONDS_REG + 1)
#define NUM_ALARM_REGS (RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1)
struct rk808_rtc {
struct rk808 *rk808;
struct rtc_device *rtc;
int irq;
};
/* Read current time and date in RTC */
static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 rtc_data[NUM_TIME_REGS];
int ret;
/* Force an update of the shadowed registers right now */
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
0);
if (ret) {
dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
return ret;
}
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
BIT_RTC_CTRL_REG_RTC_GET_TIME);
if (ret) {
dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
return ret;
}
ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG,
rtc_data, NUM_TIME_REGS);
if (ret) {
dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
return ret;
}
tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK);
tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK);
tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK);
tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK);
tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1;
tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100;
tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec);
return ret;
}
/* Set current time and date in RTC */
static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 rtc_data[NUM_TIME_REGS];
int ret;
rtc_data[0] = bin2bcd(tm->tm_sec);
rtc_data[1] = bin2bcd(tm->tm_min);
rtc_data[2] = bin2bcd(tm->tm_hour);
rtc_data[3] = bin2bcd(tm->tm_mday);
rtc_data[4] = bin2bcd(tm->tm_mon + 1);
rtc_data[5] = bin2bcd(tm->tm_year - 100);
rtc_data[6] = bin2bcd(tm->tm_wday);
dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec);
/* Stop RTC while updating the RTC registers */
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
BIT_RTC_CTRL_REG_STOP_RTC_M,
BIT_RTC_CTRL_REG_STOP_RTC_M);
if (ret) {
dev_err(dev, "Failed to update RTC control: %d\n", ret);
return ret;
}
ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG,
rtc_data, NUM_TIME_REGS);
if (ret) {
dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
return ret;
}
/* Start RTC again */
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
if (ret) {
dev_err(dev, "Failed to update RTC control: %d\n", ret);
return ret;
}
return 0;
}
/* Read alarm time and date in RTC */
static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 alrm_data[NUM_ALARM_REGS];
uint32_t int_reg;
int ret;
ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG,
alrm_data, NUM_ALARM_REGS);
alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
alrm->time.tm_hour = bcd2bin(alrm_data[2] & HOURS_REG_MSK);
alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK);
alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1;
alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
if (ret) {
dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
return ret;
}
dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
alrm->time.tm_min, alrm->time.tm_sec);
alrm->enabled = (int_reg & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M) ? 1 : 0;
return 0;
}
static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
{
struct rk808 *rk808 = rk808_rtc->rk808;
int ret;
ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
return ret;
}
static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
{
struct rk808 *rk808 = rk808_rtc->rk808;
int ret;
ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
return ret;
}
static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 alrm_data[NUM_ALARM_REGS];
int ret;
ret = rk808_rtc_stop_alarm(rk808_rtc);
if (ret) {
dev_err(dev, "Failed to stop alarm: %d\n", ret);
return ret;
}
dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
alrm->time.tm_min, alrm->time.tm_sec);
alrm_data[0] = bin2bcd(alrm->time.tm_sec);
alrm_data[1] = bin2bcd(alrm->time.tm_min);
alrm_data[2] = bin2bcd(alrm->time.tm_hour);
alrm_data[3] = bin2bcd(alrm->time.tm_mday);
alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG,
alrm_data, NUM_ALARM_REGS);
if (ret) {
dev_err(dev, "Failed to bulk write: %d\n", ret);
return ret;
}
if (alrm->enabled) {
ret = rk808_rtc_start_alarm(rk808_rtc);
if (ret) {
dev_err(dev, "Failed to start alarm: %d\n", ret);
return ret;
}
}
return 0;
}
static int rk808_rtc_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
if (enabled)
return rk808_rtc_start_alarm(rk808_rtc);
return rk808_rtc_stop_alarm(rk808_rtc);
}
/*
* We will just handle setting the frequency and make use the framework for
* reading the periodic interupts.
*
* @freq: Current periodic IRQ freq:
* bit 0: every second
* bit 1: every minute
* bit 2: every hour
* bit 3: every day
*/
static irqreturn_t rk808_alarm_irq(int irq, void *data)
{
struct rk808_rtc *rk808_rtc = data;
struct rk808 *rk808 = rk808_rtc->rk808;
struct i2c_client *client = rk808->i2c;
int ret;
ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
RTC_STATUS_MASK);
if (ret) {
dev_err(&client->dev,
"%s:Failed to update RTC status: %d\n", __func__, ret);
return ret;
}
rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF);
dev_dbg(&client->dev,
"%s:irq=%d\n", __func__, irq);
return IRQ_HANDLED;
}
static const struct rtc_class_ops rk808_rtc_ops = {
.read_time = rk808_rtc_readtime,
.set_time = rk808_rtc_set_time,
.read_alarm = rk808_rtc_readalarm,
.set_alarm = rk808_rtc_setalarm,
.alarm_irq_enable = rk808_rtc_alarm_irq_enable,
};
#ifdef CONFIG_PM_SLEEP
/* Turn off the alarm if it should not be a wake source. */
static int rk808_rtc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev);
if (device_may_wakeup(dev))
enable_irq_wake(rk808_rtc->irq);
return 0;
}
/* Enable the alarm if it should be enabled (in case it was disabled to
* prevent use as a wake source).
*/
static int rk808_rtc_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev);
if (device_may_wakeup(dev))
disable_irq_wake(rk808_rtc->irq);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops,
rk808_rtc_suspend, rk808_rtc_resume);
static int rk808_rtc_probe(struct platform_device *pdev)
{
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
struct rk808_rtc *rk808_rtc;
struct rtc_time tm;
int ret;
rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL);
if (rk808_rtc == NULL)
return -ENOMEM;
platform_set_drvdata(pdev, rk808_rtc);
rk808_rtc->rk808 = rk808;
/* start rtc running by default, and use shadowed timer. */
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
BIT_RTC_CTRL_REG_STOP_RTC_M |
BIT_RTC_CTRL_REG_RTC_READSEL_M,
BIT_RTC_CTRL_REG_RTC_READSEL_M);
if (ret) {
dev_err(&pdev->dev,
"Failed to update RTC control: %d\n", ret);
return ret;
}
ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
RTC_STATUS_MASK);
if (ret) {
dev_err(&pdev->dev,
"Failed to write RTC status: %d\n", ret);
return ret;
}
/* set init time */
ret = rk808_rtc_readtime(&pdev->dev, &tm);
if (ret) {
dev_err(&pdev->dev, "Failed to read RTC time\n");
return ret;
}
ret = rtc_valid_tm(&tm);
if (ret)
dev_warn(&pdev->dev, "invalid date/time\n");
device_init_wakeup(&pdev->dev, 1);
rk808_rtc->rtc = devm_rtc_device_register(&pdev->dev, "rk808-rtc",
&rk808_rtc_ops, THIS_MODULE);
if (IS_ERR(rk808_rtc->rtc)) {
ret = PTR_ERR(rk808_rtc->rtc);
return ret;
}
rk808_rtc->irq = platform_get_irq(pdev, 0);
if (rk808_rtc->irq < 0) {
if (rk808_rtc->irq != -EPROBE_DEFER)
dev_err(&pdev->dev, "Wake up is not possible as irq = %d\n",
rk808_rtc->irq);
return rk808_rtc->irq;
}
/* request alarm irq of rk808 */
ret = devm_request_threaded_irq(&pdev->dev, rk808_rtc->irq, NULL,
rk808_alarm_irq, 0,
"RTC alarm", rk808_rtc);
if (ret) {
dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
rk808_rtc->irq, ret);
}
return ret;
}
static struct platform_driver rk808_rtc_driver = {
.probe = rk808_rtc_probe,
.driver = {
.name = "rk808-rtc",
.pm = &rk808_rtc_pm_ops,
},
};
module_platform_driver(rk808_rtc_driver);
MODULE_DESCRIPTION("RTC driver for the rk808 series PMICs");
MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:rk808-rtc");

View File

@ -142,12 +142,11 @@ static int rs5c_get_regs(struct rs5c372 *rs5c)
}
dev_dbg(&client->dev,
"%02x %02x %02x (%02x) %02x %02x %02x (%02x), "
"%02x %02x %02x, %02x %02x %02x; %02x %02x\n",
rs5c->regs[0], rs5c->regs[1], rs5c->regs[2], rs5c->regs[3],
rs5c->regs[4], rs5c->regs[5], rs5c->regs[6], rs5c->regs[7],
rs5c->regs[8], rs5c->regs[9], rs5c->regs[10], rs5c->regs[11],
rs5c->regs[12], rs5c->regs[13], rs5c->regs[14], rs5c->regs[15]);
"%3ph (%02x) %3ph (%02x), %3ph, %3ph; %02x %02x\n",
rs5c->regs + 0, rs5c->regs[3],
rs5c->regs + 4, rs5c->regs[7],
rs5c->regs + 8, rs5c->regs + 11,
rs5c->regs[14], rs5c->regs[15]);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -257,11 +257,11 @@ static ssize_t chp_status_write(struct device *dev,
if (!num_args)
return count;
if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) {
if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) {
mutex_lock(&cp->lock);
error = s390_vary_chpid(cp->chpid, 1);
mutex_unlock(&cp->lock);
} else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) {
} else if (!strncasecmp(cmd, "off", 3) || !strcmp(cmd, "0")) {
mutex_lock(&cp->lock);
error = s390_vary_chpid(cp->chpid, 0);
mutex_unlock(&cp->lock);

View File

@ -528,7 +528,7 @@ ips_setup(char *ips_str)
* Update the variables
*/
for (i = 0; i < ARRAY_SIZE(options); i++) {
if (strnicmp
if (strncasecmp
(key, options[i].option_name,
strlen(options[i].option_name)) == 0) {
if (value)

View File

@ -3371,7 +3371,7 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf,
char work[20];
if (1 == sscanf(buf, "%10s", work)) {
if (0 == strnicmp(work,"0x", 2)) {
if (0 == strncasecmp(work,"0x", 2)) {
if (1 == sscanf(&work[2], "%x", &opts))
goto opts_done;
} else {

View File

@ -79,7 +79,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr)
{
int cmd_num;
for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++)
if (0 == strnicmp(cmdstr , android_wifi_cmd_str[cmd_num],
if (0 == strncasecmp(cmdstr , android_wifi_cmd_str[cmd_num],
strlen(android_wifi_cmd_str[cmd_num])))
break;
return cmd_num;

View File

@ -2957,25 +2957,13 @@ extern inline int rtllib_get_scans(struct rtllib_device *ieee)
static inline const char *escape_essid(const char *essid, u8 essid_len)
{
static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
const char *s = essid;
char *d = escaped;
if (rtllib_is_empty_essid(essid, essid_len)) {
memcpy(escaped, "<hidden>", sizeof("<hidden>"));
return escaped;
}
essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
while (essid_len--) {
if (*s == '\0') {
*d++ = '\\';
*d++ = '0';
s++;
} else {
*d++ = *s++;
}
}
*d = '\0';
snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid);
return escaped;
}

View File

@ -2593,25 +2593,13 @@ static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
static inline const char *escape_essid(const char *essid, u8 essid_len) {
static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
const char *s = essid;
char *d = escaped;
if (ieee80211_is_empty_essid(essid, essid_len)) {
memcpy(escaped, "<hidden>", sizeof("<hidden>"));
return escaped;
}
essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
while (essid_len--) {
if (*s == '\0') {
*d++ = '\\';
*d++ = '0';
s++;
} else {
*d++ = *s++;
}
}
*d = '\0';
snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid);
return escaped;
}

View File

@ -60,7 +60,6 @@
#include <linux/netdevice.h>
#include <linux/workqueue.h>
#include <linux/byteorder/generic.h>
#include <linux/ctype.h>
#include <linux/io.h>
#include <linux/delay.h>
@ -81,27 +80,6 @@
#include "hfa384x.h"
#include "prism2mgmt.h"
/* Create a string of printable chars from something that might not be */
/* It's recommended that the str be 4*len + 1 bytes long */
#define wlan_mkprintstr(buf, buflen, str, strlen) \
{ \
int i = 0; \
int j = 0; \
memset(str, 0, (strlen)); \
for (i = 0; i < (buflen); i++) { \
if (isprint((buf)[i])) { \
(str)[j] = (buf)[i]; \
j++; \
} else { \
(str)[j] = '\\'; \
(str)[j+1] = 'x'; \
(str)[j+2] = hex_asc_hi((buf)[i]); \
(str)[j+3] = hex_asc_lo((buf)[i]); \
j += 4; \
} \
} \
}
static char *dev_info = "prism2_usb";
static wlandevice_t *create_wlan(void);
@ -607,7 +585,6 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
u16 temp;
u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
/* Collect version and compatibility info */
/* Some are critical, some are not */
@ -862,9 +839,8 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER,
snum, HFA384x_RID_NICSERIALNUMBER_LEN);
if (!result) {
wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN,
pstr, sizeof(pstr));
netdev_info(wlandev->netdev, "Prism2 card SN: %s\n", pstr);
netdev_info(wlandev->netdev, "Prism2 card SN: %*pEhp\n",
HFA384x_RID_NICSERIALNUMBER_LEN, snum);
} else {
netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n");
goto failed;

View File

@ -66,7 +66,7 @@ static struct thermal_governor *__find_governor(const char *name)
return def_governor;
list_for_each_entry(pos, &thermal_governor_list, governor_list)
if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH))
if (!strncasecmp(name, pos->name, THERMAL_NAME_LENGTH))
return pos;
return NULL;
@ -104,7 +104,7 @@ int thermal_register_governor(struct thermal_governor *governor)
name = pos->tzp->governor_name;
if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH))
if (!strncasecmp(name, governor->name, THERMAL_NAME_LENGTH))
pos->governor = governor;
}
@ -129,7 +129,7 @@ void thermal_unregister_governor(struct thermal_governor *governor)
mutex_lock(&thermal_list_lock);
list_for_each_entry(pos, &thermal_tz_list, node) {
if (!strnicmp(pos->governor->name, governor->name,
if (!strncasecmp(pos->governor->name, governor->name,
THERMAL_NAME_LENGTH))
pos->governor = NULL;
}
@ -1665,7 +1665,7 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name)
mutex_lock(&thermal_list_lock);
list_for_each_entry(pos, &thermal_tz_list, node)
if (!strnicmp(name, pos->type, THERMAL_NAME_LENGTH)) {
if (!strncasecmp(name, pos->type, THERMAL_NAME_LENGTH)) {
found++;
ref = pos;
}

View File

@ -1001,7 +1001,7 @@ static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val,
for (i = 0 ; i < size ; i++ ) {
if (s != NULL) {
if (!strnicmp(p[i].name, s, strlen(s)))
if (!strncasecmp(p[i].name, s, strlen(s)))
return p[i].val;
} else {
if (p[i].val == val)

View File

@ -601,12 +601,12 @@ static int s3c2410fb_debug_store(struct device *dev,
if (len < 1)
return -EINVAL;
if (strnicmp(buf, "on", 2) == 0 ||
strnicmp(buf, "1", 1) == 0) {
if (strncasecmp(buf, "on", 2) == 0 ||
strncasecmp(buf, "1", 1) == 0) {
debug = 1;
dev_dbg(dev, "s3c2410fb: Debug On");
} else if (strnicmp(buf, "off", 3) == 0 ||
strnicmp(buf, "0", 1) == 0) {
} else if (strncasecmp(buf, "off", 3) == 0 ||
strncasecmp(buf, "0", 1) == 0) {
debug = 0;
dev_dbg(dev, "s3c2410fb: Debug Off");
} else {

View File

@ -162,7 +162,7 @@ static void sisfb_search_mode(char *name, bool quiet)
return;
}
if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
if(!strncasecmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
if(!quiet)
printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
@ -201,7 +201,7 @@ static void sisfb_search_mode(char *name, bool quiet)
i = 0; j = 0;
while(sisbios_mode[i].mode_no[0] != 0) {
if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
if(!strncasecmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
if(sisfb_fstn) {
if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
sisbios_mode[i-1].mode_no[1] == 0x56 ||
@ -262,7 +262,7 @@ sisfb_search_crt2type(const char *name)
if(name == NULL) return;
while(sis_crt2type[i].type_no != -1) {
if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
if(!strncasecmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
sisfb_crt2type = sis_crt2type[i].type_no;
sisfb_tvplug = sis_crt2type[i].tvplug_no;
sisfb_crt2flags = sis_crt2type[i].flags;
@ -289,7 +289,7 @@ sisfb_search_tvstd(const char *name)
return;
while(sis_tvtype[i].type_no != -1) {
if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
if(!strncasecmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
sisfb_tvstd = sis_tvtype[i].type_no;
break;
}
@ -308,12 +308,12 @@ sisfb_search_specialtiming(const char *name)
if(name == NULL)
return;
if(!strnicmp(name, "none", 4)) {
if(!strncasecmp(name, "none", 4)) {
sisfb_specialtiming = CUT_FORCENONE;
printk(KERN_DEBUG "sisfb: Special timing disabled\n");
} else {
while(mycustomttable[i].chipID != 0) {
if(!strnicmp(name,mycustomttable[i].optionName,
if(!strncasecmp(name,mycustomttable[i].optionName,
strlen(mycustomttable[i].optionName))) {
sisfb_specialtiming = mycustomttable[i].SpecialID;
found = true;
@ -3952,68 +3952,68 @@ static int __init sisfb_setup(char *options)
if(!(*this_opt)) continue;
if(!strnicmp(this_opt, "off", 3)) {
if(!strncasecmp(this_opt, "off", 3)) {
sisfb_off = 1;
} else if(!strnicmp(this_opt, "forcecrt2type:", 14)) {
} else if(!strncasecmp(this_opt, "forcecrt2type:", 14)) {
/* Need to check crt2 type first for fstn/dstn */
sisfb_search_crt2type(this_opt + 14);
} else if(!strnicmp(this_opt, "tvmode:",7)) {
} else if(!strncasecmp(this_opt, "tvmode:",7)) {
sisfb_search_tvstd(this_opt + 7);
} else if(!strnicmp(this_opt, "tvstandard:",11)) {
} else if(!strncasecmp(this_opt, "tvstandard:",11)) {
sisfb_search_tvstd(this_opt + 11);
} else if(!strnicmp(this_opt, "mode:", 5)) {
} else if(!strncasecmp(this_opt, "mode:", 5)) {
sisfb_search_mode(this_opt + 5, false);
} else if(!strnicmp(this_opt, "vesa:", 5)) {
} else if(!strncasecmp(this_opt, "vesa:", 5)) {
sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false);
} else if(!strnicmp(this_opt, "rate:", 5)) {
} else if(!strncasecmp(this_opt, "rate:", 5)) {
sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
} else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
} else if(!strncasecmp(this_opt, "forcecrt1:", 10)) {
sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
} else if(!strnicmp(this_opt, "mem:",4)) {
} else if(!strncasecmp(this_opt, "mem:",4)) {
sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
} else if(!strnicmp(this_opt, "pdc:", 4)) {
} else if(!strncasecmp(this_opt, "pdc:", 4)) {
sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
} else if(!strnicmp(this_opt, "pdc1:", 5)) {
} else if(!strncasecmp(this_opt, "pdc1:", 5)) {
sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
} else if(!strnicmp(this_opt, "noaccel", 7)) {
} else if(!strncasecmp(this_opt, "noaccel", 7)) {
sisfb_accel = 0;
} else if(!strnicmp(this_opt, "accel", 5)) {
} else if(!strncasecmp(this_opt, "accel", 5)) {
sisfb_accel = -1;
} else if(!strnicmp(this_opt, "noypan", 6)) {
} else if(!strncasecmp(this_opt, "noypan", 6)) {
sisfb_ypan = 0;
} else if(!strnicmp(this_opt, "ypan", 4)) {
} else if(!strncasecmp(this_opt, "ypan", 4)) {
sisfb_ypan = -1;
} else if(!strnicmp(this_opt, "nomax", 5)) {
} else if(!strncasecmp(this_opt, "nomax", 5)) {
sisfb_max = 0;
} else if(!strnicmp(this_opt, "max", 3)) {
} else if(!strncasecmp(this_opt, "max", 3)) {
sisfb_max = -1;
} else if(!strnicmp(this_opt, "userom:", 7)) {
} else if(!strncasecmp(this_opt, "userom:", 7)) {
sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
} else if(!strnicmp(this_opt, "useoem:", 7)) {
} else if(!strncasecmp(this_opt, "useoem:", 7)) {
sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
} else if(!strnicmp(this_opt, "nocrt2rate", 10)) {
} else if(!strncasecmp(this_opt, "nocrt2rate", 10)) {
sisfb_nocrt2rate = 1;
} else if(!strnicmp(this_opt, "scalelcd:", 9)) {
} else if(!strncasecmp(this_opt, "scalelcd:", 9)) {
unsigned long temp = 2;
temp = simple_strtoul(this_opt + 9, NULL, 0);
if((temp == 0) || (temp == 1)) {
sisfb_scalelcd = temp ^ 1;
}
} else if(!strnicmp(this_opt, "tvxposoffset:", 13)) {
} else if(!strncasecmp(this_opt, "tvxposoffset:", 13)) {
int temp = 0;
temp = (int)simple_strtol(this_opt + 13, NULL, 0);
if((temp >= -32) && (temp <= 32)) {
sisfb_tvxposoffset = temp;
}
} else if(!strnicmp(this_opt, "tvyposoffset:", 13)) {
} else if(!strncasecmp(this_opt, "tvyposoffset:", 13)) {
int temp = 0;
temp = (int)simple_strtol(this_opt + 13, NULL, 0);
if((temp >= -32) && (temp <= 32)) {
sisfb_tvyposoffset = temp;
}
} else if(!strnicmp(this_opt, "specialtiming:", 14)) {
} else if(!strncasecmp(this_opt, "specialtiming:", 14)) {
sisfb_search_specialtiming(this_opt + 14);
} else if(!strnicmp(this_opt, "lvdshl:", 7)) {
} else if(!strncasecmp(this_opt, "lvdshl:", 7)) {
int temp = 4;
temp = simple_strtoul(this_opt + 7, NULL, 0);
if((temp >= 0) && (temp <= 3)) {
@ -4022,9 +4022,9 @@ static int __init sisfb_setup(char *options)
} else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
sisfb_search_mode(this_opt, true);
#if !defined(__i386__) && !defined(__x86_64__)
} else if(!strnicmp(this_opt, "resetcard", 9)) {
} else if(!strncasecmp(this_opt, "resetcard", 9)) {
sisfb_resetcard = 1;
} else if(!strnicmp(this_opt, "videoram:", 9)) {
} else if(!strncasecmp(this_opt, "videoram:", 9)) {
sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
#endif
} else {

View File

@ -1187,9 +1187,9 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
if (len < 1)
return -EINVAL;
if (strnicmp(buf, "crt", 3) == 0)
if (strncasecmp(buf, "crt", 3) == 0)
head = HEAD_CRT;
else if (strnicmp(buf, "panel", 5) == 0)
else if (strncasecmp(buf, "panel", 5) == 0)
head = HEAD_PANEL;
else
return -EINVAL;

View File

@ -10,8 +10,6 @@
#include "affs.h"
extern struct timezone sys_tz;
static char ErrorBuffer[256];
/*

View File

@ -584,11 +584,14 @@ affs_extent_file_ofs(struct inode *inode, u32 newsize)
bh->b_state &= ~(1UL << BH_New);
mark_buffer_dirty_inode(bh, inode);
if (prev_bh) {
u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
if (tmp)
affs_warning(sb, "extent_file_ofs", "next block already set for %d (%d)", bidx, tmp);
u32 tmp_next = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
if (tmp_next)
affs_warning(sb, "extent_file_ofs",
"next block already set for %d (%d)",
bidx, tmp_next);
AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next);
mark_buffer_dirty_inode(prev_bh, inode);
affs_brelse(prev_bh);
}
@ -727,11 +730,14 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
AFFS_DATA_HEAD(bh)->next = 0;
bh->b_state &= ~(1UL << BH_New);
if (prev_bh) {
u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
if (tmp)
affs_warning(sb, "commit_write_ofs", "next block already set for %d (%d)", bidx, tmp);
u32 tmp_next = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
if (tmp_next)
affs_warning(sb, "commit_write_ofs",
"next block already set for %d (%d)",
bidx, tmp_next);
AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next);
mark_buffer_dirty_inode(prev_bh, inode);
}
}
@ -758,11 +764,14 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
AFFS_DATA_HEAD(bh)->next = 0;
bh->b_state &= ~(1UL << BH_New);
if (prev_bh) {
u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
if (tmp)
affs_warning(sb, "commit_write_ofs", "next block already set for %d (%d)", bidx, tmp);
u32 tmp_next = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
if (tmp_next)
affs_warning(sb, "commit_write_ofs",
"next block already set for %d (%d)",
bidx, tmp_next);
AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp);
affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next);
mark_buffer_dirty_inode(prev_bh, inode);
}
} else if (be32_to_cpu(AFFS_DATA_HEAD(bh)->size) < tmp)
@ -842,12 +851,12 @@ affs_truncate(struct inode *inode)
struct address_space *mapping = inode->i_mapping;
struct page *page;
void *fsdata;
loff_t size = inode->i_size;
loff_t isize = inode->i_size;
int res;
res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
res = mapping->a_ops->write_begin(NULL, mapping, isize, 0, 0, &page, &fsdata);
if (!res)
res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
res = mapping->a_ops->write_end(NULL, mapping, isize, 0, 0, page, fsdata);
else
inode->i_size = AFFS_I(inode)->mmu_private;
mark_inode_dirty(inode);

View File

@ -14,13 +14,11 @@
#include "affs.h"
extern const struct inode_operations affs_symlink_inode_operations;
extern struct timezone sys_tz;
struct inode *affs_iget(struct super_block *sb, unsigned long ino)
{
struct affs_sb_info *sbi = AFFS_SB(sb);
struct buffer_head *bh;
struct affs_head *head;
struct affs_tail *tail;
struct inode *inode;
u32 block;
@ -49,7 +47,6 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
goto bad_inode;
}
head = AFFS_HEAD(bh);
tail = AFFS_TAIL(sb, bh);
prot = be32_to_cpu(tail->protect);

View File

@ -20,8 +20,6 @@
#include <linux/writeback.h>
#include "affs.h"
extern struct timezone sys_tz;
static int affs_statfs(struct dentry *dentry, struct kstatfs *buf);
static int affs_remount (struct super_block *sb, int *flags, char *data);
@ -308,7 +306,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
u32 chksum;
int num_bm;
int i, j;
s32 key;
kuid_t uid;
kgid_t gid;
int reserved;
@ -367,7 +364,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
i = j = blocksize;
size = size / (blocksize / 512);
}
for (blocksize = i, key = 0; blocksize <= j; blocksize <<= 1, size >>= 1) {
for (blocksize = i; blocksize <= j; blocksize <<= 1, size >>= 1) {
sbi->s_root_block = root_block;
if (root_block < 0)
sbi->s_root_block = (reserved + size - 1) / 2;
@ -399,7 +396,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
be32_to_cpu(AFFS_ROOT_TAIL(sb, root_bh)->stype) == ST_ROOT) {
sbi->s_hashsize = blocksize / 4 - 56;
sbi->s_root_block += num_bm;
key = 1;
goto got_root;
}
affs_brelse(root_bh);

View File

@ -79,6 +79,10 @@ struct autofs_info {
};
#define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */
#define AUTOFS_INF_NO_RCU (1<<1) /* the dentry is being considered
* for expiry, so RCU_walk is
* not permitted
*/
#define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */
struct autofs_wait_queue {
@ -148,7 +152,7 @@ void autofs4_free_ino(struct autofs_info *);
/* Expiration */
int is_autofs4_dentry(struct dentry *);
int autofs4_expire_wait(struct dentry *dentry);
int autofs4_expire_wait(struct dentry *dentry, int rcu_walk);
int autofs4_expire_run(struct super_block *, struct vfsmount *,
struct autofs_sb_info *,
struct autofs_packet_expire __user *);

View File

@ -450,7 +450,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
ino = autofs4_dentry_ino(path.dentry);
if (ino) {
err = 0;
autofs4_expire_wait(path.dentry);
autofs4_expire_wait(path.dentry, 0);
spin_lock(&sbi->fs_lock);
param->requester.uid = from_kuid_munged(current_user_ns(), ino->uid);
param->requester.gid = from_kgid_munged(current_user_ns(), ino->gid);

View File

@ -30,12 +30,6 @@ static inline int autofs4_can_expire(struct dentry *dentry,
/* Too young to die */
if (!timeout || time_after(ino->last_used + timeout, now))
return 0;
/* update last_used here :-
- obviously makes sense if it is in use now
- less obviously, prevents rapid-fire expire
attempts if expire fails the first time */
ino->last_used = now;
}
return 1;
}
@ -327,10 +321,19 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
if (ino->flags & AUTOFS_INF_PENDING)
goto out;
if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
ino->flags |= AUTOFS_INF_EXPIRING;
init_completion(&ino->expire_complete);
ino->flags |= AUTOFS_INF_NO_RCU;
spin_unlock(&sbi->fs_lock);
return root;
synchronize_rcu();
spin_lock(&sbi->fs_lock);
if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
ino->flags |= AUTOFS_INF_EXPIRING;
smp_mb();
ino->flags &= ~AUTOFS_INF_NO_RCU;
init_completion(&ino->expire_complete);
spin_unlock(&sbi->fs_lock);
return root;
}
ino->flags &= ~AUTOFS_INF_NO_RCU;
}
out:
spin_unlock(&sbi->fs_lock);
@ -339,6 +342,89 @@ out:
return NULL;
}
/* Check if 'dentry' should expire, or return a nearby
* dentry that is suitable.
* If returned dentry is different from arg dentry,
* then a dget() reference was taken, else not.
*/
static struct dentry *should_expire(struct dentry *dentry,
struct vfsmount *mnt,
unsigned long timeout,
int how)
{
int do_now = how & AUTOFS_EXP_IMMEDIATE;
int exp_leaves = how & AUTOFS_EXP_LEAVES;
struct autofs_info *ino = autofs4_dentry_ino(dentry);
unsigned int ino_count;
/* No point expiring a pending mount */
if (ino->flags & AUTOFS_INF_PENDING)
return NULL;
/*
* Case 1: (i) indirect mount or top level pseudo direct mount
* (autofs-4.1).
* (ii) indirect mount with offset mount, check the "/"
* offset (autofs-5.0+).
*/
if (d_mountpoint(dentry)) {
DPRINTK("checking mountpoint %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/* Can we umount this guy */
if (autofs4_mount_busy(mnt, dentry))
return NULL;
/* Can we expire this guy */
if (autofs4_can_expire(dentry, timeout, do_now))
return dentry;
return NULL;
}
if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
DPRINTK("checking symlink %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/*
* A symlink can't be "busy" in the usual sense so
* just check last used for expire timeout.
*/
if (autofs4_can_expire(dentry, timeout, do_now))
return dentry;
return NULL;
}
if (simple_empty(dentry))
return NULL;
/* Case 2: tree mount, expire iff entire tree is not busy */
if (!exp_leaves) {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
if (d_count(dentry) > ino_count)
return NULL;
if (!autofs4_tree_busy(mnt, dentry, timeout, do_now))
return dentry;
/*
* Case 3: pseudo direct mount, expire individual leaves
* (autofs-4.1).
*/
} else {
/* Path walk currently on this dentry? */
struct dentry *expired;
ino_count = atomic_read(&ino->count) + 1;
if (d_count(dentry) > ino_count)
return NULL;
expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
if (expired) {
if (expired == dentry)
dput(dentry);
return expired;
}
}
return NULL;
}
/*
* Find an eligible tree to time-out
* A tree is eligible if :-
@ -353,11 +439,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
unsigned long timeout;
struct dentry *root = sb->s_root;
struct dentry *dentry;
struct dentry *expired = NULL;
int do_now = how & AUTOFS_EXP_IMMEDIATE;
int exp_leaves = how & AUTOFS_EXP_LEAVES;
struct dentry *expired;
struct autofs_info *ino;
unsigned int ino_count;
if (!root)
return NULL;
@ -369,77 +452,28 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
while ((dentry = get_next_positive_subdir(dentry, root))) {
spin_lock(&sbi->fs_lock);
ino = autofs4_dentry_ino(dentry);
/* No point expiring a pending mount */
if (ino->flags & AUTOFS_INF_PENDING)
goto next;
/*
* Case 1: (i) indirect mount or top level pseudo direct mount
* (autofs-4.1).
* (ii) indirect mount with offset mount, check the "/"
* offset (autofs-5.0+).
*/
if (d_mountpoint(dentry)) {
DPRINTK("checking mountpoint %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/* Can we umount this guy */
if (autofs4_mount_busy(mnt, dentry))
goto next;
/* Can we expire this guy */
if (autofs4_can_expire(dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
goto next;
if (ino->flags & AUTOFS_INF_NO_RCU)
expired = NULL;
else
expired = should_expire(dentry, mnt, timeout, how);
if (!expired) {
spin_unlock(&sbi->fs_lock);
continue;
}
if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
DPRINTK("checking symlink %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/*
* A symlink can't be "busy" in the usual sense so
* just check last used for expire timeout.
*/
if (autofs4_can_expire(dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
goto next;
}
if (simple_empty(dentry))
goto next;
/* Case 2: tree mount, expire iff entire tree is not busy */
if (!exp_leaves) {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
if (d_count(dentry) > ino_count)
goto next;
if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
/*
* Case 3: pseudo direct mount, expire individual leaves
* (autofs-4.1).
*/
} else {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
if (d_count(dentry) > ino_count)
goto next;
expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
if (expired) {
ino = autofs4_dentry_ino(expired);
ino->flags |= AUTOFS_INF_NO_RCU;
spin_unlock(&sbi->fs_lock);
synchronize_rcu();
spin_lock(&sbi->fs_lock);
if (should_expire(expired, mnt, timeout, how)) {
if (expired != dentry)
dput(dentry);
goto found;
}
goto found;
}
next:
ino->flags &= ~AUTOFS_INF_NO_RCU;
if (expired != dentry)
dput(expired);
spin_unlock(&sbi->fs_lock);
}
return NULL;
@ -447,8 +481,9 @@ next:
found:
DPRINTK("returning %p %.*s",
expired, (int)expired->d_name.len, expired->d_name.name);
ino = autofs4_dentry_ino(expired);
ino->flags |= AUTOFS_INF_EXPIRING;
smp_mb();
ino->flags &= ~AUTOFS_INF_NO_RCU;
init_completion(&ino->expire_complete);
spin_unlock(&sbi->fs_lock);
spin_lock(&sbi->lookup_lock);
@ -461,13 +496,18 @@ found:
return expired;
}
int autofs4_expire_wait(struct dentry *dentry)
int autofs4_expire_wait(struct dentry *dentry, int rcu_walk)
{
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
int status;
/* Block on any pending expire */
if (!(ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU)))
return 0;
if (rcu_walk)
return -ECHILD;
spin_lock(&sbi->fs_lock);
if (ino->flags & AUTOFS_INF_EXPIRING) {
spin_unlock(&sbi->fs_lock);
@ -519,6 +559,8 @@ int autofs4_expire_run(struct super_block *sb,
spin_lock(&sbi->fs_lock);
ino = autofs4_dentry_ino(dentry);
/* avoid rapid-fire expire attempts if expiry fails */
ino->last_used = now;
ino->flags &= ~AUTOFS_INF_EXPIRING;
complete_all(&ino->expire_complete);
spin_unlock(&sbi->fs_lock);
@ -545,6 +587,8 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
ret = autofs4_wait(sbi, dentry, NFY_EXPIRE);
spin_lock(&sbi->fs_lock);
/* avoid rapid-fire expire attempts if expiry fails */
ino->last_used = now;
ino->flags &= ~AUTOFS_INF_EXPIRING;
complete_all(&ino->expire_complete);
spin_unlock(&sbi->fs_lock);

View File

@ -210,7 +210,8 @@ next:
return NULL;
}
static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)
static struct dentry *autofs4_lookup_expiring(struct dentry *dentry,
bool rcu_walk)
{
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct dentry *parent = dentry->d_parent;
@ -229,6 +230,11 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)
struct dentry *expiring;
struct qstr *qstr;
if (rcu_walk) {
spin_unlock(&sbi->lookup_lock);
return ERR_PTR(-ECHILD);
}
ino = list_entry(p, struct autofs_info, expiring);
expiring = ino->dentry;
@ -264,13 +270,15 @@ next:
return NULL;
}
static int autofs4_mount_wait(struct dentry *dentry)
static int autofs4_mount_wait(struct dentry *dentry, bool rcu_walk)
{
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
int status = 0;
if (ino->flags & AUTOFS_INF_PENDING) {
if (rcu_walk)
return -ECHILD;
DPRINTK("waiting for mount name=%.*s",
dentry->d_name.len, dentry->d_name.name);
status = autofs4_wait(sbi, dentry, NFY_MOUNT);
@ -280,20 +288,22 @@ static int autofs4_mount_wait(struct dentry *dentry)
return status;
}
static int do_expire_wait(struct dentry *dentry)
static int do_expire_wait(struct dentry *dentry, bool rcu_walk)
{
struct dentry *expiring;
expiring = autofs4_lookup_expiring(dentry);
expiring = autofs4_lookup_expiring(dentry, rcu_walk);
if (IS_ERR(expiring))
return PTR_ERR(expiring);
if (!expiring)
return autofs4_expire_wait(dentry);
return autofs4_expire_wait(dentry, rcu_walk);
else {
/*
* If we are racing with expire the request might not
* be quite complete, but the directory has been removed
* so it must have been successful, just wait for it.
*/
autofs4_expire_wait(expiring);
autofs4_expire_wait(expiring, 0);
autofs4_del_expiring(expiring);
dput(expiring);
}
@ -345,7 +355,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
* and the directory was removed, so just go ahead and try
* the mount.
*/
status = do_expire_wait(dentry);
status = do_expire_wait(dentry, 0);
if (status && status != -EAGAIN)
return NULL;
@ -353,7 +363,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
spin_lock(&sbi->fs_lock);
if (ino->flags & AUTOFS_INF_PENDING) {
spin_unlock(&sbi->fs_lock);
status = autofs4_mount_wait(dentry);
status = autofs4_mount_wait(dentry, 0);
if (status)
return ERR_PTR(status);
goto done;
@ -394,7 +404,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
}
ino->flags |= AUTOFS_INF_PENDING;
spin_unlock(&sbi->fs_lock);
status = autofs4_mount_wait(dentry);
status = autofs4_mount_wait(dentry, 0);
spin_lock(&sbi->fs_lock);
ino->flags &= ~AUTOFS_INF_PENDING;
if (status) {
@ -423,28 +433,46 @@ static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk)
/* The daemon never waits. */
if (autofs4_oz_mode(sbi)) {
if (rcu_walk)
return 0;
if (!d_mountpoint(dentry))
return -EISDIR;
return 0;
}
/* We need to sleep, so we need pathwalk to be in ref-mode */
if (rcu_walk)
return -ECHILD;
/* Wait for pending expires */
do_expire_wait(dentry);
if (do_expire_wait(dentry, rcu_walk) == -ECHILD)
return -ECHILD;
/*
* This dentry may be under construction so wait on mount
* completion.
*/
status = autofs4_mount_wait(dentry);
status = autofs4_mount_wait(dentry, rcu_walk);
if (status)
return status;
if (rcu_walk) {
/* We don't need fs_lock in rcu_walk mode,
* just testing 'AUTOFS_INFO_NO_RCU' is enough.
* simple_empty() takes a spinlock, so leave it
* to last.
* We only return -EISDIR when certain this isn't
* a mount-trap.
*/
struct inode *inode;
if (ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU))
return 0;
if (d_mountpoint(dentry))
return 0;
inode = ACCESS_ONCE(dentry->d_inode);
if (inode && S_ISLNK(inode->i_mode))
return -EISDIR;
if (list_empty(&dentry->d_subdirs))
return 0;
if (!simple_empty(dentry))
return -EISDIR;
return 0;
}
spin_lock(&sbi->fs_lock);
/*
* If the dentry has been selected for expire while we slept

View File

@ -78,11 +78,11 @@
/*
* In memory structure of each btree node
*/
typedef struct {
struct befs_btree_node {
befs_host_btree_nodehead head; /* head of node converted to cpu byteorder */
struct buffer_head *bh;
befs_btree_nodehead *od_node; /* on disk node */
} befs_btree_node;
};
/* local constants */
static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL;
@ -90,27 +90,30 @@ static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL;
/* local functions */
static int befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds,
befs_btree_super * bt_super,
befs_btree_node * this_node,
struct befs_btree_node *this_node,
befs_off_t * node_off);
static int befs_bt_read_super(struct super_block *sb, befs_data_stream * ds,
befs_btree_super * sup);
static int befs_bt_read_node(struct super_block *sb, befs_data_stream * ds,
befs_btree_node * node, befs_off_t node_off);
struct befs_btree_node *node,
befs_off_t node_off);
static int befs_leafnode(befs_btree_node * node);
static int befs_leafnode(struct befs_btree_node *node);
static fs16 *befs_bt_keylen_index(befs_btree_node * node);
static fs16 *befs_bt_keylen_index(struct befs_btree_node *node);
static fs64 *befs_bt_valarray(befs_btree_node * node);
static fs64 *befs_bt_valarray(struct befs_btree_node *node);
static char *befs_bt_keydata(befs_btree_node * node);
static char *befs_bt_keydata(struct befs_btree_node *node);
static int befs_find_key(struct super_block *sb, befs_btree_node * node,
static int befs_find_key(struct super_block *sb,
struct befs_btree_node *node,
const char *findkey, befs_off_t * value);
static char *befs_bt_get_key(struct super_block *sb, befs_btree_node * node,
static char *befs_bt_get_key(struct super_block *sb,
struct befs_btree_node *node,
int index, u16 * keylen);
static int befs_compare_strings(const void *key1, int keylen1,
@ -191,7 +194,7 @@ befs_bt_read_super(struct super_block *sb, befs_data_stream * ds,
static int
befs_bt_read_node(struct super_block *sb, befs_data_stream * ds,
befs_btree_node * node, befs_off_t node_off)
struct befs_btree_node *node, befs_off_t node_off)
{
uint off = 0;
@ -247,7 +250,7 @@ int
befs_btree_find(struct super_block *sb, befs_data_stream * ds,
const char *key, befs_off_t * value)
{
befs_btree_node *this_node = NULL;
struct befs_btree_node *this_node = NULL;
befs_btree_super bt_super;
befs_off_t node_off;
int res;
@ -260,11 +263,11 @@ befs_btree_find(struct super_block *sb, befs_data_stream * ds,
goto error;
}
this_node = kmalloc(sizeof (befs_btree_node),
this_node = kmalloc(sizeof(struct befs_btree_node),
GFP_NOFS);
if (!this_node) {
befs_error(sb, "befs_btree_find() failed to allocate %zu "
"bytes of memory", sizeof (befs_btree_node));
"bytes of memory", sizeof(struct befs_btree_node));
goto error;
}
@ -333,7 +336,7 @@ befs_btree_find(struct super_block *sb, befs_data_stream * ds,
* Use binary search instead of a linear.
*/
static int
befs_find_key(struct super_block *sb, befs_btree_node * node,
befs_find_key(struct super_block *sb, struct befs_btree_node *node,
const char *findkey, befs_off_t * value)
{
int first, last, mid;
@ -417,7 +420,7 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds,
loff_t key_no, size_t bufsize, char *keybuf, size_t * keysize,
befs_off_t * value)
{
befs_btree_node *this_node;
struct befs_btree_node *this_node;
befs_btree_super bt_super;
befs_off_t node_off = 0;
int cur_key;
@ -436,9 +439,10 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds,
goto error;
}
if ((this_node = kmalloc(sizeof (befs_btree_node), GFP_NOFS)) == NULL) {
this_node = kmalloc(sizeof(struct befs_btree_node), GFP_NOFS);
if (this_node == NULL) {
befs_error(sb, "befs_btree_read() failed to allocate %zu "
"bytes of memory", sizeof (befs_btree_node));
"bytes of memory", sizeof(struct befs_btree_node));
goto error;
}
@ -545,7 +549,8 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds,
*/
static int
befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds,
befs_btree_super * bt_super, befs_btree_node * this_node,
befs_btree_super *bt_super,
struct befs_btree_node *this_node,
befs_off_t * node_off)
{
@ -600,7 +605,7 @@ befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds,
* Return 1 if leaf, 0 if interior
*/
static int
befs_leafnode(befs_btree_node * node)
befs_leafnode(struct befs_btree_node *node)
{
/* all interior nodes (and only interior nodes) have an overflow node */
if (node->head.overflow == befs_bt_inval)
@ -623,7 +628,7 @@ befs_leafnode(befs_btree_node * node)
* Except that rounding up to 8 works, and rounding up to 4 doesn't.
*/
static fs16 *
befs_bt_keylen_index(befs_btree_node * node)
befs_bt_keylen_index(struct befs_btree_node *node)
{
const int keylen_align = 8;
unsigned long int off =
@ -644,7 +649,7 @@ befs_bt_keylen_index(befs_btree_node * node)
* of the node pointed to by the node header
*/
static fs64 *
befs_bt_valarray(befs_btree_node * node)
befs_bt_valarray(struct befs_btree_node *node)
{
void *keylen_index_start = (void *) befs_bt_keylen_index(node);
size_t keylen_index_size = node->head.all_key_count * sizeof (fs16);
@ -660,7 +665,7 @@ befs_bt_valarray(befs_btree_node * node)
* of the node pointed to by the node header
*/
static char *
befs_bt_keydata(befs_btree_node * node)
befs_bt_keydata(struct befs_btree_node *node)
{
return (char *) ((void *) node->od_node + sizeof (befs_btree_nodehead));
}
@ -676,7 +681,7 @@ befs_bt_keydata(befs_btree_node * node)
* Returns NULL on failure (bad input) and sets *@keylen = 0
*/
static char *
befs_bt_get_key(struct super_block *sb, befs_btree_node * node,
befs_bt_get_key(struct super_block *sb, struct befs_btree_node *node,
int index, u16 * keylen)
{
int prev_key_end;

View File

@ -62,7 +62,22 @@ static struct file_system_type bm_fs_type;
static struct vfsmount *bm_mnt;
static int entry_count;
/*
/*
* Max length of the register string. Determined by:
* - 7 delimiters
* - name: ~50 bytes
* - type: 1 byte
* - offset: 3 bytes (has to be smaller than BINPRM_BUF_SIZE)
* - magic: 128 bytes (512 in escaped form)
* - mask: 128 bytes (512 in escaped form)
* - interp: ~50 bytes
* - flags: 5 bytes
* Round that up a bit, and then back off to hold the internal data
* (like struct Node).
*/
#define MAX_REGISTER_LENGTH 1920
/*
* Check if we support the binfmt
* if we do, return the node, else NULL
* locking is done in load_misc_binary
@ -279,7 +294,7 @@ static Node *create_entry(const char __user *buffer, size_t count)
/* some sanity checks */
err = -EINVAL;
if ((count < 11) || (count > 256))
if ((count < 11) || (count > MAX_REGISTER_LENGTH))
goto out;
err = -ENOMEM;
@ -396,12 +411,12 @@ static int parse_command(const char __user *buffer, size_t count)
{
char s[4];
if (!count)
return 0;
if (count > 3)
return -EINVAL;
if (copy_from_user(s, buffer, count))
return -EFAULT;
if (!count)
return 0;
if (s[count-1] == '\n')
count--;
if (count == 1 && s[0] == '0')

View File

@ -1331,8 +1331,8 @@ lookup_bh_lru(struct block_device *bdev, sector_t block, unsigned size)
for (i = 0; i < BH_LRU_SIZE; i++) {
struct buffer_head *bh = __this_cpu_read(bh_lrus.bhs[i]);
if (bh && bh->b_bdev == bdev &&
bh->b_blocknr == block && bh->b_size == size) {
if (bh && bh->b_blocknr == block && bh->b_bdev == bdev &&
bh->b_size == size) {
if (i) {
while (i) {
__this_cpu_write(bh_lrus.bhs[i],

View File

@ -195,15 +195,15 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
else
noff = tkn_e - (sb_mountdata + off) + 1;
if (strnicmp(sb_mountdata + off, "unc=", 4) == 0) {
if (strncasecmp(sb_mountdata + off, "unc=", 4) == 0) {
off += noff;
continue;
}
if (strnicmp(sb_mountdata + off, "ip=", 3) == 0) {
if (strncasecmp(sb_mountdata + off, "ip=", 3) == 0) {
off += noff;
continue;
}
if (strnicmp(sb_mountdata + off, "prefixpath=", 11) == 0) {
if (strncasecmp(sb_mountdata + off, "prefixpath=", 11) == 0) {
off += noff;
continue;
}

View File

@ -1718,7 +1718,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
goto cifs_parse_mount_err;
}
if (strnicmp(string, "default", 7) != 0) {
if (strncasecmp(string, "default", 7) != 0) {
vol->iocharset = kstrdup(string,
GFP_KERNEL);
if (!vol->iocharset) {
@ -1790,7 +1790,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
if (string == NULL)
goto out_nomem;
if (strnicmp(string, "1", 1) == 0) {
if (strncasecmp(string, "1", 1) == 0) {
/* This is the default */
break;
}

View File

@ -199,6 +199,14 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm)
err = cn_printf(cn, "%d",
task_tgid_nr(current));
break;
case 'i':
err = cn_printf(cn, "%d",
task_pid_vnr(current));
break;
case 'I':
err = cn_printf(cn, "%d",
task_pid_nr(current));
break;
/* uid */
case 'u':
err = cn_printf(cn, "%d", cred->uid);

View File

@ -164,8 +164,6 @@ int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster)
return 0;
}
extern struct timezone sys_tz;
/*
* The epoch of FAT timestamp is 1980.
* : bits : value

View File

@ -242,8 +242,6 @@ extern int hfs_mac2asc(struct super_block *, char *, const struct hfs_name *);
/* super.c */
extern void hfs_mark_mdb_dirty(struct super_block *sb);
extern struct timezone sys_tz;
/*
* There are two time systems. Both are based on seconds since
* a particular time/date.

View File

@ -247,7 +247,7 @@ static int isofs_dentry_cmp_common(
}
if (alen == blen) {
if (ci) {
if (strnicmp(name->name, str, alen) == 0)
if (strncasecmp(name->name, str, alen) == 0)
return 0;
} else {
if (strncmp(name->name, str, alen) == 0)

View File

@ -1178,9 +1178,6 @@ static int day_n[] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
extern struct timezone sys_tz;
static int utc2local(int time)
{
return time - sys_tz.tz_minuteswest * 60;

View File

@ -56,11 +56,9 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
mutex_unlock(&inode->i_mutex);
nilfs = inode->i_sb->s_fs_info;
if (!err && nilfs_test_opt(nilfs, BARRIER)) {
err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
if (err != -EIO)
err = 0;
}
if (!err)
err = nilfs_flush_device(nilfs);
return err;
}

View File

@ -126,7 +126,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
nilfs_transaction_abort(inode->i_sb);
goto out;
}
nilfs_mark_inode_dirty(inode);
nilfs_mark_inode_dirty_sync(inode);
nilfs_transaction_commit(inode->i_sb); /* never fails */
/* Error handling should be detailed */
set_buffer_new(bh_result);
@ -672,7 +672,7 @@ void nilfs_write_inode_common(struct inode *inode,
for substitutions of appended fields */
}
void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh)
void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh, int flags)
{
ino_t ino = inode->i_ino;
struct nilfs_inode_info *ii = NILFS_I(inode);
@ -683,7 +683,8 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh)
if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state))
memset(raw_inode, 0, NILFS_MDT(ifile)->mi_entry_size);
set_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
if (flags & I_DIRTY_DATASYNC)
set_bit(NILFS_I_INODE_SYNC, &ii->i_state);
nilfs_write_inode_common(inode, raw_inode, 0);
/* XXX: call with has_bmap = 0 is a workaround to avoid
@ -939,7 +940,7 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty)
return 0;
}
int nilfs_mark_inode_dirty(struct inode *inode)
int __nilfs_mark_inode_dirty(struct inode *inode, int flags)
{
struct buffer_head *ibh;
int err;
@ -950,7 +951,7 @@ int nilfs_mark_inode_dirty(struct inode *inode)
"failed to reget inode block.\n");
return err;
}
nilfs_update_inode(inode, ibh);
nilfs_update_inode(inode, ibh, flags);
mark_buffer_dirty(ibh);
nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile);
brelse(ibh);
@ -983,7 +984,7 @@ void nilfs_dirty_inode(struct inode *inode, int flags)
return;
}
nilfs_transaction_begin(inode->i_sb, &ti, 0);
nilfs_mark_inode_dirty(inode);
__nilfs_mark_inode_dirty(inode, flags);
nilfs_transaction_commit(inode->i_sb); /* never fails */
}

View File

@ -1022,11 +1022,9 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
return ret;
nilfs = inode->i_sb->s_fs_info;
if (nilfs_test_opt(nilfs, BARRIER)) {
ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
if (ret == -EIO)
return ret;
}
ret = nilfs_flush_device(nilfs);
if (ret < 0)
return ret;
if (argp != NULL) {
down_read(&nilfs->ns_segctor_sem);

View File

@ -104,7 +104,7 @@ enum {
constructor */
NILFS_I_COLLECTED, /* All dirty blocks are collected */
NILFS_I_UPDATED, /* The file has been written back */
NILFS_I_INODE_DIRTY, /* write_inode is requested */
NILFS_I_INODE_SYNC, /* dsync is not allowed for inode */
NILFS_I_BMAP, /* has bmap and btnode_cache */
NILFS_I_GCINODE, /* inode for GC, on memory only */
};
@ -273,7 +273,7 @@ struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root,
unsigned long ino);
extern struct inode *nilfs_iget_for_gc(struct super_block *sb,
unsigned long ino, __u64 cno);
extern void nilfs_update_inode(struct inode *, struct buffer_head *);
extern void nilfs_update_inode(struct inode *, struct buffer_head *, int);
extern void nilfs_truncate(struct inode *);
extern void nilfs_evict_inode(struct inode *);
extern int nilfs_setattr(struct dentry *, struct iattr *);
@ -282,10 +282,18 @@ int nilfs_permission(struct inode *inode, int mask);
int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh);
extern int nilfs_inode_dirty(struct inode *);
int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty);
extern int nilfs_mark_inode_dirty(struct inode *);
extern int __nilfs_mark_inode_dirty(struct inode *, int);
extern void nilfs_dirty_inode(struct inode *, int flags);
int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
__u64 start, __u64 len);
static inline int nilfs_mark_inode_dirty(struct inode *inode)
{
return __nilfs_mark_inode_dirty(inode, I_DIRTY);
}
static inline int nilfs_mark_inode_dirty_sync(struct inode *inode)
{
return __nilfs_mark_inode_dirty(inode, I_DIRTY_SYNC);
}
/* super.c */
extern struct inode *nilfs_alloc_inode(struct super_block *);

View File

@ -930,7 +930,7 @@ static void nilfs_drop_collected_inodes(struct list_head *head)
if (!test_and_clear_bit(NILFS_I_COLLECTED, &ii->i_state))
continue;
clear_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
clear_bit(NILFS_I_INODE_SYNC, &ii->i_state);
set_bit(NILFS_I_UPDATED, &ii->i_state);
}
}
@ -1833,6 +1833,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
nilfs_set_next_segment(nilfs, segbuf);
if (update_sr) {
nilfs->ns_flushed_device = 0;
nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
@ -2194,7 +2195,7 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
nilfs_transaction_lock(sb, &ti, 0);
ii = NILFS_I(inode);
if (test_bit(NILFS_I_INODE_DIRTY, &ii->i_state) ||
if (test_bit(NILFS_I_INODE_SYNC, &ii->i_state) ||
nilfs_test_opt(nilfs, STRICT_ORDER) ||
test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) ||
nilfs_discontinued(nilfs)) {
@ -2216,6 +2217,8 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
sci->sc_dsync_end = end;
err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC);
if (!err)
nilfs->ns_flushed_device = 0;
nilfs_transaction_unlock(sb);
return err;

View File

@ -310,6 +310,9 @@ int nilfs_commit_super(struct super_block *sb, int flag)
nilfs->ns_sbsize));
}
clear_nilfs_sb_dirty(nilfs);
nilfs->ns_flushed_device = 1;
/* make sure store to ns_flushed_device cannot be reordered */
smp_wmb();
return nilfs_sync_super(sb, flag);
}
@ -514,6 +517,9 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
}
up_write(&nilfs->ns_sem);
if (!err)
err = nilfs_flush_device(nilfs);
return err;
}

View File

@ -46,6 +46,7 @@ enum {
/**
* struct the_nilfs - struct to supervise multiple nilfs mount points
* @ns_flags: flags
* @ns_flushed_device: flag indicating if all volatile data was flushed
* @ns_bdev: block device
* @ns_sem: semaphore for shared states
* @ns_snapshot_mount_mutex: mutex to protect snapshot mounts
@ -103,6 +104,7 @@ enum {
*/
struct the_nilfs {
unsigned long ns_flags;
int ns_flushed_device;
struct block_device *ns_bdev;
struct rw_semaphore ns_sem;
@ -371,4 +373,24 @@ static inline int nilfs_segment_is_active(struct the_nilfs *nilfs, __u64 n)
return n == nilfs->ns_segnum || n == nilfs->ns_nextnum;
}
static inline int nilfs_flush_device(struct the_nilfs *nilfs)
{
int err;
if (!nilfs_test_opt(nilfs, BARRIER) || nilfs->ns_flushed_device)
return 0;
nilfs->ns_flushed_device = 1;
/*
* the store to ns_flushed_device must not be reordered after
* blkdev_issue_flush().
*/
smp_wmb();
err = blkdev_issue_flush(nilfs->ns_bdev, GFP_KERNEL, NULL);
if (err != -EIO)
err = 0;
return err;
}
#endif /* _THE_NILFS_H */

View File

@ -2244,7 +2244,7 @@ ssize_t o2hb_heartbeat_group_mode_store(struct o2hb_heartbeat_group *group,
return -EINVAL;
for (i = 0; i < O2HB_HEARTBEAT_NUM_MODES; ++i) {
if (strnicmp(page, o2hb_heartbeat_mode_desc[i], len))
if (strncasecmp(page, o2hb_heartbeat_mode_desc[i], len))
continue;
ret = o2hb_global_heartbeat_mode_set(i);

View File

@ -49,13 +49,13 @@ static ssize_t mlog_mask_show(u64 mask, char *buf)
static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
{
if (!strnicmp(buf, "allow", 5)) {
if (!strncasecmp(buf, "allow", 5)) {
__mlog_set_u64(mask, mlog_and_bits);
__mlog_clear_u64(mask, mlog_not_bits);
} else if (!strnicmp(buf, "deny", 4)) {
} else if (!strncasecmp(buf, "deny", 4)) {
__mlog_set_u64(mask, mlog_not_bits);
__mlog_clear_u64(mask, mlog_and_bits);
} else if (!strnicmp(buf, "off", 3)) {
} else if (!strncasecmp(buf, "off", 3)) {
__mlog_clear_u64(mask, mlog_not_bits);
__mlog_clear_u64(mask, mlog_and_bits);
} else

View File

@ -306,9 +306,7 @@ static const struct super_operations omfs_sops = {
*/
static int omfs_get_imap(struct super_block *sb)
{
int bitmap_size;
int array_size;
int count;
unsigned int bitmap_size, count, array_size;
struct omfs_sb_info *sbi = OMFS_SB(sb);
struct buffer_head *bh;
unsigned long **ptr;
@ -473,6 +471,12 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_sys_blocksize = be32_to_cpu(omfs_sb->s_sys_blocksize);
mutex_init(&sbi->s_bitmap_lock);
if (sbi->s_num_blocks > OMFS_MAX_BLOCKS) {
printk(KERN_ERR "omfs: sysblock number (%llx) is out of range\n",
(unsigned long long)sbi->s_num_blocks);
goto out_brelse_bh;
}
if (sbi->s_sys_blocksize > PAGE_SIZE) {
printk(KERN_ERR "omfs: sysblock size (%d) is out of range\n",
sbi->s_sys_blocksize);

View File

@ -18,6 +18,7 @@
#define OMFS_XOR_COUNT 19
#define OMFS_MAX_BLOCK_SIZE 8192
#define OMFS_MAX_CLUSTER_SIZE 8
#define OMFS_MAX_BLOCKS (1ul << 31)
struct omfs_super_block {
char s_fill1[256];

View File

@ -827,8 +827,21 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
.private = &cp,
};
down_read(&mm->mmap_sem);
if (type == CLEAR_REFS_SOFT_DIRTY)
if (type == CLEAR_REFS_SOFT_DIRTY) {
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (!(vma->vm_flags & VM_SOFTDIRTY))
continue;
up_read(&mm->mmap_sem);
down_write(&mm->mmap_sem);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
vma->vm_flags &= ~VM_SOFTDIRTY;
vma_set_page_prot(vma);
}
downgrade_write(&mm->mmap_sem);
break;
}
mmu_notifier_invalidate_range_start(mm, 0, -1);
}
for (vma = mm->mmap; vma; vma = vma->vm_next) {
cp.vma = vma;
if (is_vm_hugetlb_page(vma))
@ -848,10 +861,6 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
continue;
if (type == CLEAR_REFS_MAPPED && !vma->vm_file)
continue;
if (type == CLEAR_REFS_SOFT_DIRTY) {
if (vma->vm_flags & VM_SOFTDIRTY)
vma->vm_flags &= ~VM_SOFTDIRTY;
}
walk_page_range(vma->vm_start, vma->vm_end,
&clear_refs_walk);
}

View File

@ -699,11 +699,13 @@ static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh,
chunk->bh[chunk->nr++] = bh;
if (chunk->nr >= CHUNK_SIZE) {
ret = 1;
if (lock)
if (lock) {
spin_unlock(lock);
fn(chunk);
if (lock)
fn(chunk);
spin_lock(lock);
} else {
fn(chunk);
}
}
return ret;
}

View File

@ -784,7 +784,6 @@ static u64 ufs_bitmap_search(struct super_block *sb,
0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe
};
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
struct ufs_cylinder_group *ucg;
unsigned start, length, loc;
unsigned pos, want, blockmap, mask, end;
u64 result;
@ -792,8 +791,6 @@ static u64 ufs_bitmap_search(struct super_block *sb,
UFSD("ENTER, cg %u, goal %llu, count %u\n", ucpi->c_cgx,
(unsigned long long)goal, count);
ucg = ubh_get_ucg(UCPI_UBH(ucpi));
if (goal)
start = ufs_dtogd(uspi, goal) >> 3;
else

View File

@ -253,6 +253,20 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
#define pgprot_device pgprot_noncached
#endif
#ifndef pgprot_modify
#define pgprot_modify pgprot_modify
static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
{
if (pgprot_val(oldprot) == pgprot_val(pgprot_noncached(oldprot)))
newprot = pgprot_noncached(newprot);
if (pgprot_val(oldprot) == pgprot_val(pgprot_writecombine(oldprot)))
newprot = pgprot_writecombine(newprot);
if (pgprot_val(oldprot) == pgprot_val(pgprot_device(oldprot)))
newprot = pgprot_device(newprot);
return newprot;
}
#endif
/*
* When walking page tables, get the address of the next boundary,
* or the end address of the range if that comes earlier. Although no

View File

@ -22,6 +22,9 @@ extern int __init cma_declare_contiguous(phys_addr_t size,
phys_addr_t base, phys_addr_t limit,
phys_addr_t alignment, unsigned int order_per_bit,
bool fixed, struct cma **res_cma);
extern int cma_init_reserved_mem(phys_addr_t size,
phys_addr_t base, int order_per_bit,
struct cma **res_cma);
extern struct page *cma_alloc(struct cma *cma, int count, unsigned int align);
extern bool cma_release(struct cma *cma, struct page *pages, int count);
#endif

View File

@ -0,0 +1,66 @@
#ifndef __LINUX_COMPILER_H
#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
#endif
#define __used __attribute__((__used__))
#define __must_check __attribute__((warn_unused_result))
#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
/* Mark functions as cold. gcc will assume any path leading to a call
to them will be unlikely. This means a lot of manual unlikely()s
are unnecessary now for any paths leading to the usual suspects
like BUG(), printk(), panic() etc. [but let's keep them for now for
older compilers]
Early snapshots of gcc 4.3 don't support this and we can't detect this
in the preprocessor, but we can live with this because they're unreleased.
Maketime probing would be overkill here.
gcc also has a __attribute__((__hot__)) to move hot functions into
a special section, but I don't see any sense in this right now in
the kernel context */
#define __cold __attribute__((__cold__))
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
#ifndef __CHECKER__
# define __compiletime_warning(message) __attribute__((warning(message)))
# define __compiletime_error(message) __attribute__((error(message)))
#endif /* __CHECKER__ */
/*
* Mark a position in code as unreachable. This can be used to
* suppress control flow warnings after asm blocks that transfer
* control elsewhere.
*
* Early snapshots of gcc 4.5 don't support this and we can't detect
* this in the preprocessor, but we can live with this because they're
* unreleased. Really, we need to have autoconf for the kernel.
*/
#define unreachable() __builtin_unreachable()
/* Mark a function definition as prohibited from being cloned. */
#define __noclone __attribute__((__noclone__))
/*
* Tell the optimizer that something else uses this function or variable.
*/
#define __visible __attribute__((externally_visible))
/*
* GCC 'asm goto' miscompiles certain code sequences:
*
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
*
* Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
* Fixed in GCC 4.8.2 and later versions.
*
* (asm goto is automatically volatile - the naming reflects this.)
*/
#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
#define __HAVE_BUILTIN_BSWAP32__
#define __HAVE_BUILTIN_BSWAP64__
#define __HAVE_BUILTIN_BSWAP16__
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */

View File

@ -376,10 +376,6 @@ extern unsigned long simple_strtoul(const char *,char **,unsigned int);
extern long simple_strtol(const char *,char **,unsigned int);
extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
extern long long simple_strtoll(const char *,char **,unsigned int);
#define strict_strtoul kstrtoul
#define strict_strtol kstrtol
#define strict_strtoull kstrtoull
#define strict_strtoll kstrtoll
extern int num_to_str(char *buf, int size, unsigned long long num);

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