diff --git a/[refs] b/[refs]
index 30d8bf1a5f0f..a9a29dc61551 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 55850f47333c6e7d932e6426eaed863b27c9cd7f
+refs/heads/master: 3db1d97a8109db0a6c2b5cfbb7877990e548ee54
diff --git a/trunk/Documentation/BUG-HUNTING b/trunk/Documentation/BUG-HUNTING
index 65022a87bf17..6c816751b868 100644
--- a/trunk/Documentation/BUG-HUNTING
+++ b/trunk/Documentation/BUG-HUNTING
@@ -214,23 +214,6 @@ And recompile the kernel with CONFIG_DEBUG_INFO enabled:
gdb vmlinux
(gdb) p vt_ioctl
(gdb) l *(0x
+ 0xda8)
-or, as one command
- (gdb) l *(vt_ioctl + 0xda8)
-
-If you have a call trace, such as :-
->Call Trace:
-> [] :jbd:log_wait_commit+0xa3/0xf5
-> [] autoremove_wake_function+0x0/0x2e
-> [] :jbd:journal_stop+0x1be/0x1ee
-> ...
-this shows the problem in the :jbd: module. You can load that module in gdb
-and list the relevant code.
- gdb fs/jbd/jbd.ko
- (gdb) p log_wait_commit
- (gdb) l *(0x + 0xa3)
-or
- (gdb) l *(log_wait_commit + 0xa3)
-
Another very useful option of the Kernel Hacking section in menuconfig is
Debug memory allocations. This will help you see whether data has been
diff --git a/trunk/Documentation/DocBook/kernel-locking.tmpl b/trunk/Documentation/DocBook/kernel-locking.tmpl
index 2e9d6b41f034..01825ee7db64 100644
--- a/trunk/Documentation/DocBook/kernel-locking.tmpl
+++ b/trunk/Documentation/DocBook/kernel-locking.tmpl
@@ -717,7 +717,7 @@ used, and when it gets full, throws out the least used one.
For our first example, we assume that all operations are in user
context (ie. from system calls), so we can sleep. This means we can
-use a mutex to protect the cache and all the objects within
+use a semaphore to protect the cache and all the objects within
it. Here's the code:
@@ -725,7 +725,7 @@ it. Here's the code:
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <linux/mutex.h>
+#include <asm/semaphore.h>
#include <asm/errno.h>
struct object
@@ -737,7 +737,7 @@ struct object
};
/* Protects the cache, cache_num, and the objects within it */
-static DEFINE_MUTEX(cache_lock);
+static DECLARE_MUTEX(cache_lock);
static LIST_HEAD(cache);
static unsigned int cache_num = 0;
#define MAX_CACHE_SIZE 10
@@ -789,17 +789,17 @@ int cache_add(int id, const char *name)
obj->id = id;
obj->popularity = 0;
- mutex_lock(&cache_lock);
+ down(&cache_lock);
__cache_add(obj);
- mutex_unlock(&cache_lock);
+ up(&cache_lock);
return 0;
}
void cache_delete(int id)
{
- mutex_lock(&cache_lock);
+ down(&cache_lock);
__cache_delete(__cache_find(id));
- mutex_unlock(&cache_lock);
+ up(&cache_lock);
}
int cache_find(int id, char *name)
@@ -807,13 +807,13 @@ int cache_find(int id, char *name)
struct object *obj;
int ret = -ENOENT;
- mutex_lock(&cache_lock);
+ down(&cache_lock);
obj = __cache_find(id);
if (obj) {
ret = 0;
strcpy(name, obj->name);
}
- mutex_unlock(&cache_lock);
+ up(&cache_lock);
return ret;
}
@@ -853,7 +853,7 @@ The change is shown below, in standard patch format: the
int popularity;
};
--static DEFINE_MUTEX(cache_lock);
+-static DECLARE_MUTEX(cache_lock);
+static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED;
static LIST_HEAD(cache);
static unsigned int cache_num = 0;
@@ -870,22 +870,22 @@ The change is shown below, in standard patch format: the
obj->id = id;
obj->popularity = 0;
-- mutex_lock(&cache_lock);
+- down(&cache_lock);
+ spin_lock_irqsave(&cache_lock, flags);
__cache_add(obj);
-- mutex_unlock(&cache_lock);
+- up(&cache_lock);
+ spin_unlock_irqrestore(&cache_lock, flags);
return 0;
}
void cache_delete(int id)
{
-- mutex_lock(&cache_lock);
+- down(&cache_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&cache_lock, flags);
__cache_delete(__cache_find(id));
-- mutex_unlock(&cache_lock);
+- up(&cache_lock);
+ spin_unlock_irqrestore(&cache_lock, flags);
}
@@ -895,14 +895,14 @@ The change is shown below, in standard patch format: the
int ret = -ENOENT;
+ unsigned long flags;
-- mutex_lock(&cache_lock);
+- down(&cache_lock);
+ spin_lock_irqsave(&cache_lock, flags);
obj = __cache_find(id);
if (obj) {
ret = 0;
strcpy(name, obj->name);
}
-- mutex_unlock(&cache_lock);
+- up(&cache_lock);
+ spin_unlock_irqrestore(&cache_lock, flags);
return ret;
}
diff --git a/trunk/Documentation/fb/deferred_io.txt b/trunk/Documentation/fb/deferred_io.txt
index 748328370250..63883a892120 100644
--- a/trunk/Documentation/fb/deferred_io.txt
+++ b/trunk/Documentation/fb/deferred_io.txt
@@ -7,10 +7,10 @@ IO. The following example may be a useful explanation of how one such setup
works:
- userspace app like Xfbdev mmaps framebuffer
-- deferred IO and driver sets up fault and page_mkwrite handlers
+- deferred IO and driver sets up nopage and page_mkwrite handlers
- userspace app tries to write to mmaped vaddress
-- we get pagefault and reach fault handler
-- fault handler finds and returns physical page
+- we get pagefault and reach nopage handler
+- nopage handler finds and returns physical page
- we get page_mkwrite where we add this page to a list
- schedule a workqueue task to be run after a delay
- app continues writing to that page with no additional cost. this is
diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt
index 68ce1300a360..a7d9d179131a 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -208,6 +208,13 @@ Who: Randy Dunlap
---------------------------
+What: drivers depending on OSS_OBSOLETE
+When: options in 2.6.23, code in 2.6.25
+Why: obsolete OSS drivers
+Who: Adrian Bunk
+
+---------------------------
+
What: libata spindown skipping and warning
When: Dec 2008
Why: Some halt(8) implementations synchronize caches for and spin
diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt
index 5681e2fa1496..e2799b5fafea 100644
--- a/trunk/Documentation/filesystems/proc.txt
+++ b/trunk/Documentation/filesystems/proc.txt
@@ -1029,14 +1029,6 @@ nr_inodes
Denotes the number of inodes the system has allocated. This number will
grow and shrink dynamically.
-nr_open
--------
-
-Denotes the maximum number of file-handles a process can
-allocate. Default value is 1024*1024 (1048576) which should be
-enough for most machines. Actual limit depends on RLIMIT_NOFILE
-resource limit.
-
nr_free_inodes
--------------
diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt
index 30c101761d0d..53a63890aea4 100644
--- a/trunk/Documentation/kprobes.txt
+++ b/trunk/Documentation/kprobes.txt
@@ -96,9 +96,7 @@ or in registers (e.g., for x86_64 or for an i386 fastcall function).
The jprobe will work in either case, so long as the handler's
prototype matches that of the probed function.
-1.3 Return Probes
-
-1.3.1 How Does a Return Probe Work?
+1.3 How Does a Return Probe Work?
When you call register_kretprobe(), Kprobes establishes a kprobe at
the entry to the function. When the probed function is called and this
@@ -109,9 +107,9 @@ At boot time, Kprobes registers a kprobe at the trampoline.
When the probed function executes its return instruction, control
passes to the trampoline and that probe is hit. Kprobes' trampoline
-handler calls the user-specified return handler associated with the
-kretprobe, then sets the saved instruction pointer to the saved return
-address, and that's where execution resumes upon return from the trap.
+handler calls the user-specified handler associated with the kretprobe,
+then sets the saved instruction pointer to the saved return address,
+and that's where execution resumes upon return from the trap.
While the probed function is executing, its return address is
stored in an object of type kretprobe_instance. Before calling
@@ -133,30 +131,6 @@ zero when the return probe is registered, and is incremented every
time the probed function is entered but there is no kretprobe_instance
object available for establishing the return probe.
-1.3.2 Kretprobe entry-handler
-
-Kretprobes also provides an optional user-specified handler which runs
-on function entry. This handler is specified by setting the entry_handler
-field of the kretprobe struct. Whenever the kprobe placed by kretprobe at the
-function entry is hit, the user-defined entry_handler, if any, is invoked.
-If the entry_handler returns 0 (success) then a corresponding return handler
-is guaranteed to be called upon function return. If the entry_handler
-returns a non-zero error then Kprobes leaves the return address as is, and
-the kretprobe has no further effect for that particular function instance.
-
-Multiple entry and return handler invocations are matched using the unique
-kretprobe_instance object associated with them. Additionally, a user
-may also specify per return-instance private data to be part of each
-kretprobe_instance object. This is especially useful when sharing private
-data between corresponding user entry and return handlers. The size of each
-private data object can be specified at kretprobe registration time by
-setting the data_size field of the kretprobe struct. This data can be
-accessed through the data field of each kretprobe_instance object.
-
-In case probed function is entered but there is no kretprobe_instance
-object available, then in addition to incrementing the nmissed count,
-the user entry_handler invocation is also skipped.
-
2. Architectures Supported
Kprobes, jprobes, and return probes are implemented on the following
@@ -300,8 +274,6 @@ of interest:
- ret_addr: the return address
- rp: points to the corresponding kretprobe object
- task: points to the corresponding task struct
-- data: points to per return-instance private data; see "Kretprobe
- entry-handler" for details.
The regs_return_value(regs) macro provides a simple abstraction to
extract the return value from the appropriate register as defined by
@@ -584,52 +556,23 @@ report failed calls to sys_open().
#include
#include
#include
-#include
-
-/* per-instance private data */
-struct my_data {
- ktime_t entry_stamp;
-};
static const char *probed_func = "sys_open";
-/* Timestamp function entry. */
-static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- struct my_data *data;
-
- if(!current->mm)
- return 1; /* skip kernel threads */
-
- data = (struct my_data *)ri->data;
- data->entry_stamp = ktime_get();
- return 0;
-}
-
-/* If the probed function failed, log the return value and duration.
- * Duration may turn out to be zero consistently, depending upon the
- * granularity of time accounting on the platform. */
-static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+/* Return-probe handler: If the probed function fails, log the return value. */
+static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
int retval = regs_return_value(regs);
- struct my_data *data = (struct my_data *)ri->data;
- s64 delta;
- ktime_t now;
-
if (retval < 0) {
- now = ktime_get();
- delta = ktime_to_ns(ktime_sub(now, data->entry_stamp));
- printk("%s: return val = %d (duration = %lld ns)\n",
- probed_func, retval, delta);
+ printk("%s returns %d\n", probed_func, retval);
}
return 0;
}
static struct kretprobe my_kretprobe = {
- .handler = return_handler,
- .entry_handler = entry_handler,
- .data_size = sizeof(struct my_data),
- .maxactive = 20, /* probe up to 20 instances concurrently */
+ .handler = ret_handler,
+ /* Probe up to 20 instances concurrently. */
+ .maxactive = 20
};
static int __init kretprobe_init(void)
@@ -641,7 +584,7 @@ static int __init kretprobe_init(void)
printk("register_kretprobe failed, returned %d\n", ret);
return -1;
}
- printk("Kretprobe active on %s\n", my_kretprobe.kp.symbol_name);
+ printk("Planted return probe at %p\n", my_kretprobe.kp.addr);
return 0;
}
@@ -651,7 +594,7 @@ static void __exit kretprobe_exit(void)
printk("kretprobe unregistered\n");
/* nmissed > 0 suggests that maxactive was set too low. */
printk("Missed probing %d instances of %s\n",
- my_kretprobe.nmissed, probed_func);
+ my_kretprobe.nmissed, probed_func);
}
module_init(kretprobe_init)
diff --git a/trunk/Documentation/kref.txt b/trunk/Documentation/kref.txt
index 130b6e87aa7e..f38b59d00c63 100644
--- a/trunk/Documentation/kref.txt
+++ b/trunk/Documentation/kref.txt
@@ -141,10 +141,10 @@ The last rule (rule 3) is the nastiest one to handle. Say, for
instance, you have a list of items that are each kref-ed, and you wish
to get the first one. You can't just pull the first item off the list
and kref_get() it. That violates rule 3 because you are not already
-holding a valid pointer. You must add a mutex (or some other lock).
-For instance:
+holding a valid pointer. You must add locks or semaphores. For
+instance:
-static DEFINE_MUTEX(mutex);
+static DECLARE_MUTEX(sem);
static LIST_HEAD(q);
struct my_data
{
@@ -155,12 +155,12 @@ struct my_data
static struct my_data *get_entry()
{
struct my_data *entry = NULL;
- mutex_lock(&mutex);
+ down(&sem);
if (!list_empty(&q)) {
entry = container_of(q.next, struct my_q_entry, link);
kref_get(&entry->refcount);
}
- mutex_unlock(&mutex);
+ up(&sem);
return entry;
}
@@ -174,9 +174,9 @@ static void release_entry(struct kref *ref)
static void put_entry(struct my_data *entry)
{
- mutex_lock(&mutex);
+ down(&sem);
kref_put(&entry->refcount, release_entry);
- mutex_unlock(&mutex);
+ up(&sem);
}
The kref_put() return value is useful if you do not want to hold the
@@ -191,13 +191,13 @@ static void release_entry(struct kref *ref)
static void put_entry(struct my_data *entry)
{
- mutex_lock(&mutex);
+ down(&sem);
if (kref_put(&entry->refcount, release_entry)) {
list_del(&entry->link);
- mutex_unlock(&mutex);
+ up(&sem);
kfree(entry);
} else
- mutex_unlock(&mutex);
+ up(&sem);
}
This is really more useful if you have to call other routines as part
diff --git a/trunk/Documentation/md.txt b/trunk/Documentation/md.txt
index 396cdd982c26..5818628207b5 100644
--- a/trunk/Documentation/md.txt
+++ b/trunk/Documentation/md.txt
@@ -416,16 +416,6 @@ also have
sectors in total that could need to be processed. The two
numbers are separated by a '/' thus effectively showing one
value, a fraction of the process that is complete.
- A 'select' on this attribute will return when resync completes,
- when it reaches the current sync_max (below) and possibly at
- other times.
-
- sync_max
- This is a number of sectors at which point a resync/recovery
- process will pause. When a resync is active, the value can
- only ever be increased, never decreased. The value of 'max'
- effectively disables the limit.
-
sync_speed
This shows the current actual speed, in K/sec, of the current
diff --git a/trunk/Documentation/rtc.txt b/trunk/Documentation/rtc.txt
index 8deffcd68cb8..e20b19c1b60d 100644
--- a/trunk/Documentation/rtc.txt
+++ b/trunk/Documentation/rtc.txt
@@ -182,8 +182,8 @@ driver returns ENOIOCTLCMD. Some common examples:
since the frequency is stored in the irq_freq member of the rtc_device
structure. Your driver needs to initialize the irq_freq member during
init. Make sure you check the requested frequency is in range of your
- hardware in the irq_set_freq function. If it isn't, return -EINVAL. If
- you cannot actually change the frequency, do not define irq_set_freq.
+ hardware in the irq_set_freq function. If you cannot actually change
+ the frequency, just return -ENOTTY.
If all else fails, check out the rtc-test.c driver!
@@ -268,8 +268,8 @@ int main(int argc, char **argv)
/* This read will block */
retval = read(fd, &data, sizeof(unsigned long));
if (retval == -1) {
- perror("read");
- exit(errno);
+ perror("read");
+ exit(errno);
}
fprintf(stderr, " %d",i);
fflush(stderr);
@@ -326,11 +326,11 @@ test_READ:
rtc_tm.tm_sec %= 60;
rtc_tm.tm_min++;
}
- if (rtc_tm.tm_min == 60) {
+ if (rtc_tm.tm_min == 60) {
rtc_tm.tm_min = 0;
rtc_tm.tm_hour++;
}
- if (rtc_tm.tm_hour == 24)
+ if (rtc_tm.tm_hour == 24)
rtc_tm.tm_hour = 0;
retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
@@ -407,8 +407,8 @@ test_PIE:
"\n...Periodic IRQ rate is fixed\n");
goto done;
}
- perror("RTC_IRQP_SET ioctl");
- exit(errno);
+ perror("RTC_IRQP_SET ioctl");
+ exit(errno);
}
fprintf(stderr, "\n%ldHz:\t", tmp);
@@ -417,27 +417,27 @@ test_PIE:
/* Enable periodic interrupts */
retval = ioctl(fd, RTC_PIE_ON, 0);
if (retval == -1) {
- perror("RTC_PIE_ON ioctl");
- exit(errno);
+ perror("RTC_PIE_ON ioctl");
+ exit(errno);
}
for (i=1; i<21; i++) {
- /* This blocks */
- retval = read(fd, &data, sizeof(unsigned long));
- if (retval == -1) {
- perror("read");
- exit(errno);
- }
- fprintf(stderr, " %d",i);
- fflush(stderr);
- irqcount++;
+ /* This blocks */
+ retval = read(fd, &data, sizeof(unsigned long));
+ if (retval == -1) {
+ perror("read");
+ exit(errno);
+ }
+ fprintf(stderr, " %d",i);
+ fflush(stderr);
+ irqcount++;
}
/* Disable periodic interrupts */
retval = ioctl(fd, RTC_PIE_OFF, 0);
if (retval == -1) {
- perror("RTC_PIE_OFF ioctl");
- exit(errno);
+ perror("RTC_PIE_OFF ioctl");
+ exit(errno);
}
}
diff --git a/trunk/Documentation/sysctl/fs.txt b/trunk/Documentation/sysctl/fs.txt
index f99254327ae5..aa986a35e994 100644
--- a/trunk/Documentation/sysctl/fs.txt
+++ b/trunk/Documentation/sysctl/fs.txt
@@ -23,7 +23,6 @@ Currently, these files are in /proc/sys/fs:
- inode-max
- inode-nr
- inode-state
-- nr_open
- overflowuid
- overflowgid
- suid_dumpable
@@ -92,15 +91,6 @@ usage of file handles and you don't need to increase the maximum.
==============================================================
-nr_open:
-
-This denotes the maximum number of file-handles a process can
-allocate. Default value is 1024*1024 (1048576) which should be
-enough for most machines. Actual limit depends on RLIMIT_NOFILE
-resource limit.
-
-==============================================================
-
inode-max, inode-nr & inode-state:
As with file handles, the kernel allocates the inode structures
diff --git a/trunk/Documentation/unaligned-memory-access.txt b/trunk/Documentation/unaligned-memory-access.txt
deleted file mode 100644
index 6223eace3c09..000000000000
--- a/trunk/Documentation/unaligned-memory-access.txt
+++ /dev/null
@@ -1,226 +0,0 @@
-UNALIGNED MEMORY ACCESSES
-=========================
-
-Linux runs on a wide variety of architectures which have varying behaviour
-when it comes to memory access. This document presents some details about
-unaligned accesses, why you need to write code that doesn't cause them,
-and how to write such code!
-
-
-The definition of an unaligned access
-=====================================
-
-Unaligned memory accesses occur when you try to read N bytes of data starting
-from an address that is not evenly divisible by N (i.e. addr % N != 0).
-For example, reading 4 bytes of data from address 0x10004 is fine, but
-reading 4 bytes of data from address 0x10005 would be an unaligned memory
-access.
-
-The above may seem a little vague, as memory access can happen in different
-ways. The context here is at the machine code level: certain instructions read
-or write a number of bytes to or from memory (e.g. movb, movw, movl in x86
-assembly). As will become clear, it is relatively easy to spot C statements
-which will compile to multiple-byte memory access instructions, namely when
-dealing with types such as u16, u32 and u64.
-
-
-Natural alignment
-=================
-
-The rule mentioned above forms what we refer to as natural alignment:
-When accessing N bytes of memory, the base memory address must be evenly
-divisible by N, i.e. addr % N == 0.
-
-When writing code, assume the target architecture has natural alignment
-requirements.
-
-In reality, only a few architectures require natural alignment on all sizes
-of memory access. However, we must consider ALL supported architectures;
-writing code that satisfies natural alignment requirements is the easiest way
-to achieve full portability.
-
-
-Why unaligned access is bad
-===========================
-
-The effects of performing an unaligned memory access vary from architecture
-to architecture. It would be easy to write a whole document on the differences
-here; a summary of the common scenarios is presented below:
-
- - Some architectures are able to perform unaligned memory accesses
- transparently, but there is usually a significant performance cost.
- - Some architectures raise processor exceptions when unaligned accesses
- happen. The exception handler is able to correct the unaligned access,
- at significant cost to performance.
- - Some architectures raise processor exceptions when unaligned accesses
- happen, but the exceptions do not contain enough information for the
- unaligned access to be corrected.
- - Some architectures are not capable of unaligned memory access, but will
- silently perform a different memory access to the one that was requested,
- resulting a a subtle code bug that is hard to detect!
-
-It should be obvious from the above that if your code causes unaligned
-memory accesses to happen, your code will not work correctly on certain
-platforms and will cause performance problems on others.
-
-
-Code that does not cause unaligned access
-=========================================
-
-At first, the concepts above may seem a little hard to relate to actual
-coding practice. After all, you don't have a great deal of control over
-memory addresses of certain variables, etc.
-
-Fortunately things are not too complex, as in most cases, the compiler
-ensures that things will work for you. For example, take the following
-structure:
-
- struct foo {
- u16 field1;
- u32 field2;
- u8 field3;
- };
-
-Let us assume that an instance of the above structure resides in memory
-starting at address 0x10000. With a basic level of understanding, it would
-not be unreasonable to expect that accessing field2 would cause an unaligned
-access. You'd be expecting field2 to be located at offset 2 bytes into the
-structure, i.e. address 0x10002, but that address is not evenly divisible
-by 4 (remember, we're reading a 4 byte value here).
-
-Fortunately, the compiler understands the alignment constraints, so in the
-above case it would insert 2 bytes of padding in between field1 and field2.
-Therefore, for standard structure types you can always rely on the compiler
-to pad structures so that accesses to fields are suitably aligned (assuming
-you do not cast the field to a type of different length).
-
-Similarly, you can also rely on the compiler to align variables and function
-parameters to a naturally aligned scheme, based on the size of the type of
-the variable.
-
-At this point, it should be clear that accessing a single byte (u8 or char)
-will never cause an unaligned access, because all memory addresses are evenly
-divisible by one.
-
-On a related topic, with the above considerations in mind you may observe
-that you could reorder the fields in the structure in order to place fields
-where padding would otherwise be inserted, and hence reduce the overall
-resident memory size of structure instances. The optimal layout of the
-above example is:
-
- struct foo {
- u32 field2;
- u16 field1;
- u8 field3;
- };
-
-For a natural alignment scheme, the compiler would only have to add a single
-byte of padding at the end of the structure. This padding is added in order
-to satisfy alignment constraints for arrays of these structures.
-
-Another point worth mentioning is the use of __attribute__((packed)) on a
-structure type. This GCC-specific attribute tells the compiler never to
-insert any padding within structures, useful when you want to use a C struct
-to represent some data that comes in a fixed arrangement 'off the wire'.
-
-You might be inclined to believe that usage of this attribute can easily
-lead to unaligned accesses when accessing fields that do not satisfy
-architectural alignment requirements. However, again, the compiler is aware
-of the alignment constraints and will generate extra instructions to perform
-the memory access in a way that does not cause unaligned access. Of course,
-the extra instructions obviously cause a loss in performance compared to the
-non-packed case, so the packed attribute should only be used when avoiding
-structure padding is of importance.
-
-
-Code that causes unaligned access
-=================================
-
-With the above in mind, let's move onto a real life example of a function
-that can cause an unaligned memory access. The following function adapted
-from include/linux/etherdevice.h is an optimized routine to compare two
-ethernet MAC addresses for equality.
-
-unsigned int compare_ether_addr(const u8 *addr1, const u8 *addr2)
-{
- const u16 *a = (const u16 *) addr1;
- const u16 *b = (const u16 *) addr2;
- return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
-}
-
-In the above function, the reference to a[0] causes 2 bytes (16 bits) to
-be read from memory starting at address addr1. Think about what would happen
-if addr1 was an odd address such as 0x10003. (Hint: it'd be an unaligned
-access.)
-
-Despite the potential unaligned access problems with the above function, it
-is included in the kernel anyway but is understood to only work on
-16-bit-aligned addresses. It is up to the caller to ensure this alignment or
-not use this function at all. This alignment-unsafe function is still useful
-as it is a decent optimization for the cases when you can ensure alignment,
-which is true almost all of the time in ethernet networking context.
-
-
-Here is another example of some code that could cause unaligned accesses:
- void myfunc(u8 *data, u32 value)
- {
- [...]
- *((u32 *) data) = cpu_to_le32(value);
- [...]
- }
-
-This code will cause unaligned accesses every time the data parameter points
-to an address that is not evenly divisible by 4.
-
-In summary, the 2 main scenarios where you may run into unaligned access
-problems involve:
- 1. Casting variables to types of different lengths
- 2. Pointer arithmetic followed by access to at least 2 bytes of data
-
-
-Avoiding unaligned accesses
-===========================
-
-The easiest way to avoid unaligned access is to use the get_unaligned() and
-put_unaligned() macros provided by the header file.
-
-Going back to an earlier example of code that potentially causes unaligned
-access:
-
- void myfunc(u8 *data, u32 value)
- {
- [...]
- *((u32 *) data) = cpu_to_le32(value);
- [...]
- }
-
-To avoid the unaligned memory access, you would rewrite it as follows:
-
- void myfunc(u8 *data, u32 value)
- {
- [...]
- value = cpu_to_le32(value);
- put_unaligned(value, (u32 *) data);
- [...]
- }
-
-The get_unaligned() macro works similarly. Assuming 'data' is a pointer to
-memory and you wish to avoid unaligned access, its usage is as follows:
-
- u32 value = get_unaligned((u32 *) data);
-
-These macros work work for memory accesses of any length (not just 32 bits as
-in the examples above). Be aware that when compared to standard access of
-aligned memory, using these macros to access unaligned memory can be costly in
-terms of performance.
-
-If use of such macros is not convenient, another option is to use memcpy(),
-where the source or destination (or both) are of type u8* or unsigned char*.
-Due to the byte-wise nature of this operation, unaligned accesses are avoided.
-
---
-Author: Daniel Drake
-With help from: Alan Cox, Avuton Olrich, Heikki Orsila, Jan Engelhardt,
-Johannes Berg, Kyle McMartin, Kyle Moffett, Randy Dunlap, Robert Hancock,
-Uli Kunitz, Vadim Lobanov
-
diff --git a/trunk/Documentation/w1/masters/00-INDEX b/trunk/Documentation/w1/masters/00-INDEX
index 7b0ceaaad7af..752613c4cea2 100644
--- a/trunk/Documentation/w1/masters/00-INDEX
+++ b/trunk/Documentation/w1/masters/00-INDEX
@@ -4,5 +4,3 @@ ds2482
- The Maxim/Dallas Semiconductor DS2482 provides 1-wire busses.
ds2490
- The Maxim/Dallas Semiconductor DS2490 builds USB <-> W1 bridges.
-w1-gpio
- - GPIO 1-wire bus master driver.
diff --git a/trunk/Documentation/w1/masters/w1-gpio b/trunk/Documentation/w1/masters/w1-gpio
deleted file mode 100644
index af5d3b4aa851..000000000000
--- a/trunk/Documentation/w1/masters/w1-gpio
+++ /dev/null
@@ -1,33 +0,0 @@
-Kernel driver w1-gpio
-=====================
-
-Author: Ville Syrjala
-
-
-Description
------------
-
-GPIO 1-wire bus master driver. The driver uses the GPIO API to control the
-wire and the GPIO pin can be specified using platform data.
-
-
-Example (mach-at91)
--------------------
-
-#include
-
-static struct w1_gpio_platform_data foo_w1_gpio_pdata = {
- .pin = AT91_PIN_PB20,
- .is_open_drain = 1,
-};
-
-static struct platform_device foo_w1_device = {
- .name = "w1-gpio",
- .id = -1,
- .dev.platform_data = &foo_w1_gpio_pdata,
-};
-
-...
- at91_set_GPIO_periph(foo_w1_gpio_pdata.pin, 1);
- at91_set_multi_drive(foo_w1_gpio_pdata.pin, 1);
- platform_device_register(&foo_w1_device);
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index c5325d2bb86d..4f3da8b56979 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -338,12 +338,13 @@ S: Maintained for 2.4; PCI support for 2.6.
AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
P: Thomas Dahlmann
M: thomas.dahlmann@amd.com
-L: info-linux@geode.amd.com (subscribers-only)
+L: info-linux@geode.amd.com
S: Supported
AMD GEODE PROCESSOR/CHIPSET SUPPORT
P: Jordan Crouse
-L: info-linux@geode.amd.com (subscribers-only)
+M: info-linux@geode.amd.com
+L: info-linux@geode.amd.com
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
S: Supported
@@ -840,12 +841,6 @@ L: linux-kernel@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
S: Maintained
-BLOCK2MTD DRIVER
-P: Joern Engel
-M: joern@lazybastard.org
-L: linux-mtd@lists.infradead.org
-S: Maintained
-
BLUETOOTH SUBSYSTEM
P: Marcel Holtmann
M: marcel@holtmann.org
@@ -3036,8 +3031,8 @@ L: linux-abi-devel@lists.sourceforge.net
S: Maintained
PHRAM MTD DRIVER
-P: Joern Engel
-M: joern@lazybastard.org
+P: Jörn Engel
+M: joern@wh.fh-wedel.de
L: linux-mtd@lists.infradead.org
S: Maintained
@@ -3861,12 +3856,6 @@ M: oliver@neukum.name
L: linux-usb@vger.kernel.org
S: Maintained
-USB AUERSWALD DRIVER
-P: Wolfgang Muees
-M: wolfgang@iksw-muees.de
-L: linux-usb@vger.kernel.org
-S: Maintained
-
USB BLOCK DRIVER (UB ub)
P: Pete Zaitcev
M: zaitcev@redhat.com
@@ -4017,6 +4006,12 @@ S: Maintained
W: http://geocities.com/i0xox0i
W: http://firstlight.net/cvs
+USB AUERSWALD DRIVER
+P: Wolfgang Muees
+M: wolfgang@iksw-muees.de
+L: linux-usb@vger.kernel.org
+S: Maintained
+
USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
P: Gary Brubaker
M: xavyer@ix.netcom.com
diff --git a/trunk/arch/alpha/Kconfig.debug b/trunk/arch/alpha/Kconfig.debug
index 3f6265f2d9d4..f45f28cc10da 100644
--- a/trunk/arch/alpha/Kconfig.debug
+++ b/trunk/arch/alpha/Kconfig.debug
@@ -7,6 +7,15 @@ config EARLY_PRINTK
depends on ALPHA_GENERIC || ALPHA_SRM
default y
+config DEBUG_RWLOCK
+ bool "Read-write spinlock debugging"
+ depends on DEBUG_KERNEL
+ help
+ If you say Y here then read-write lock processing will count how many
+ times it has tried to get the lock and issue an error message after
+ too many attempts. If you suspect a rwlock problem or a kernel
+ hacker asks for this option then say Y. Otherwise say N.
+
config ALPHA_LEGACY_START_ADDRESS
bool "Legacy kernel start address"
depends on ALPHA_GENERIC
diff --git a/trunk/arch/alpha/defconfig b/trunk/arch/alpha/defconfig
index e43f68fd66b0..6da9c3dbde44 100644
--- a/trunk/arch/alpha/defconfig
+++ b/trunk/arch/alpha/defconfig
@@ -882,6 +882,7 @@ CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_SPINLOCK is not set
CONFIG_DEBUG_INFO=y
CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_RWLOCK is not set
# CONFIG_DEBUG_SEMAPHORE is not set
CONFIG_ALPHA_LEGACY_START_ADDRESS=y
CONFIG_MATHEMU=y
diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c
index 72f9a619a66d..6413c5f23226 100644
--- a/trunk/arch/alpha/kernel/osf_sys.c
+++ b/trunk/arch/alpha/kernel/osf_sys.c
@@ -430,7 +430,7 @@ sys_getpagesize(void)
asmlinkage unsigned long
sys_getdtablesize(void)
{
- return sysctl_nr_open;
+ return NR_OPEN;
}
/*
diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c
index 63c2073401ee..f4ab233201b2 100644
--- a/trunk/arch/alpha/kernel/smp.c
+++ b/trunk/arch/alpha/kernel/smp.c
@@ -77,6 +77,10 @@ int smp_num_probed; /* Internal processor count */
int smp_num_cpus = 1; /* Number that came online. */
EXPORT_SYMBOL(smp_num_cpus);
+extern void calibrate_delay(void);
+
+
+
/*
* Called by both boot and secondaries to move global data into
* per-processor storage.
diff --git a/trunk/arch/arm/mach-at91/board-sam9261ek.c b/trunk/arch/arm/mach-at91/board-sam9261ek.c
index 0ce38dfa6ebe..aa29ea58ca09 100644
--- a/trunk/arch/arm/mach-at91/board-sam9261ek.c
+++ b/trunk/arch/arm/mach-at91/board-sam9261ek.c
@@ -383,7 +383,6 @@ static void at91_lcdc_tft_power_control(int on)
}
static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
- .lcdcon_is_backlight = true,
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN,
.default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2,
diff --git a/trunk/arch/arm/mach-at91/board-sam9263ek.c b/trunk/arch/arm/mach-at91/board-sam9263ek.c
index 38313abef657..f09347a86e71 100644
--- a/trunk/arch/arm/mach-at91/board-sam9263ek.c
+++ b/trunk/arch/arm/mach-at91/board-sam9263ek.c
@@ -253,7 +253,6 @@ static void at91_lcdc_power_control(int on)
/* Driver datas */
static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
- .lcdcon_is_backlight = true,
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN,
.default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2,
diff --git a/trunk/arch/avr32/lib/delay.c b/trunk/arch/avr32/lib/delay.c
index 9aa8800830f3..b3bc0b56e2c6 100644
--- a/trunk/arch/avr32/lib/delay.c
+++ b/trunk/arch/avr32/lib/delay.c
@@ -12,15 +12,13 @@
#include
#include
-#include
#include
#include
-#include
#include
#include
-int __devinit read_current_timer(unsigned long *timer_value)
+int read_current_timer(unsigned long *timer_value)
{
*timer_value = sysreg_read(COUNT);
return 0;
diff --git a/trunk/arch/frv/kernel/setup.c b/trunk/arch/frv/kernel/setup.c
index b38ae1fc15fd..a74c08786b21 100644
--- a/trunk/arch/frv/kernel/setup.c
+++ b/trunk/arch/frv/kernel/setup.c
@@ -708,7 +708,7 @@ static void __init reserve_dma_coherent(void)
/*
* calibrate the delay loop
*/
-void __cpuinit calibrate_delay(void)
+void __init calibrate_delay(void)
{
loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ);
diff --git a/trunk/arch/h8300/kernel/irq.c b/trunk/arch/h8300/kernel/irq.c
index 5a1b4cfea05b..8dec4dd57b4e 100644
--- a/trunk/arch/h8300/kernel/irq.c
+++ b/trunk/arch/h8300/kernel/irq.c
@@ -14,7 +14,6 @@
#include
#include
#include
-#include
#include
#include
diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c
index 32ee5979a042..480b1a5085d5 100644
--- a/trunk/arch/ia64/kernel/smpboot.c
+++ b/trunk/arch/ia64/kernel/smpboot.c
@@ -120,6 +120,7 @@ static volatile unsigned long go[SLAVE + 1];
#define DEBUG_ITC_SYNC 0
+extern void __devinit calibrate_delay (void);
extern void start_ap (void);
extern unsigned long ia64_iobase;
@@ -476,7 +477,7 @@ start_secondary (void *unused)
return 0;
}
-struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs)
+struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
{
return NULL;
}
diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 2c676cc05418..ab3eaf85fe4d 100644
--- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -100,11 +100,11 @@ u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus)
static irqreturn_t
pcibr_error_intr_handler(int irq, void *arg)
{
- struct pcibus_info *soft = arg;
+ struct pcibus_info *soft = (struct pcibus_info *)arg;
- if (sal_pcibr_error_interrupt(soft) < 0)
+ if (sal_pcibr_error_interrupt(soft) < 0) {
panic("pcibr_error_intr_handler(): Fatal Bridge Error");
-
+ }
return IRQ_HANDLED;
}
diff --git a/trunk/arch/m68k/amiga/chipram.c b/trunk/arch/m68k/amiga/chipram.c
index cbe36538af47..d10726f9038b 100644
--- a/trunk/arch/m68k/amiga/chipram.c
+++ b/trunk/arch/m68k/amiga/chipram.c
@@ -32,10 +32,12 @@ void __init amiga_chip_init(void)
if (!AMIGAHW_PRESENT(CHIP_RAM))
return;
+#ifndef CONFIG_APUS_FAST_EXCEPT
/*
* Remove the first 4 pages where PPC exception handlers will be located
*/
amiga_chip_size -= 0x4000;
+#endif
chipram_res.end = amiga_chip_size-1;
request_resource(&iomem_resource, &chipram_res);
diff --git a/trunk/arch/m68k/amiga/cia.c b/trunk/arch/m68k/amiga/cia.c
index 343fab49bd9a..c4a4ffd45bc0 100644
--- a/trunk/arch/m68k/amiga/cia.c
+++ b/trunk/arch/m68k/amiga/cia.c
@@ -84,7 +84,7 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask)
static irqreturn_t cia_handler(int irq, void *dev_id)
{
- struct ciabase *base = dev_id;
+ struct ciabase *base = (struct ciabase *)dev_id;
int mach_irq;
unsigned char ints;
diff --git a/trunk/arch/m68knommu/lib/memcpy.c b/trunk/arch/m68knommu/lib/memcpy.c
index b50dbcad4746..0d5577569e4c 100644
--- a/trunk/arch/m68knommu/lib/memcpy.c
+++ b/trunk/arch/m68knommu/lib/memcpy.c
@@ -1,5 +1,6 @@
#include
+#include
void * memcpy(void * to, const void * from, size_t n)
{
diff --git a/trunk/arch/mips/au1000/common/gpio.c b/trunk/arch/mips/au1000/common/gpio.c
index 0b658f1db4ce..8527856aec45 100644
--- a/trunk/arch/mips/au1000/common/gpio.c
+++ b/trunk/arch/mips/au1000/common/gpio.c
@@ -27,6 +27,7 @@
* others have a second one : GPIO2
*/
+#include
#include
#include
#include
diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c
index 9d41dab90a80..1e5dfc28294a 100644
--- a/trunk/arch/mips/kernel/smp.c
+++ b/trunk/arch/mips/kernel/smp.c
@@ -52,6 +52,7 @@ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
EXPORT_SYMBOL(phys_cpu_present_map);
EXPORT_SYMBOL(cpu_online_map);
+extern void __init calibrate_delay(void);
extern void cpu_idle(void);
/* Number of TCs (or siblings in Intel speak) per CPU core */
diff --git a/trunk/arch/mips/kernel/sysirix.c b/trunk/arch/mips/kernel/sysirix.c
index 22fd41e946b2..4c477c7ff74a 100644
--- a/trunk/arch/mips/kernel/sysirix.c
+++ b/trunk/arch/mips/kernel/sysirix.c
@@ -356,7 +356,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
retval = NGROUPS_MAX;
goto out;
case 5:
- retval = sysctl_nr_open;
+ retval = NR_OPEN;
goto out;
case 6:
retval = 1;
diff --git a/trunk/arch/parisc/Kconfig.debug b/trunk/arch/parisc/Kconfig.debug
index bc989e522a04..9166bd117267 100644
--- a/trunk/arch/parisc/Kconfig.debug
+++ b/trunk/arch/parisc/Kconfig.debug
@@ -2,6 +2,15 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
+config DEBUG_RWLOCK
+ bool "Read-write spinlock debugging"
+ depends on DEBUG_KERNEL && SMP
+ help
+ If you say Y here then read-write lock processing will count how many
+ times it has tried to get the lock and issue an error message after
+ too many attempts. If you suspect a rwlock problem or a kernel
+ hacker asks for this option then say Y. Otherwise say N.
+
config DEBUG_RODATA
bool "Write protect kernel read-only data structures"
depends on DEBUG_KERNEL
diff --git a/trunk/arch/parisc/configs/a500_defconfig b/trunk/arch/parisc/configs/a500_defconfig
index ddacc72e38fb..ea071218a3ed 100644
--- a/trunk/arch/parisc/configs/a500_defconfig
+++ b/trunk/arch/parisc/configs/a500_defconfig
@@ -1050,6 +1050,7 @@ CONFIG_SCHED_DEBUG=y
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_RWLOCK is not set
# CONFIG_DEBUG_RODATA is not set
#
diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c
index 3b26fbd6bec9..5cd3db5cae41 100644
--- a/trunk/arch/powerpc/kernel/time.c
+++ b/trunk/arch/powerpc/kernel/time.c
@@ -66,7 +66,6 @@
#include
#include
#include
-#include
#ifdef CONFIG_PPC_ISERIES
#include
#include
@@ -190,8 +189,6 @@ u64 __cputime_sec_factor;
EXPORT_SYMBOL(__cputime_sec_factor);
u64 __cputime_clockt_factor;
EXPORT_SYMBOL(__cputime_clockt_factor);
-DEFINE_PER_CPU(unsigned long, cputime_last_delta);
-DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
static void calc_cputime_factors(void)
{
@@ -260,8 +257,8 @@ void account_system_vtime(struct task_struct *tsk)
}
account_system_time(tsk, 0, delta);
account_system_time_scaled(tsk, deltascaled);
- per_cpu(cputime_last_delta, smp_processor_id()) = delta;
- per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
+ get_paca()->purrdelta = delta;
+ get_paca()->spurrdelta = deltascaled;
local_irq_restore(flags);
}
@@ -279,7 +276,10 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
get_paca()->user_time = 0;
account_user_time(tsk, utime);
- utimescaled = cputime_to_scaled(utime);
+ /* Estimate the scaled utime by scaling the real utime based
+ * on the last spurr to purr ratio */
+ utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta;
+ get_paca()->spurrdelta = get_paca()->purrdelta = 0;
account_user_time_scaled(tsk, utimescaled);
}
diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c
index 792d3ce8112e..c04abcc28a7a 100644
--- a/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -113,6 +113,8 @@ static inline void debug_calc_bogomips(void)
* result. We backup/restore the value to avoid affecting the
* core cpufreq framework's own calculation.
*/
+ extern void calibrate_delay(void);
+
unsigned long save_lpj = loops_per_jiffy;
calibrate_delay();
loops_per_jiffy = save_lpj;
diff --git a/trunk/arch/ppc/8260_io/enet.c b/trunk/arch/ppc/8260_io/enet.c
index ec1defea9c1e..25ef55bacd99 100644
--- a/trunk/arch/ppc/8260_io/enet.c
+++ b/trunk/arch/ppc/8260_io/enet.c
@@ -418,7 +418,7 @@ scc_enet_rx(struct net_device *dev)
struct sk_buff *skb;
ushort pkt_len;
- cep = dev->priv;
+ cep = (struct scc_enet_private *)dev->priv;
/* First, grab all of the stats for the incoming packet.
* These get messed up if we get called due to a busy condition.
diff --git a/trunk/arch/ppc/8260_io/fcc_enet.c b/trunk/arch/ppc/8260_io/fcc_enet.c
index bcc3aa9d04f3..a3a27dafff1f 100644
--- a/trunk/arch/ppc/8260_io/fcc_enet.c
+++ b/trunk/arch/ppc/8260_io/fcc_enet.c
@@ -682,7 +682,7 @@ fcc_enet_rx(struct net_device *dev)
struct sk_buff *skb;
ushort pkt_len;
- cep = dev->priv;
+ cep = (struct fcc_enet_private *)dev->priv;
/* First, grab all of the stats for the incoming packet.
* These get messed up if we get called due to a busy condition.
diff --git a/trunk/arch/ppc/kernel/vmlinux.lds.S b/trunk/arch/ppc/kernel/vmlinux.lds.S
index 8a24bc47eb6c..52b64fcbdfc5 100644
--- a/trunk/arch/ppc/kernel/vmlinux.lds.S
+++ b/trunk/arch/ppc/kernel/vmlinux.lds.S
@@ -143,6 +143,11 @@ SECTIONS
. = ALIGN(4096);
__init_end = .;
+
+ . = ALIGN(4096);
+ _sextratext = .;
+ _eextratext = .;
+
__bss_start = .;
.bss :
{
diff --git a/trunk/arch/ppc/platforms/prep_setup.c b/trunk/arch/ppc/platforms/prep_setup.c
index 38449855d5ff..3c56654bfc6f 100644
--- a/trunk/arch/ppc/platforms/prep_setup.c
+++ b/trunk/arch/ppc/platforms/prep_setup.c
@@ -91,11 +91,20 @@ extern void prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi
#define cached_21 (((char *)(ppc_cached_irq_mask))[3])
#define cached_A1 (((char *)(ppc_cached_irq_mask))[2])
+#ifdef CONFIG_SOUND_CS4232
+long ppc_cs4232_dma, ppc_cs4232_dma2;
+#endif
+
extern PTE *Hash, *Hash_end;
extern unsigned long Hash_size, Hash_mask;
extern int probingmem;
extern unsigned long loops_per_jiffy;
+#ifdef CONFIG_SOUND_CS4232
+EXPORT_SYMBOL(ppc_cs4232_dma);
+EXPORT_SYMBOL(ppc_cs4232_dma2);
+#endif
+
/* useful ISA ports */
#define PREP_SYSCTL 0x81c
/* present in the IBM reference design; possibly identical in Mot boxes: */
@@ -560,6 +569,74 @@ prep_show_percpuinfo(struct seq_file *m, int i)
return 0;
}
+#ifdef CONFIG_SOUND_CS4232
+static long __init masktoint(unsigned int i)
+{
+ int t = -1;
+ while (i >> ++t)
+ ;
+ return (t-1);
+}
+
+/*
+ * ppc_cs4232_dma and ppc_cs4232_dma2 are used in include/asm/dma.h
+ * to distinguish sound dma-channels from others. This is because
+ * blocksize on 16 bit dma-channels 5,6,7 is 128k, but
+ * the cs4232.c uses 64k like on 8 bit dma-channels 0,1,2,3
+ */
+
+static void __init prep_init_sound(void)
+{
+ PPC_DEVICE *audiodevice = NULL;
+
+ /*
+ * Get the needed resource information from residual data.
+ *
+ */
+ if (have_residual_data)
+ audiodevice = residual_find_device(~0, NULL,
+ MultimediaController, AudioController, -1, 0);
+
+ if (audiodevice != NULL) {
+ PnP_TAG_PACKET *pkt;
+
+ pkt = PnP_find_packet((unsigned char *)&res->DevicePnPHeap[audiodevice->AllocatedOffset],
+ S5_Packet, 0);
+ if (pkt != NULL)
+ ppc_cs4232_dma = masktoint(pkt->S5_Pack.DMAMask);
+ pkt = PnP_find_packet((unsigned char*)&res->DevicePnPHeap[audiodevice->AllocatedOffset],
+ S5_Packet, 1);
+ if (pkt != NULL)
+ ppc_cs4232_dma2 = masktoint(pkt->S5_Pack.DMAMask);
+ }
+
+ /*
+ * These are the PReP specs' defaults for the cs4231. We use these
+ * as fallback incase we don't have residual data.
+ * At least the IBM Thinkpad 850 with IDE DMA Channels at 6 and 7
+ * will use the other values.
+ */
+ if (audiodevice == NULL) {
+ switch (_prep_type) {
+ case _PREP_IBM:
+ ppc_cs4232_dma = 1;
+ ppc_cs4232_dma2 = -1;
+ break;
+ default:
+ ppc_cs4232_dma = 6;
+ ppc_cs4232_dma2 = 7;
+ }
+ }
+
+ /*
+ * Find a way to push this information to the cs4232 driver
+ * Give it out with printk, when not in cmd_line?
+ * Append it to cmd_line and boot_command_line?
+ * Format is cs4232=io,irq,dma,dma2
+ */
+}
+#endif /* CONFIG_SOUND_CS4232 */
+
/*
* Fill out screen_info according to the residual data. This allows us to use
* at least vesafb.
@@ -821,6 +898,10 @@ prep_setup_arch(void)
}
}
+#ifdef CONFIG_SOUND_CS4232
+ prep_init_sound();
+#endif /* CONFIG_SOUND_CS4232 */
+
prep_init_vesa();
switch (_prep_type) {
diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c
index 0def48158c7d..89a6de95070c 100644
--- a/trunk/arch/sparc/kernel/sun4d_smp.c
+++ b/trunk/arch/sparc/kernel/sun4d_smp.c
@@ -19,12 +19,12 @@
#include
#include
#include
-#include
#include
#include
#include
+#include
#include
#include
#include
@@ -41,6 +41,8 @@
extern ctxd_t *srmmu_ctx_table_phys;
+extern void calibrate_delay(void);
+
static volatile int smp_processors_ready = 0;
static int smp_highest_cpu;
extern volatile unsigned long cpu_callin_map[NR_CPUS];
diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c
index 0b9407267162..730eb5796f8e 100644
--- a/trunk/arch/sparc/kernel/sun4m_smp.c
+++ b/trunk/arch/sparc/kernel/sun4m_smp.c
@@ -16,8 +16,6 @@
#include
#include
#include
-#include
-
#include
#include
#include
@@ -25,6 +23,7 @@
#include
#include
+#include
#include
#include
#include
@@ -40,6 +39,8 @@
extern ctxd_t *srmmu_ctx_table_phys;
+extern void calibrate_delay(void);
+
extern volatile unsigned long cpu_callin_map[NR_CPUS];
extern unsigned char boot_cpu_id;
diff --git a/trunk/arch/sparc/kernel/systbls.S b/trunk/arch/sparc/kernel/systbls.S
index ee010f4532a0..9064485dc40b 100644
--- a/trunk/arch/sparc/kernel/systbls.S
+++ b/trunk/arch/sparc/kernel/systbls.S
@@ -79,7 +79,8 @@ sys_call_table:
/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
/*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy
/*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
-/*310*/ .long sys_utimensat, sys_signalfd, sys_ni_syscall, sys_eventfd, sys_fallocate
+/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
+/*315*/ .long sys_timerfd_settime, sys_timerfd_gettime
#ifdef CONFIG_SUNOS_EMUL
/* Now the SunOS syscall table. */
@@ -197,6 +198,7 @@ sunos_sys_table:
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys
/*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys
- .long sunos_nosys, sunos_nosys
+ .long sunos_nosys, sunos_nosys, sunos_nosys
+ .long sunos_nosys
#endif
diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c
index a8052b76df41..c39944927f1a 100644
--- a/trunk/arch/sparc64/kernel/smp.c
+++ b/trunk/arch/sparc64/kernel/smp.c
@@ -46,6 +46,8 @@
#include
#include
+extern void calibrate_delay(void);
+
int sparc64_multi_core __read_mostly;
cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE;
diff --git a/trunk/arch/sparc64/kernel/sparc64_ksyms.c b/trunk/arch/sparc64/kernel/sparc64_ksyms.c
index 8649635d6d74..60765e314bd8 100644
--- a/trunk/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/trunk/arch/sparc64/kernel/sparc64_ksyms.c
@@ -277,7 +277,6 @@ EXPORT_SYMBOL(sys_getpid);
EXPORT_SYMBOL(sys_geteuid);
EXPORT_SYMBOL(sys_getuid);
EXPORT_SYMBOL(sys_getegid);
-EXPORT_SYMBOL(sysctl_nr_open);
EXPORT_SYMBOL(sys_getgid);
EXPORT_SYMBOL(svr4_getcontext);
EXPORT_SYMBOL(svr4_setcontext);
diff --git a/trunk/arch/sparc64/kernel/systbls.S b/trunk/arch/sparc64/kernel/systbls.S
index b8058906e727..adc62f490f36 100644
--- a/trunk/arch/sparc64/kernel/systbls.S
+++ b/trunk/arch/sparc64/kernel/systbls.S
@@ -80,7 +80,8 @@ sys_call_table32:
.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy
.word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait
-/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_ni_syscall, sys_eventfd, compat_sys_fallocate
+/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate
+ .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime
#endif /* CONFIG_COMPAT */
@@ -152,7 +153,8 @@ sys_call_table:
.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy
.word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
-/*310*/ .word sys_utimensat, sys_signalfd, sys_ni_syscall, sys_eventfd, sys_fallocate
+/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
+ .word sys_timerfd_settime, sys_timerfd_gettime
#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -271,6 +273,7 @@ sunos_sys_table:
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys
/*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys
+ .word sunos_nosys, sunos_nosys, sunos_nosys
+ .word sunos_nosys
#endif
diff --git a/trunk/arch/sparc64/kernel/time.c b/trunk/arch/sparc64/kernel/time.c
index d204f1ab1d4c..4352ee4d8dac 100644
--- a/trunk/arch/sparc64/kernel/time.c
+++ b/trunk/arch/sparc64/kernel/time.c
@@ -1707,11 +1707,6 @@ static void __exit rtc_mini_exit(void)
misc_deregister(&rtc_mini_dev);
}
-int __devinit read_current_timer(unsigned long *timer_val)
-{
- *timer_val = tick_ops->get_tick();
- return 0;
-}
module_init(rtc_mini_init);
module_exit(rtc_mini_exit);
diff --git a/trunk/arch/sparc64/solaris/fs.c b/trunk/arch/sparc64/solaris/fs.c
index 9311bfe4f2f7..61be597bf430 100644
--- a/trunk/arch/sparc64/solaris/fs.c
+++ b/trunk/arch/sparc64/solaris/fs.c
@@ -624,7 +624,7 @@ asmlinkage int solaris_ulimit(int cmd, int val)
case 3: /* UL_GMEMLIM */
return current->signal->rlim[RLIMIT_DATA].rlim_cur;
case 4: /* UL_GDESLIM */
- return sysctl_nr_open;
+ return NR_OPEN;
}
return -EINVAL;
}
diff --git a/trunk/arch/sparc64/solaris/timod.c b/trunk/arch/sparc64/solaris/timod.c
index f53123c02c2b..a9d32ceabf26 100644
--- a/trunk/arch/sparc64/solaris/timod.c
+++ b/trunk/arch/sparc64/solaris/timod.c
@@ -859,8 +859,7 @@ asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
SOLD("entry");
lock_kernel();
- if (fd >= sysctl_nr_open)
- goto out;
+ if(fd >= NR_OPEN) goto out;
fdt = files_fdtable(current->files);
filp = fdt->fd[fd];
@@ -928,8 +927,7 @@ asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
SOLD("entry");
lock_kernel();
- if (fd >= sysctl_nr_open)
- goto out;
+ if(fd >= NR_OPEN) goto out;
fdt = files_fdtable(current->files);
filp = fdt->fd[fd];
diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig
index e6728bd61cc1..434821187cfc 100644
--- a/trunk/arch/x86/Kconfig
+++ b/trunk/arch/x86/Kconfig
@@ -415,7 +415,7 @@ config HPET_TIMER
config HPET_EMULATE_RTC
def_bool y
- depends on HPET_TIMER && (RTC=y || RTC=m || RTC_DRV_CMOS=m || RTC_DRV_CMOS=y)
+ depends on HPET_TIMER && (RTC=y || RTC=m)
# Mark as embedded because too many people got it wrong.
# The code disables itself when not needed.
diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c
index f86a3c4a2669..d9313d9adced 100644
--- a/trunk/arch/x86/kernel/cpu/common.c
+++ b/trunk/arch/x86/kernel/cpu/common.c
@@ -637,7 +637,7 @@ void __init early_cpu_init(void)
}
/* Make sure %fs is initialized properly in idle threads */
-struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs)
+struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
{
memset(regs, 0, sizeof(struct pt_regs));
regs->fs = __KERNEL_PERCPU;
diff --git a/trunk/arch/x86/kernel/cpu/cyrix.c b/trunk/arch/x86/kernel/cpu/cyrix.c
index 7139b0262703..404a6a2d4016 100644
--- a/trunk/arch/x86/kernel/cpu/cyrix.c
+++ b/trunk/arch/x86/kernel/cpu/cyrix.c
@@ -83,6 +83,8 @@ static char cyrix_model_mult2[] __cpuinitdata = "12233445";
* FIXME: our newer udelay uses the tsc. We don't need to frob with SLOP
*/
+extern void calibrate_delay(void) __init;
+
static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c)
{
unsigned long flags;
diff --git a/trunk/arch/x86/kernel/smpboot_32.c b/trunk/arch/x86/kernel/smpboot_32.c
index 579b9b740c7c..5787a0c3e296 100644
--- a/trunk/arch/x86/kernel/smpboot_32.c
+++ b/trunk/arch/x86/kernel/smpboot_32.c
@@ -202,6 +202,8 @@ void __cpuinit smp_store_cpu_info(int id)
;
}
+extern void calibrate_delay(void);
+
static atomic_t init_deasserted;
static void __cpuinit smp_callin(void)
diff --git a/trunk/arch/x86/lib/delay_32.c b/trunk/arch/x86/lib/delay_32.c
index 4535e6d147ad..aad9d95469dc 100644
--- a/trunk/arch/x86/lib/delay_32.c
+++ b/trunk/arch/x86/lib/delay_32.c
@@ -12,10 +12,8 @@
#include
#include
-#include
#include
#include
-#include
#include
#include
@@ -65,7 +63,7 @@ void use_tsc_delay(void)
delay_fn = delay_tsc;
}
-int __devinit read_current_timer(unsigned long *timer_val)
+int read_current_timer(unsigned long *timer_val)
{
if (delay_fn == delay_tsc) {
rdtscl(*timer_val);
diff --git a/trunk/arch/x86/lib/delay_64.c b/trunk/arch/x86/lib/delay_64.c
index bbc610518516..45cdd3fbd91c 100644
--- a/trunk/arch/x86/lib/delay_64.c
+++ b/trunk/arch/x86/lib/delay_64.c
@@ -10,10 +10,8 @@
#include
#include
-#include
#include
#include
-#include
#include
#include
@@ -22,7 +20,7 @@
#include
#endif
-int __devinit read_current_timer(unsigned long *timer_value)
+int read_current_timer(unsigned long *timer_value)
{
rdtscll(*timer_value);
return 0;
diff --git a/trunk/arch/x86/mach-voyager/voyager_smp.c b/trunk/arch/x86/mach-voyager/voyager_smp.c
index 3cc8eb2f36a9..dffa786f61fe 100644
--- a/trunk/arch/x86/mach-voyager/voyager_smp.c
+++ b/trunk/arch/x86/mach-voyager/voyager_smp.c
@@ -444,6 +444,8 @@ static __u32 __init setup_trampoline(void)
static void __init start_secondary(void *unused)
{
__u8 cpuid = hard_smp_processor_id();
+ /* external functions not defined in the headers */
+ extern void calibrate_delay(void);
cpu_init();
diff --git a/trunk/arch/xtensa/kernel/time.c b/trunk/arch/xtensa/kernel/time.c
index 8df1e842f6d4..60d29fe0b1bd 100644
--- a/trunk/arch/xtensa/kernel/time.c
+++ b/trunk/arch/xtensa/kernel/time.c
@@ -204,7 +204,7 @@ irqreturn_t timer_interrupt (int irq, void *dev_id)
}
#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
-void __cpuinit calibrate_delay(void)
+void __devinit calibrate_delay(void)
{
loops_per_jiffy = CCOUNT_PER_JIFFY;
printk("Calibrating delay loop (skipped)... "
diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c
index 499b003f9278..c5885f5ce0ac 100644
--- a/trunk/drivers/base/cpu.c
+++ b/trunk/drivers/base/cpu.c
@@ -110,7 +110,7 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
*
* Initialize and register the CPU device.
*/
-int __cpuinit register_cpu(struct cpu *cpu, int num)
+int __devinit register_cpu(struct cpu *cpu, int num)
{
int error;
cpu->node_id = cpu_to_node(num);
diff --git a/trunk/drivers/block/ataflop.c b/trunk/drivers/block/ataflop.c
index 424995073c6b..94268c75d04f 100644
--- a/trunk/drivers/block/ataflop.c
+++ b/trunk/drivers/block/ataflop.c
@@ -90,7 +90,7 @@ static struct atari_disk_type {
unsigned blocks; /* total number of blocks */
unsigned fdc_speed; /* fdc_speed setting */
unsigned stretch; /* track doubling ? */
-} atari_disk_type[] = {
+} disk_type[] = {
{ "d360", 9, 720, 0, 0}, /* 0: 360kB diskette */
{ "D360", 9, 720, 0, 1}, /* 1: 360kb in 720k or 1.2MB drive */
{ "D720", 9,1440, 0, 0}, /* 2: 720kb in 720k or 1.2MB drive */
@@ -658,7 +658,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
return -EINVAL;
}
type = minor2disktype[type].index;
- UDT = &atari_disk_type[type];
+ UDT = &disk_type[type];
}
if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) {
@@ -1064,7 +1064,7 @@ static void fd_rwsec_done1(int status)
searched for a non-existent sector! */
!(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) {
if (Probing) {
- if (SUDT > atari_disk_type) {
+ if (SUDT > disk_type) {
if (SUDT[-1].blocks > ReqBlock) {
/* try another disk type */
SUDT--;
@@ -1082,7 +1082,7 @@ static void fd_rwsec_done1(int status)
} else {
/* record not found, but not probing. Maybe stretch wrong ? Restart probing */
if (SUD.autoprobe) {
- SUDT = atari_disk_type + StartDiskType[DriveType];
+ SUDT = disk_type + StartDiskType[DriveType];
set_capacity(unit[SelectedDrive].disk,
SUDT->blocks);
Probing = 1;
@@ -1421,7 +1421,7 @@ static void redo_fd_request(void)
if (type == 0) {
if (!UDT) {
Probing = 1;
- UDT = atari_disk_type + StartDiskType[DriveType];
+ UDT = disk_type + StartDiskType[DriveType];
set_capacity(floppy->disk, UDT->blocks);
UD.autoprobe = 1;
}
@@ -1439,7 +1439,7 @@ static void redo_fd_request(void)
goto repeat;
}
type = minor2disktype[type].index;
- UDT = &atari_disk_type[type];
+ UDT = &disk_type[type];
set_capacity(floppy->disk, UDT->blocks);
UD.autoprobe = 0;
}
@@ -1505,7 +1505,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
if (minor2disktype[type].drive_types > DriveType)
return -ENODEV;
type = minor2disktype[type].index;
- dtp = &atari_disk_type[type];
+ dtp = &disk_type[type];
if (UD.flags & FTD_MSG)
printk (KERN_ERR "floppy%d: found dtp %p name %s!\n",
drive, dtp, dtp->name);
@@ -1576,7 +1576,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
continue;
}
setidx = minor2disktype[settype].index;
- dtp = &atari_disk_type[setidx];
+ dtp = &disk_type[setidx];
/* found matching entry ?? */
if ( dtp->blocks == setprm.size
diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c
index 9715be3f2487..855ce8e5efba 100644
--- a/trunk/drivers/block/cciss.c
+++ b/trunk/drivers/block/cciss.c
@@ -2630,14 +2630,12 @@ static void do_cciss_request(struct request_queue *q)
c->Request.CDB[8] = creq->nr_sectors & 0xff;
c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
} else {
- u32 upper32 = upper_32_bits(start_blk);
-
c->Request.CDBLen = 16;
c->Request.CDB[1]= 0;
- c->Request.CDB[2]= (upper32 >> 24) & 0xff; //MSB
- c->Request.CDB[3]= (upper32 >> 16) & 0xff;
- c->Request.CDB[4]= (upper32 >> 8) & 0xff;
- c->Request.CDB[5]= upper32 & 0xff;
+ c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
+ c->Request.CDB[3]= (start_blk >> 48) & 0xff;
+ c->Request.CDB[4]= (start_blk >> 40) & 0xff;
+ c->Request.CDB[5]= (start_blk >> 32) & 0xff;
c->Request.CDB[6]= (start_blk >> 24) & 0xff;
c->Request.CDB[7]= (start_blk >> 16) & 0xff;
c->Request.CDB[8]= (start_blk >> 8) & 0xff;
diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c
index 91ebb007416c..b8af22e610df 100644
--- a/trunk/drivers/block/loop.c
+++ b/trunk/drivers/block/loop.c
@@ -973,10 +973,6 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
lo->transfer = xfer->transfer;
lo->ioctl = xfer->ioctl;
- if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) !=
- (info->lo_flags & LO_FLAGS_AUTOCLEAR))
- lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
-
lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
lo->lo_init[0] = info->lo_init[0];
lo->lo_init[1] = info->lo_init[1];
@@ -1335,10 +1331,6 @@ static int lo_release(struct inode *inode, struct file *file)
mutex_lock(&lo->lo_ctl_mutex);
--lo->lo_refcnt;
-
- if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt)
- loop_clr_fd(lo, inode->i_bdev);
-
mutex_unlock(&lo->lo_ctl_mutex);
return 0;
diff --git a/trunk/drivers/block/paride/pt.c b/trunk/drivers/block/paride/pt.c
index 8b9549ab4a4e..76096cad798f 100644
--- a/trunk/drivers/block/paride/pt.c
+++ b/trunk/drivers/block/paride/pt.c
@@ -660,7 +660,7 @@ static int pt_open(struct inode *inode, struct file *file)
pt_identify(tape);
err = -ENODEV;
- if (!(tape->flags & PT_MEDIA))
+ if (!tape->flags & PT_MEDIA)
goto out;
err = -EROFS;
diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c
index 674cd66dcaba..e9de1712e5a0 100644
--- a/trunk/drivers/block/pktcdvd.c
+++ b/trunk/drivers/block/pktcdvd.c
@@ -2212,11 +2212,11 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
return ret;
}
- if (!(buf[6] & 0x40)) {
+ if (!buf[6] & 0x40) {
printk(DRIVER_NAME": Disc type is not CD-RW\n");
return 1;
}
- if (!(buf[6] & 0x4)) {
+ if (!buf[6] & 0x4) {
printk(DRIVER_NAME": A1 values on media are not valid, maybe not CDRW?\n");
return 1;
}
diff --git a/trunk/drivers/block/rd.c b/trunk/drivers/block/rd.c
index 06e23be70904..82f4eecc8699 100644
--- a/trunk/drivers/block/rd.c
+++ b/trunk/drivers/block/rd.c
@@ -56,7 +56,6 @@
#include
#include
#include
-#include
#include
@@ -451,7 +450,7 @@ static int __init rd_init(void)
err = -ENOMEM;
if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 ||
- !is_power_of_2(rd_blocksize)) {
+ (rd_blocksize & (rd_blocksize-1))) {
printk("RAMDISK: wrong blocksize %d, reverting to defaults\n",
rd_blocksize);
rd_blocksize = BLOCK_SIZE;
diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c
index db259e60289b..47e5b40510cb 100644
--- a/trunk/drivers/cdrom/cdrom.c
+++ b/trunk/drivers/cdrom/cdrom.c
@@ -1206,26 +1206,25 @@ int check_for_audio_disc(struct cdrom_device_info * cdi,
return 0;
}
+/* Admittedly, the logic below could be performed in a nicer way. */
int cdrom_release(struct cdrom_device_info *cdi, struct file *fp)
{
struct cdrom_device_ops *cdo = cdi->ops;
int opened_for_data;
- cdinfo(CD_CLOSE, "entering cdrom_release\n");
+ cdinfo(CD_CLOSE, "entering cdrom_release\n");
if (cdi->use_count > 0)
cdi->use_count--;
-
- if (cdi->use_count == 0) {
+ if (cdi->use_count == 0)
cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
+ if (cdi->use_count == 0)
cdrom_dvd_rw_close_write(cdi);
-
- if ((cdo->capability & CDC_LOCK) && !keeplocked) {
- cdinfo(CD_CLOSE, "Unlocking door!\n");
- cdo->lock_door(cdi, 0);
- }
+ if (cdi->use_count == 0 &&
+ (cdo->capability & CDC_LOCK) && !keeplocked) {
+ cdinfo(CD_CLOSE, "Unlocking door!\n");
+ cdo->lock_door(cdi, 0);
}
-
opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
!(fp && fp->f_flags & O_NONBLOCK);
diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig
index 85bf9b2aa74a..466629594776 100644
--- a/trunk/drivers/char/Kconfig
+++ b/trunk/drivers/char/Kconfig
@@ -276,7 +276,7 @@ config N_HDLC
config RISCOM8
tristate "SDL RISCom/8 card support"
- depends on SERIAL_NONSTANDARD
+ depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
help
This is a driver for the SDL Communications RISCom/8 multiport card,
which gives you many serial ports. You would need something like
@@ -765,7 +765,7 @@ config JS_RTC
config SGI_DS1286
tristate "SGI DS1286 RTC support"
- depends on SGI_HAS_DS1286
+ depends on SGI_IP22
help
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c
index 44160d5ebca0..480fae29c9b2 100644
--- a/trunk/drivers/char/hvc_console.c
+++ b/trunk/drivers/char/hvc_console.c
@@ -93,7 +93,7 @@ struct hvc_struct {
};
/* dynamic list of hvc_struct instances */
-static LIST_HEAD(hvc_structs);
+static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs);
/*
* Protect the list of hvc_struct instances from inserts and removals during
diff --git a/trunk/drivers/char/hvcs.c b/trunk/drivers/char/hvcs.c
index 786d518e9477..3402def22007 100644
--- a/trunk/drivers/char/hvcs.c
+++ b/trunk/drivers/char/hvcs.c
@@ -306,7 +306,7 @@ struct hvcs_struct {
/* Required to back map a kref to its containing object */
#define from_kref(k) container_of(k, struct hvcs_struct, kref)
-static LIST_HEAD(hvcs_structs);
+static struct list_head hvcs_structs = LIST_HEAD_INIT(hvcs_structs);
static DEFINE_SPINLOCK(hvcs_structs_lock);
static void hvcs_unthrottle(struct tty_struct *tty);
diff --git a/trunk/drivers/char/hw_random/via-rng.c b/trunk/drivers/char/hw_random/via-rng.c
index f7feae4ebb5e..868e39fd42e4 100644
--- a/trunk/drivers/char/hw_random/via-rng.c
+++ b/trunk/drivers/char/hw_random/via-rng.c
@@ -42,8 +42,6 @@ enum {
VIA_STRFILT_ENABLE = (1 << 14),
VIA_RAWBITS_ENABLE = (1 << 13),
VIA_RNG_ENABLE = (1 << 6),
- VIA_NOISESRC1 = (1 << 8),
- VIA_NOISESRC2 = (1 << 9),
VIA_XSTORE_CNT_MASK = 0x0F,
VIA_RNG_CHUNK_8 = 0x00, /* 64 rand bits, 64 stored bits */
@@ -121,7 +119,6 @@ static int via_rng_data_read(struct hwrng *rng, u32 *data)
static int via_rng_init(struct hwrng *rng)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
u32 lo, hi, old_lo;
/* Control the RNG via MSR. Tread lightly and pay very close
@@ -137,17 +134,6 @@ static int via_rng_init(struct hwrng *rng)
lo &= ~VIA_XSTORE_CNT_MASK;
lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE);
lo |= VIA_RNG_ENABLE;
- lo |= VIA_NOISESRC1;
-
- /* Enable secondary noise source on CPUs where it is present. */
-
- /* Nehemiah stepping 8 and higher */
- if ((c->x86_model == 9) && (c->x86_mask > 7))
- lo |= VIA_NOISESRC2;
-
- /* Esther */
- if (c->x86_model >= 10)
- lo |= VIA_NOISESRC2;
if (lo != old_lo)
wrmsr(MSR_VIA_RNG, lo, hi);
diff --git a/trunk/drivers/char/i8k.c b/trunk/drivers/char/i8k.c
index 179223a17414..30e564516422 100644
--- a/trunk/drivers/char/i8k.c
+++ b/trunk/drivers/char/i8k.c
@@ -439,13 +439,6 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
},
},
- { /* UK Inspiron 6400 */
- .ident = "Dell Inspiron 3",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "MM061"),
- },
- },
{ }
};
diff --git a/trunk/drivers/char/ip27-rtc.c b/trunk/drivers/char/ip27-rtc.c
index 86e6538a77b0..932264a657d0 100644
--- a/trunk/drivers/char/ip27-rtc.c
+++ b/trunk/drivers/char/ip27-rtc.c
@@ -46,8 +46,8 @@
#include
#include
-static long rtc_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg);
+static int rtc_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg);
static int rtc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data);
@@ -75,7 +75,8 @@ static unsigned long epoch = 1970; /* year corresponding to 0x00 */
static const unsigned char days_in_mo[] =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg)
{
struct rtc_time wtime;
@@ -196,7 +197,7 @@ static int rtc_release(struct inode *inode, struct file *file)
static const struct file_operations rtc_fops = {
.owner = THIS_MODULE,
- .unlocked_ioctl = rtc_ioctl,
+ .ioctl = rtc_ioctl,
.open = rtc_open,
.release = rtc_release,
};
diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c
index 32b2b22996dc..5dc1265ce1d5 100644
--- a/trunk/drivers/char/ipmi/ipmi_msghandler.c
+++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c
@@ -365,12 +365,12 @@ static struct device_driver ipmidriver = {
};
static DEFINE_MUTEX(ipmidriver_mutex);
-static LIST_HEAD(ipmi_interfaces);
+static struct list_head ipmi_interfaces = LIST_HEAD_INIT(ipmi_interfaces);
static DEFINE_MUTEX(ipmi_interfaces_mutex);
/* List of watchers that want to know when smi's are added and
deleted. */
-static LIST_HEAD(smi_watchers);
+static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers);
static DEFINE_MUTEX(smi_watchers_mutex);
@@ -441,7 +441,7 @@ struct watcher_entry {
int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
{
ipmi_smi_t intf;
- LIST_HEAD(to_deliver);
+ struct list_head to_deliver = LIST_HEAD_INIT(to_deliver);
struct watcher_entry *e, *e2;
mutex_lock(&smi_watchers_mutex);
diff --git a/trunk/drivers/char/lp.c b/trunk/drivers/char/lp.c
index 60ac642752be..81674d7c56c7 100644
--- a/trunk/drivers/char/lp.c
+++ b/trunk/drivers/char/lp.c
@@ -312,7 +312,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
if (copy_size > LP_BUFFER_SIZE)
copy_size = LP_BUFFER_SIZE;
- if (mutex_lock_interruptible(&lp_table[minor].port_mutex))
+ if (down_interruptible (&lp_table[minor].port_mutex))
return -EINTR;
if (copy_from_user (kbuf, buf, copy_size)) {
@@ -399,7 +399,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
lp_release_parport (&lp_table[minor]);
}
out_unlock:
- mutex_unlock(&lp_table[minor].port_mutex);
+ up (&lp_table[minor].port_mutex);
return retv;
}
@@ -421,7 +421,7 @@ static ssize_t lp_read(struct file * file, char __user * buf,
if (count > LP_BUFFER_SIZE)
count = LP_BUFFER_SIZE;
- if (mutex_lock_interruptible(&lp_table[minor].port_mutex))
+ if (down_interruptible (&lp_table[minor].port_mutex))
return -EINTR;
lp_claim_parport_or_block (&lp_table[minor]);
@@ -479,7 +479,7 @@ static ssize_t lp_read(struct file * file, char __user * buf,
if (retval > 0 && copy_to_user (buf, kbuf, retval))
retval = -EFAULT;
- mutex_unlock(&lp_table[minor].port_mutex);
+ up (&lp_table[minor].port_mutex);
return retval;
}
@@ -888,7 +888,7 @@ static int __init lp_init (void)
lp_table[i].last_error = 0;
init_waitqueue_head (&lp_table[i].waitq);
init_waitqueue_head (&lp_table[i].dataq);
- mutex_init(&lp_table[i].port_mutex);
+ init_MUTEX (&lp_table[i].port_mutex);
lp_table[i].timeout = 10 * HZ;
}
diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c
index 47420787a017..fd0abef7ee08 100644
--- a/trunk/drivers/char/mxser.c
+++ b/trunk/drivers/char/mxser.c
@@ -37,6 +37,7 @@
#include
+#include
#include
#include
#include
diff --git a/trunk/drivers/char/mxser_new.c b/trunk/drivers/char/mxser_new.c
index bf1bee4e1f5e..081c84c7b548 100644
--- a/trunk/drivers/char/mxser_new.c
+++ b/trunk/drivers/char/mxser_new.c
@@ -20,6 +20,7 @@
*/
#include
+#include
#include
#include
#include
diff --git a/trunk/drivers/char/n_tty.c b/trunk/drivers/char/n_tty.c
index 90c3969012a3..596c7173997b 100644
--- a/trunk/drivers/char/n_tty.c
+++ b/trunk/drivers/char/n_tty.c
@@ -695,16 +695,17 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return;
}
+ if (tty->stopped && !tty->flow_stopped &&
+ I_IXON(tty) && I_IXANY(tty)) {
+ start_tty(tty);
+ return;
+ }
+
if (I_ISTRIP(tty))
c &= 0x7f;
if (I_IUCLC(tty) && L_IEXTEN(tty))
c=tolower(c);
- if (tty->stopped && !tty->flow_stopped && I_IXON(tty) &&
- ((I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty)) ||
- c == INTR_CHAR(tty) || c == QUIT_CHAR(tty)))
- start_tty(tty);
-
if (tty->closing) {
if (I_IXON(tty)) {
if (c == START_CHAR(tty))
@@ -768,21 +769,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
signal = SIGTSTP;
if (c == SUSP_CHAR(tty)) {
send_signal:
- /*
- * Echo character, and then send the signal.
- * Note that we do not use isig() here because we want
- * the order to be:
- * 1) flush, 2) echo, 3) signal
- */
- if (!L_NOFLSH(tty)) {
- n_tty_flush_buffer(tty);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- }
- if (L_ECHO(tty))
- echo_char(c, tty);
- if (tty->pgrp)
- kill_pgrp(tty->pgrp, signal, 1);
+ isig(signal, tty, 0);
return;
}
}
diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c
index 279ff5005cec..8caff0ca80ff 100644
--- a/trunk/drivers/char/pcmcia/synclink_cs.c
+++ b/trunk/drivers/char/pcmcia/synclink_cs.c
@@ -57,7 +57,6 @@
#include
#include
#include
-#include
#include
#include
@@ -88,6 +87,8 @@
#include
+#include "linux/synclink.h"
+
static MGSL_PARAMS default_params = {
MGSL_MODE_HDLC, /* unsigned long mode */
0, /* unsigned char loopback; */
diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c
index f43c89f7c449..c511a831f0c0 100644
--- a/trunk/drivers/char/random.c
+++ b/trunk/drivers/char/random.c
@@ -1039,7 +1039,6 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
p += bytes;
add_entropy_words(r, buf, (bytes + 3) / 4);
- cond_resched();
}
return 0;
diff --git a/trunk/drivers/char/riscom8.c b/trunk/drivers/char/riscom8.c
index d130b87d8ed7..102ece4c4e0e 100644
--- a/trunk/drivers/char/riscom8.c
+++ b/trunk/drivers/char/riscom8.c
@@ -47,7 +47,6 @@
#include
#include
#include
-#include
#include
@@ -82,8 +81,6 @@
static struct tty_driver *riscom_driver;
-static DEFINE_SPINLOCK(riscom_lock);
-
static struct riscom_board rc_board[RC_NBOARD] = {
{
.base = RC_IOBASE1,
@@ -220,14 +217,13 @@ static void __init rc_init_CD180(struct riscom_board const * bp)
{
unsigned long flags;
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
rc_out(bp, RC_CTOUT, 0); /* Clear timeout */
rc_wait_CCR(bp); /* Wait for CCR ready */
rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */
- spin_unlock_irqrestore(&riscom_lock, flags);
+ sti();
msleep(50); /* Delay 0.05 sec */
- spin_lock_irqsave(&riscom_lock, flags);
+ cli();
rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */
rc_out(bp, CD180_GICR, 0); /* Clear all bits */
rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */
@@ -238,7 +234,7 @@ static void __init rc_init_CD180(struct riscom_board const * bp)
rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8);
rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff);
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
/* Main probing routine, also sets irq. */
@@ -816,9 +812,9 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
}
port->xmit_buf = (unsigned char *) tmp;
}
-
- spin_lock_irqsave(&riscom_lock, flags);
-
+
+ save_flags(flags); cli();
+
if (port->tty)
clear_bit(TTY_IO_ERROR, &port->tty->flags);
@@ -829,7 +825,7 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
rc_change_speed(bp, port);
port->flags |= ASYNC_INITIALIZED;
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
return 0;
}
@@ -905,7 +901,6 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
int retval;
int do_clocal = 0;
int CD;
- unsigned long flags;
/*
* If the device is in the middle of being closed, then block
@@ -941,26 +936,19 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
*/
retval = 0;
add_wait_queue(&port->open_wait, &wait);
-
- spin_lock_irqsave(&riscom_lock, flags);
-
+ cli();
if (!tty_hung_up_p(filp))
port->count--;
-
- spin_unlock_irqrestore(&riscom_lock, flags);
-
+ sti();
port->blocked_open++;
while (1) {
- spin_lock_irqsave(&riscom_lock, flags);
-
+ cli();
rc_out(bp, CD180_CAR, port_No(port));
CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
rc_out(bp, CD180_MSVR, MSVR_RTS);
bp->DTR &= ~(1u << port_No(port));
rc_out(bp, RC_DTR, bp->DTR);
-
- spin_unlock_irqrestore(&riscom_lock, flags);
-
+ sti();
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
!(port->flags & ASYNC_INITIALIZED)) {
@@ -1032,9 +1020,8 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
if (!port || rc_paranoia_check(port, tty->name, "close"))
return;
-
- spin_lock_irqsave(&riscom_lock, flags);
-
+
+ save_flags(flags); cli();
if (tty_hung_up_p(filp))
goto out;
@@ -1101,9 +1088,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
}
port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
wake_up_interruptible(&port->close_wait);
-
-out:
- spin_unlock_irqrestore(&riscom_lock, flags);
+out: restore_flags(flags);
}
static int rc_write(struct tty_struct * tty,
@@ -1122,33 +1107,34 @@ static int rc_write(struct tty_struct * tty,
if (!tty || !port->xmit_buf)
return 0;
+ save_flags(flags);
while (1) {
- spin_lock_irqsave(&riscom_lock, flags);
-
+ cli();
c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
SERIAL_XMIT_SIZE - port->xmit_head));
- if (c <= 0)
- break; /* lock continues to be held */
+ if (c <= 0) {
+ restore_flags(flags);
+ break;
+ }
memcpy(port->xmit_buf + port->xmit_head, buf, c);
port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
port->xmit_cnt += c;
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
buf += c;
count -= c;
total += c;
}
+ cli();
if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
!(port->IER & IER_TXRDY)) {
port->IER |= IER_TXRDY;
rc_out(bp, CD180_CAR, port_No(port));
rc_out(bp, CD180_IER, port->IER);
}
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
return total;
}
@@ -1164,7 +1150,7 @@ static void rc_put_char(struct tty_struct * tty, unsigned char ch)
if (!tty || !port->xmit_buf)
return;
- spin_lock_irqsave(&riscom_lock, flags);
+ save_flags(flags); cli();
if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
goto out;
@@ -1172,9 +1158,7 @@ static void rc_put_char(struct tty_struct * tty, unsigned char ch)
port->xmit_buf[port->xmit_head++] = ch;
port->xmit_head &= SERIAL_XMIT_SIZE - 1;
port->xmit_cnt++;
-
-out:
- spin_unlock_irqrestore(&riscom_lock, flags);
+out: restore_flags(flags);
}
static void rc_flush_chars(struct tty_struct * tty)
@@ -1189,13 +1173,11 @@ static void rc_flush_chars(struct tty_struct * tty)
!port->xmit_buf)
return;
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
port->IER |= IER_TXRDY;
rc_out(port_Board(port), CD180_CAR, port_No(port));
rc_out(port_Board(port), CD180_IER, port->IER);
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
static int rc_write_room(struct tty_struct * tty)
@@ -1230,11 +1212,9 @@ static void rc_flush_buffer(struct tty_struct *tty)
if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
return;
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
tty_wakeup(tty);
}
@@ -1251,15 +1231,11 @@ static int rc_tiocmget(struct tty_struct *tty, struct file *file)
return -ENODEV;
bp = port_Board(port);
-
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
rc_out(bp, CD180_CAR, port_No(port));
status = rc_in(bp, CD180_MSVR);
result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG;
-
- spin_unlock_irqrestore(&riscom_lock, flags);
-
+ restore_flags(flags);
result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0)
| ((status & MSVR_DTR) ? TIOCM_DTR : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
@@ -1280,8 +1256,7 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file,
bp = port_Board(port);
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
if (set & TIOCM_RTS)
port->MSVR |= MSVR_RTS;
if (set & TIOCM_DTR)
@@ -1295,9 +1270,7 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file,
rc_out(bp, CD180_CAR, port_No(port));
rc_out(bp, CD180_MSVR, port->MSVR);
rc_out(bp, RC_DTR, bp->DTR);
-
- spin_unlock_irqrestore(&riscom_lock, flags);
-
+ restore_flags(flags);
return 0;
}
@@ -1306,8 +1279,7 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length
struct riscom_board *bp = port_Board(port);
unsigned long flags;
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
port->break_length = RISCOM_TPS / HZ * length;
port->COR2 |= COR2_ETC;
port->IER |= IER_TXRDY;
@@ -1317,8 +1289,7 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length
rc_wait_CCR(bp);
rc_out(bp, CD180_CCR, CCR_CORCHG2);
rc_wait_CCR(bp);
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
static inline int rc_set_serial_info(struct riscom_port * port,
@@ -1327,6 +1298,7 @@ static inline int rc_set_serial_info(struct riscom_port * port,
struct serial_struct tmp;
struct riscom_board *bp = port_Board(port);
int change_speed;
+ unsigned long flags;
if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
return -EFAULT;
@@ -1360,11 +1332,9 @@ static inline int rc_set_serial_info(struct riscom_port * port,
port->closing_wait = tmp.closing_wait;
}
if (change_speed) {
- unsigned long flags;
-
- spin_lock_irqsave(&riscom_lock, flags);
+ save_flags(flags); cli();
rc_change_speed(bp, port);
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
return 0;
}
@@ -1444,19 +1414,17 @@ static void rc_throttle(struct tty_struct * tty)
return;
bp = port_Board(port);
-
- spin_lock_irqsave(&riscom_lock, flags);
-
+
+ save_flags(flags); cli();
port->MSVR &= ~MSVR_RTS;
rc_out(bp, CD180_CAR, port_No(port));
- if (I_IXOFF(tty)) {
+ if (I_IXOFF(tty)) {
rc_wait_CCR(bp);
rc_out(bp, CD180_CCR, CCR_SSCH2);
rc_wait_CCR(bp);
}
rc_out(bp, CD180_MSVR, port->MSVR);
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
static void rc_unthrottle(struct tty_struct * tty)
@@ -1470,8 +1438,7 @@ static void rc_unthrottle(struct tty_struct * tty)
bp = port_Board(port);
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
port->MSVR |= MSVR_RTS;
rc_out(bp, CD180_CAR, port_No(port));
if (I_IXOFF(tty)) {
@@ -1480,8 +1447,7 @@ static void rc_unthrottle(struct tty_struct * tty)
rc_wait_CCR(bp);
}
rc_out(bp, CD180_MSVR, port->MSVR);
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
static void rc_stop(struct tty_struct * tty)
@@ -1495,13 +1461,11 @@ static void rc_stop(struct tty_struct * tty)
bp = port_Board(port);
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
port->IER &= ~IER_TXRDY;
rc_out(bp, CD180_CAR, port_No(port));
rc_out(bp, CD180_IER, port->IER);
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
static void rc_start(struct tty_struct * tty)
@@ -1515,15 +1479,13 @@ static void rc_start(struct tty_struct * tty)
bp = port_Board(port);
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags); cli();
if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
port->IER |= IER_TXRDY;
rc_out(bp, CD180_CAR, port_No(port));
rc_out(bp, CD180_IER, port->IER);
}
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
/*
@@ -1575,9 +1537,9 @@ static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termio
tty->termios->c_iflag == old_termios->c_iflag)
return;
- spin_lock_irqsave(&riscom_lock, flags);
+ save_flags(flags); cli();
rc_change_speed(port_Board(port), port);
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
if ((old_termios->c_cflag & CRTSCTS) &&
!(tty->termios->c_cflag & CRTSCTS)) {
@@ -1665,12 +1627,11 @@ static void rc_release_drivers(void)
{
unsigned long flags;
- spin_lock_irqsave(&riscom_lock, flags);
-
+ save_flags(flags);
+ cli();
tty_unregister_driver(riscom_driver);
put_tty_driver(riscom_driver);
-
- spin_unlock_irqrestore(&riscom_lock, flags);
+ restore_flags(flags);
}
#ifndef MODULE
diff --git a/trunk/drivers/char/ser_a2232.c b/trunk/drivers/char/ser_a2232.c
index 4ba3aec9e1cd..3c869145bfdc 100644
--- a/trunk/drivers/char/ser_a2232.c
+++ b/trunk/drivers/char/ser_a2232.c
@@ -653,7 +653,7 @@ static void a2232_init_portstructs(void)
port->gs.closing_wait = 30 * HZ;
port->gs.rd = &a2232_real_driver;
#ifdef NEW_WRITE_LOCKING
- mutex_init(&(port->gs.port_write_mutex));
+ init_MUTEX(&(port->gs.port_write_mutex));
#endif
init_waitqueue_head(&port->gs.open_wait);
init_waitqueue_head(&port->gs.close_wait);
diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c
index ddc74d1f4f1b..d010ed95ed3b 100644
--- a/trunk/drivers/char/synclink.c
+++ b/trunk/drivers/char/synclink.c
@@ -85,7 +85,6 @@
#include
#include
#include
-#include
#include
#include
@@ -111,6 +110,8 @@
#include
+#include "linux/synclink.h"
+
#define RCLRVALUE 0xffff
static MGSL_PARAMS default_params = {
diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c
index 1f954acf2bac..64e835f62438 100644
--- a/trunk/drivers/char/synclink_gt.c
+++ b/trunk/drivers/char/synclink_gt.c
@@ -73,7 +73,6 @@
#include
#include
#include
-#include
#include
#include
@@ -82,6 +81,8 @@
#include
#include
+#include "linux/synclink.h"
+
#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE))
#define SYNCLINK_GENERIC_HDLC 1
#else
@@ -2039,41 +2040,37 @@ static void bh_transmit(struct slgt_info *info)
tty_wakeup(tty);
}
-static void dsr_change(struct slgt_info *info, unsigned short status)
+static void dsr_change(struct slgt_info *info)
{
- if (status & BIT3) {
- info->signals |= SerialSignal_DSR;
- info->input_signal_events.dsr_up++;
- } else {
- info->signals &= ~SerialSignal_DSR;
- info->input_signal_events.dsr_down++;
- }
+ get_signals(info);
DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals));
if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
slgt_irq_off(info, IRQ_DSR);
return;
}
info->icount.dsr++;
+ if (info->signals & SerialSignal_DSR)
+ info->input_signal_events.dsr_up++;
+ else
+ info->input_signal_events.dsr_down++;
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
}
-static void cts_change(struct slgt_info *info, unsigned short status)
+static void cts_change(struct slgt_info *info)
{
- if (status & BIT2) {
- info->signals |= SerialSignal_CTS;
- info->input_signal_events.cts_up++;
- } else {
- info->signals &= ~SerialSignal_CTS;
- info->input_signal_events.cts_down++;
- }
+ get_signals(info);
DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals));
if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
slgt_irq_off(info, IRQ_CTS);
return;
}
info->icount.cts++;
+ if (info->signals & SerialSignal_CTS)
+ info->input_signal_events.cts_up++;
+ else
+ info->input_signal_events.cts_down++;
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
@@ -2094,21 +2091,20 @@ static void cts_change(struct slgt_info *info, unsigned short status)
}
}
-static void dcd_change(struct slgt_info *info, unsigned short status)
+static void dcd_change(struct slgt_info *info)
{
- if (status & BIT1) {
- info->signals |= SerialSignal_DCD;
- info->input_signal_events.dcd_up++;
- } else {
- info->signals &= ~SerialSignal_DCD;
- info->input_signal_events.dcd_down++;
- }
+ get_signals(info);
DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals));
if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
slgt_irq_off(info, IRQ_DCD);
return;
}
info->icount.dcd++;
+ if (info->signals & SerialSignal_DCD) {
+ info->input_signal_events.dcd_up++;
+ } else {
+ info->input_signal_events.dcd_down++;
+ }
#if SYNCLINK_GENERIC_HDLC
if (info->netcount) {
if (info->signals & SerialSignal_DCD)
@@ -2131,21 +2127,20 @@ static void dcd_change(struct slgt_info *info, unsigned short status)
}
}
-static void ri_change(struct slgt_info *info, unsigned short status)
+static void ri_change(struct slgt_info *info)
{
- if (status & BIT0) {
- info->signals |= SerialSignal_RI;
- info->input_signal_events.ri_up++;
- } else {
- info->signals &= ~SerialSignal_RI;
- info->input_signal_events.ri_down++;
- }
+ get_signals(info);
DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals));
if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
slgt_irq_off(info, IRQ_RI);
return;
}
- info->icount.rng++;
+ info->icount.dcd++;
+ if (info->signals & SerialSignal_RI) {
+ info->input_signal_events.ri_up++;
+ } else {
+ info->input_signal_events.ri_down++;
+ }
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
@@ -2196,13 +2191,13 @@ static void isr_serial(struct slgt_info *info)
}
if (status & IRQ_DSR)
- dsr_change(info, status);
+ dsr_change(info);
if (status & IRQ_CTS)
- cts_change(info, status);
+ cts_change(info);
if (status & IRQ_DCD)
- dcd_change(info, status);
+ dcd_change(info);
if (status & IRQ_RI)
- ri_change(info, status);
+ ri_change(info);
}
static void isr_rdma(struct slgt_info *info)
diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c
index f3e7807f78d9..c63013b2fc36 100644
--- a/trunk/drivers/char/synclinkmp.c
+++ b/trunk/drivers/char/synclinkmp.c
@@ -66,7 +66,6 @@
#include
#include
#include
-#include
#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE))
#define SYNCLINK_GENERIC_HDLC 1
@@ -81,6 +80,8 @@
#include
+#include "linux/synclink.h"
+
static MGSL_PARAMS default_params = {
MGSL_MODE_HDLC, /* unsigned long mode */
0, /* unsigned char loopback; */
diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c
index a5d8bcb40000..c88424a0c89b 100644
--- a/trunk/drivers/char/tpm/tpm.c
+++ b/trunk/drivers/char/tpm/tpm.c
@@ -1031,13 +1031,18 @@ void tpm_remove_hardware(struct device *dev)
spin_unlock(&driver_lock);
+ dev_set_drvdata(dev, NULL);
misc_deregister(&chip->vendor.miscdev);
+ kfree(chip->vendor.miscdev.name);
sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
tpm_bios_log_teardown(chip->bios_dir);
- /* write it this way to be explicit (chip->dev == dev) */
- put_device(chip->dev);
+ clear_bit(chip->dev_num, dev_mask);
+
+ kfree(chip);
+
+ put_device(dev);
}
EXPORT_SYMBOL_GPL(tpm_remove_hardware);
@@ -1077,26 +1082,6 @@ int tpm_pm_resume(struct device *dev)
}
EXPORT_SYMBOL_GPL(tpm_pm_resume);
-/*
- * Once all references to platform device are down to 0,
- * release all allocated structures.
- * In case vendor provided release function,
- * call it too.
- */
-static void tpm_dev_release(struct device *dev)
-{
- struct tpm_chip *chip = dev_get_drvdata(dev);
-
- if (chip->vendor.release)
- chip->vendor.release(dev);
-
- chip->release(dev);
-
- clear_bit(chip->dev_num, dev_mask);
- kfree(chip->vendor.miscdev.name);
- kfree(chip);
-}
-
/*
* Called from tpm_.c probe function only for devices
* the driver has determined it should claim. Prior to calling
@@ -1151,21 +1136,23 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
chip->vendor.miscdev.parent = dev;
chip->dev = get_device(dev);
- chip->release = dev->release;
- dev->release = tpm_dev_release;
- dev_set_drvdata(dev, chip);
if (misc_register(&chip->vendor.miscdev)) {
dev_err(chip->dev,
"unable to misc_register %s, minor %d\n",
chip->vendor.miscdev.name,
chip->vendor.miscdev.minor);
- put_device(chip->dev);
+ put_device(dev);
+ clear_bit(chip->dev_num, dev_mask);
+ kfree(chip);
+ kfree(devname);
return NULL;
}
spin_lock(&driver_lock);
+ dev_set_drvdata(dev, chip);
+
list_add(&chip->list, &tpm_chip_list);
spin_unlock(&driver_lock);
@@ -1173,7 +1160,10 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
list_del(&chip->list);
misc_deregister(&chip->vendor.miscdev);
- put_device(chip->dev);
+ put_device(dev);
+ clear_bit(chip->dev_num, dev_mask);
+ kfree(chip);
+ kfree(devname);
return NULL;
}
diff --git a/trunk/drivers/char/tpm/tpm.h b/trunk/drivers/char/tpm/tpm.h
index e885148b4cfb..d15ccddc92eb 100644
--- a/trunk/drivers/char/tpm/tpm.h
+++ b/trunk/drivers/char/tpm/tpm.h
@@ -74,7 +74,6 @@ struct tpm_vendor_specific {
int (*send) (struct tpm_chip *, u8 *, size_t);
void (*cancel) (struct tpm_chip *);
u8 (*status) (struct tpm_chip *);
- void (*release) (struct device *);
struct miscdevice miscdev;
struct attribute_group *attr_group;
struct list_head list;
@@ -107,7 +106,6 @@ struct tpm_chip {
struct dentry **bios_dir;
struct list_head list;
- void (*release) (struct device *);
};
#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
diff --git a/trunk/drivers/char/tpm/tpm_infineon.c b/trunk/drivers/char/tpm/tpm_infineon.c
index 726ee8a0277f..967002a5a1e5 100644
--- a/trunk/drivers/char/tpm/tpm_infineon.c
+++ b/trunk/drivers/char/tpm/tpm_infineon.c
@@ -611,7 +611,7 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
}
}
-static struct pnp_driver tpm_inf_pnp_driver = {
+static struct pnp_driver tpm_inf_pnp = {
.name = "tpm_inf_pnp",
.driver = {
.owner = THIS_MODULE,
@@ -625,12 +625,12 @@ static struct pnp_driver tpm_inf_pnp_driver = {
static int __init init_inf(void)
{
- return pnp_register_driver(&tpm_inf_pnp_driver);
+ return pnp_register_driver(&tpm_inf_pnp);
}
static void __exit cleanup_inf(void)
{
- pnp_unregister_driver(&tpm_inf_pnp_driver);
+ pnp_unregister_driver(&tpm_inf_pnp);
}
module_init(init_inf);
diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c
index 79c86c47947f..f36fecd3fd26 100644
--- a/trunk/drivers/char/tty_io.c
+++ b/trunk/drivers/char/tty_io.c
@@ -138,7 +138,7 @@ EXPORT_SYMBOL(tty_mutex);
extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
extern int pty_limit; /* Config limit on Unix98 ptys */
static DEFINE_IDR(allocated_ptys);
-static DEFINE_MUTEX(allocated_ptys_lock);
+static DECLARE_MUTEX(allocated_ptys_lock);
static int ptmx_open(struct inode *, struct file *);
#endif
@@ -2571,9 +2571,9 @@ static void release_dev(struct file * filp)
#ifdef CONFIG_UNIX98_PTYS
/* Make this pty number available for reallocation */
if (devpts) {
- mutex_lock(&allocated_ptys_lock);
+ down(&allocated_ptys_lock);
idr_remove(&allocated_ptys, idx);
- mutex_unlock(&allocated_ptys_lock);
+ up(&allocated_ptys_lock);
}
#endif
@@ -2737,24 +2737,24 @@ static int ptmx_open(struct inode * inode, struct file * filp)
nonseekable_open(inode, filp);
/* find a device that is not in use. */
- mutex_lock(&allocated_ptys_lock);
+ down(&allocated_ptys_lock);
if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) {
- mutex_unlock(&allocated_ptys_lock);
+ up(&allocated_ptys_lock);
return -ENOMEM;
}
idr_ret = idr_get_new(&allocated_ptys, NULL, &index);
if (idr_ret < 0) {
- mutex_unlock(&allocated_ptys_lock);
+ up(&allocated_ptys_lock);
if (idr_ret == -EAGAIN)
return -ENOMEM;
return -EIO;
}
if (index >= pty_limit) {
idr_remove(&allocated_ptys, index);
- mutex_unlock(&allocated_ptys_lock);
+ up(&allocated_ptys_lock);
return -EIO;
}
- mutex_unlock(&allocated_ptys_lock);
+ up(&allocated_ptys_lock);
mutex_lock(&tty_mutex);
retval = init_dev(ptm_driver, index, &tty);
@@ -2781,9 +2781,9 @@ static int ptmx_open(struct inode * inode, struct file * filp)
release_dev(filp);
return retval;
out:
- mutex_lock(&allocated_ptys_lock);
+ down(&allocated_ptys_lock);
idr_remove(&allocated_ptys, index);
- mutex_unlock(&allocated_ptys_lock);
+ up(&allocated_ptys_lock);
return retval;
}
#endif
@@ -3721,6 +3721,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
tty->buf.head = tty->buf.tail = NULL;
tty_buffer_init(tty);
INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc);
+ init_MUTEX(&tty->buf.pty_sem);
mutex_init(&tty->termios_mutex);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
@@ -4047,6 +4048,10 @@ void __init console_init(void)
}
}
+#ifdef CONFIG_VT
+extern int vty_init(void);
+#endif
+
static int __init tty_class_init(void)
{
tty_class = class_create(THIS_MODULE, "tty");
diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c
index 367be9175061..7a5badfb7d84 100644
--- a/trunk/drivers/char/vt.c
+++ b/trunk/drivers/char/vt.c
@@ -2400,15 +2400,13 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
{
struct vc_data *vc = vc_cons[fg_console].d;
unsigned char c;
- static DEFINE_SPINLOCK(printing_lock);
+ static unsigned long printing;
const ushort *start;
ushort cnt = 0;
ushort myx;
/* console busy or not yet initialized */
- if (!printable)
- return;
- if (!spin_trylock(&printing_lock))
+ if (!printable || test_and_set_bit(0, &printing))
return;
if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
@@ -2483,7 +2481,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
notify_update(vc);
quit:
- spin_unlock(&printing_lock);
+ clear_bit(0, &printing);
}
static struct tty_driver *vt_console_device(struct console *c, int *index)
diff --git a/trunk/drivers/firmware/dcdbas.c b/trunk/drivers/firmware/dcdbas.c
index 1636806ec55e..18cdcb3ae1ca 100644
--- a/trunk/drivers/firmware/dcdbas.c
+++ b/trunk/drivers/firmware/dcdbas.c
@@ -658,5 +658,4 @@ MODULE_DESCRIPTION(DRIVER_DESCRIPTION " (version " DRIVER_VERSION ")");
MODULE_VERSION(DRIVER_VERSION);
MODULE_AUTHOR("Dell Inc.");
MODULE_LICENSE("GPL");
-/* Any System or BIOS claiming to be by Dell */
-MODULE_ALIAS("dmi:*:[bs]vnD[Ee][Ll][Ll]*:*");
+
diff --git a/trunk/drivers/firmware/dmi-id.c b/trunk/drivers/firmware/dmi-id.c
index e880d6c8d896..313c99cbdc62 100644
--- a/trunk/drivers/firmware/dmi-id.c
+++ b/trunk/drivers/firmware/dmi-id.c
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
struct dmi_device_attribute{
struct device_attribute dev_attr;
diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig
index bbd28342e771..74fac0f5c348 100644
--- a/trunk/drivers/gpio/Kconfig
+++ b/trunk/drivers/gpio/Kconfig
@@ -27,16 +27,15 @@ config DEBUG_GPIO
comment "I2C GPIO expanders:"
-config GPIO_PCA953X
- tristate "PCA953x I/O ports"
+config GPIO_PCA9539
+ tristate "PCA9539 16-bit I/O port"
depends on I2C
help
- Say yes here to support the PCA9534 (8-bit), PCA9535 (16-bit),
- PCA9536 (4-bit), PCA9537 (4-bit), PCA9538 (8-bit), and PCA9539
- (16-bit) I/O ports. These parts are made by NXP and TI.
+ Say yes here to support the PCA9539 16-bit I/O port. These
+ parts are made by NXP and TI.
This driver can also be built as a module. If so, the module
- will be called pca953x.
+ will be called pca9539.
config GPIO_PCF857X
tristate "PCF857x, PCA857x, and PCA967x I2C GPIO expanders"
diff --git a/trunk/drivers/gpio/Makefile b/trunk/drivers/gpio/Makefile
index fdde9923cf33..470ecd6aa778 100644
--- a/trunk/drivers/gpio/Makefile
+++ b/trunk/drivers/gpio/Makefile
@@ -5,5 +5,5 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o
obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
-obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
+obj-$(CONFIG_GPIO_PCA9539) += pca9539.o
obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
diff --git a/trunk/drivers/gpio/pca9539.c b/trunk/drivers/gpio/pca9539.c
new file mode 100644
index 000000000000..3e85c92a7d59
--- /dev/null
+++ b/trunk/drivers/gpio/pca9539.c
@@ -0,0 +1,271 @@
+/*
+ * pca9539.c - 16-bit I/O port with interrupt and reset
+ *
+ * Copyright (C) 2005 Ben Gardner
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * Derived from drivers/i2c/chips/pca9539.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; version 2 of the License.
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+
+
+#define NR_PCA9539_GPIOS 16
+
+#define PCA9539_INPUT 0
+#define PCA9539_OUTPUT 2
+#define PCA9539_INVERT 4
+#define PCA9539_DIRECTION 6
+
+struct pca9539_chip {
+ unsigned gpio_start;
+ uint16_t reg_output;
+ uint16_t reg_direction;
+
+ struct i2c_client *client;
+ struct gpio_chip gpio_chip;
+};
+
+/* NOTE: we can't currently rely on fault codes to come from SMBus
+ * calls, so we map all errors to EIO here and return zero otherwise.
+ */
+static int pca9539_write_reg(struct pca9539_chip *chip, int reg, uint16_t val)
+{
+ if (i2c_smbus_write_word_data(chip->client, reg, val) < 0)
+ return -EIO;
+ else
+ return 0;
+}
+
+static int pca9539_read_reg(struct pca9539_chip *chip, int reg, uint16_t *val)
+{
+ int ret;
+
+ ret = i2c_smbus_read_word_data(chip->client, reg);
+ if (ret < 0) {
+ dev_err(&chip->client->dev, "failed reading register\n");
+ return -EIO;
+ }
+
+ *val = (uint16_t)ret;
+ return 0;
+}
+
+static int pca9539_gpio_direction_input(struct gpio_chip *gc, unsigned off)
+{
+ struct pca9539_chip *chip;
+ uint16_t reg_val;
+ int ret;
+
+ chip = container_of(gc, struct pca9539_chip, gpio_chip);
+
+ reg_val = chip->reg_direction | (1u << off);
+ ret = pca9539_write_reg(chip, PCA9539_DIRECTION, reg_val);
+ if (ret)
+ return ret;
+
+ chip->reg_direction = reg_val;
+ return 0;
+}
+
+static int pca9539_gpio_direction_output(struct gpio_chip *gc,
+ unsigned off, int val)
+{
+ struct pca9539_chip *chip;
+ uint16_t reg_val;
+ int ret;
+
+ chip = container_of(gc, struct pca9539_chip, gpio_chip);
+
+ /* set output level */
+ if (val)
+ reg_val = chip->reg_output | (1u << off);
+ else
+ reg_val = chip->reg_output & ~(1u << off);
+
+ ret = pca9539_write_reg(chip, PCA9539_OUTPUT, reg_val);
+ if (ret)
+ return ret;
+
+ chip->reg_output = reg_val;
+
+ /* then direction */
+ reg_val = chip->reg_direction & ~(1u << off);
+ ret = pca9539_write_reg(chip, PCA9539_DIRECTION, reg_val);
+ if (ret)
+ return ret;
+
+ chip->reg_direction = reg_val;
+ return 0;
+}
+
+static int pca9539_gpio_get_value(struct gpio_chip *gc, unsigned off)
+{
+ struct pca9539_chip *chip;
+ uint16_t reg_val;
+ int ret;
+
+ chip = container_of(gc, struct pca9539_chip, gpio_chip);
+
+ ret = pca9539_read_reg(chip, PCA9539_INPUT, ®_val);
+ if (ret < 0) {
+ /* NOTE: diagnostic already emitted; that's all we should
+ * do unless gpio_*_value_cansleep() calls become different
+ * from their nonsleeping siblings (and report faults).
+ */
+ return 0;
+ }
+
+ return (reg_val & (1u << off)) ? 1 : 0;
+}
+
+static void pca9539_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
+{
+ struct pca9539_chip *chip;
+ uint16_t reg_val;
+ int ret;
+
+ chip = container_of(gc, struct pca9539_chip, gpio_chip);
+
+ if (val)
+ reg_val = chip->reg_output | (1u << off);
+ else
+ reg_val = chip->reg_output & ~(1u << off);
+
+ ret = pca9539_write_reg(chip, PCA9539_OUTPUT, reg_val);
+ if (ret)
+ return;
+
+ chip->reg_output = reg_val;
+}
+
+static int pca9539_init_gpio(struct pca9539_chip *chip)
+{
+ struct gpio_chip *gc;
+
+ gc = &chip->gpio_chip;
+
+ gc->direction_input = pca9539_gpio_direction_input;
+ gc->direction_output = pca9539_gpio_direction_output;
+ gc->get = pca9539_gpio_get_value;
+ gc->set = pca9539_gpio_set_value;
+
+ gc->base = chip->gpio_start;
+ gc->ngpio = NR_PCA9539_GPIOS;
+ gc->label = "pca9539";
+
+ return gpiochip_add(gc);
+}
+
+static int __devinit pca9539_probe(struct i2c_client *client)
+{
+ struct pca9539_platform_data *pdata;
+ struct pca9539_chip *chip;
+ int ret;
+
+ pdata = client->dev.platform_data;
+ if (pdata == NULL)
+ return -ENODEV;
+
+ chip = kzalloc(sizeof(struct pca9539_chip), GFP_KERNEL);
+ if (chip == NULL)
+ return -ENOMEM;
+
+ chip->client = client;
+
+ chip->gpio_start = pdata->gpio_base;
+
+ /* initialize cached registers from their original values.
+ * we can't share this chip with another i2c master.
+ */
+ ret = pca9539_read_reg(chip, PCA9539_OUTPUT, &chip->reg_output);
+ if (ret)
+ goto out_failed;
+
+ ret = pca9539_read_reg(chip, PCA9539_DIRECTION, &chip->reg_direction);
+ if (ret)
+ goto out_failed;
+
+ /* set platform specific polarity inversion */
+ ret = pca9539_write_reg(chip, PCA9539_INVERT, pdata->invert);
+ if (ret)
+ goto out_failed;
+
+ ret = pca9539_init_gpio(chip);
+ if (ret)
+ goto out_failed;
+
+ if (pdata->setup) {
+ ret = pdata->setup(client, chip->gpio_chip.base,
+ chip->gpio_chip.ngpio, pdata->context);
+ if (ret < 0)
+ dev_warn(&client->dev, "setup failed, %d\n", ret);
+ }
+
+ i2c_set_clientdata(client, chip);
+ return 0;
+
+out_failed:
+ kfree(chip);
+ return ret;
+}
+
+static int pca9539_remove(struct i2c_client *client)
+{
+ struct pca9539_platform_data *pdata = client->dev.platform_data;
+ struct pca9539_chip *chip = i2c_get_clientdata(client);
+ int ret = 0;
+
+ if (pdata->teardown) {
+ ret = pdata->teardown(client, chip->gpio_chip.base,
+ chip->gpio_chip.ngpio, pdata->context);
+ if (ret < 0) {
+ dev_err(&client->dev, "%s failed, %d\n",
+ "teardown", ret);
+ return ret;
+ }
+ }
+
+ ret = gpiochip_remove(&chip->gpio_chip);
+ if (ret) {
+ dev_err(&client->dev, "%s failed, %d\n",
+ "gpiochip_remove()", ret);
+ return ret;
+ }
+
+ kfree(chip);
+ return 0;
+}
+
+static struct i2c_driver pca9539_driver = {
+ .driver = {
+ .name = "pca9539",
+ },
+ .probe = pca9539_probe,
+ .remove = pca9539_remove,
+};
+
+static int __init pca9539_init(void)
+{
+ return i2c_add_driver(&pca9539_driver);
+}
+module_init(pca9539_init);
+
+static void __exit pca9539_exit(void)
+{
+ i2c_del_driver(&pca9539_driver);
+}
+module_exit(pca9539_exit);
+
+MODULE_AUTHOR("eric miao ");
+MODULE_DESCRIPTION("GPIO expander driver for PCA9539");
+MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/gpio/pca953x.c b/trunk/drivers/gpio/pca953x.c
deleted file mode 100644
index 92583cd4bffd..000000000000
--- a/trunk/drivers/gpio/pca953x.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * pca953x.c - 4/8/16 bit I/O ports
- *
- * Copyright (C) 2005 Ben Gardner
- * Copyright (C) 2007 Marvell International Ltd.
- *
- * Derived from drivers/i2c/chips/pca9539.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; version 2 of the License.
- */
-
-#include
-#include
-#include
-#include
-
-#include
-
-#define PCA953X_INPUT 0
-#define PCA953X_OUTPUT 1
-#define PCA953X_INVERT 2
-#define PCA953X_DIRECTION 3
-
-/* This is temporary - in 2.6.26 i2c_driver_data should replace it. */
-struct pca953x_desc {
- char name[I2C_NAME_SIZE];
- unsigned long driver_data;
-};
-
-static const struct pca953x_desc pca953x_descs[] = {
- { "pca9534", 8, },
- { "pca9535", 16, },
- { "pca9536", 4, },
- { "pca9537", 4, },
- { "pca9538", 8, },
- { "pca9539", 16, },
- /* REVISIT several pca955x parts should work here too */
-};
-
-struct pca953x_chip {
- unsigned gpio_start;
- uint16_t reg_output;
- uint16_t reg_direction;
-
- struct i2c_client *client;
- struct gpio_chip gpio_chip;
-};
-
-/* NOTE: we can't currently rely on fault codes to come from SMBus
- * calls, so we map all errors to EIO here and return zero otherwise.
- */
-static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
-{
- int ret;
-
- if (chip->gpio_chip.ngpio <= 8)
- ret = i2c_smbus_write_byte_data(chip->client, reg, val);
- else
- ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);
-
- if (ret < 0) {
- dev_err(&chip->client->dev, "failed writing register\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val)
-{
- int ret;
-
- if (chip->gpio_chip.ngpio <= 8)
- ret = i2c_smbus_read_byte_data(chip->client, reg);
- else
- ret = i2c_smbus_read_word_data(chip->client, reg << 1);
-
- if (ret < 0) {
- dev_err(&chip->client->dev, "failed reading register\n");
- return -EIO;
- }
-
- *val = (uint16_t)ret;
- return 0;
-}
-
-static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
-{
- struct pca953x_chip *chip;
- uint16_t reg_val;
- int ret;
-
- chip = container_of(gc, struct pca953x_chip, gpio_chip);
-
- reg_val = chip->reg_direction | (1u << off);
- ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
- if (ret)
- return ret;
-
- chip->reg_direction = reg_val;
- return 0;
-}
-
-static int pca953x_gpio_direction_output(struct gpio_chip *gc,
- unsigned off, int val)
-{
- struct pca953x_chip *chip;
- uint16_t reg_val;
- int ret;
-
- chip = container_of(gc, struct pca953x_chip, gpio_chip);
-
- /* set output level */
- if (val)
- reg_val = chip->reg_output | (1u << off);
- else
- reg_val = chip->reg_output & ~(1u << off);
-
- ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
- if (ret)
- return ret;
-
- chip->reg_output = reg_val;
-
- /* then direction */
- reg_val = chip->reg_direction & ~(1u << off);
- ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
- if (ret)
- return ret;
-
- chip->reg_direction = reg_val;
- return 0;
-}
-
-static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
-{
- struct pca953x_chip *chip;
- uint16_t reg_val;
- int ret;
-
- chip = container_of(gc, struct pca953x_chip, gpio_chip);
-
- ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val);
- if (ret < 0) {
- /* NOTE: diagnostic already emitted; that's all we should
- * do unless gpio_*_value_cansleep() calls become different
- * from their nonsleeping siblings (and report faults).
- */
- return 0;
- }
-
- return (reg_val & (1u << off)) ? 1 : 0;
-}
-
-static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
-{
- struct pca953x_chip *chip;
- uint16_t reg_val;
- int ret;
-
- chip = container_of(gc, struct pca953x_chip, gpio_chip);
-
- if (val)
- reg_val = chip->reg_output | (1u << off);
- else
- reg_val = chip->reg_output & ~(1u << off);
-
- ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
- if (ret)
- return;
-
- chip->reg_output = reg_val;
-}
-
-static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
-{
- struct gpio_chip *gc;
-
- gc = &chip->gpio_chip;
-
- gc->direction_input = pca953x_gpio_direction_input;
- gc->direction_output = pca953x_gpio_direction_output;
- gc->get = pca953x_gpio_get_value;
- gc->set = pca953x_gpio_set_value;
-
- gc->base = chip->gpio_start;
- gc->ngpio = gpios;
- gc->label = chip->client->name;
-}
-
-static int __devinit pca953x_probe(struct i2c_client *client)
-{
- struct pca953x_platform_data *pdata;
- struct pca953x_chip *chip;
- int ret, i;
- const struct pca953x_desc *id = NULL;
-
- pdata = client->dev.platform_data;
- if (pdata == NULL)
- return -ENODEV;
-
- /* this loop vanishes when we get i2c_device_id */
- for (i = 0; i < ARRAY_SIZE(pca953x_descs); i++)
- if (!strcmp(pca953x_descs[i].name, client->name)) {
- id = pca953x_descs + i;
- break;
- }
- if (!id)
- return -ENODEV;
-
- chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
- chip->client = client;
-
- chip->gpio_start = pdata->gpio_base;
-
- /* initialize cached registers from their original values.
- * we can't share this chip with another i2c master.
- */
- pca953x_setup_gpio(chip, id->driver_data);
-
- ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
- if (ret)
- goto out_failed;
-
- ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction);
- if (ret)
- goto out_failed;
-
- /* set platform specific polarity inversion */
- ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert);
- if (ret)
- goto out_failed;
-
-
- ret = gpiochip_add(&chip->gpio_chip);
- if (ret)
- goto out_failed;
-
- if (pdata->setup) {
- ret = pdata->setup(client, chip->gpio_chip.base,
- chip->gpio_chip.ngpio, pdata->context);
- if (ret < 0)
- dev_warn(&client->dev, "setup failed, %d\n", ret);
- }
-
- i2c_set_clientdata(client, chip);
- return 0;
-
-out_failed:
- kfree(chip);
- return ret;
-}
-
-static int pca953x_remove(struct i2c_client *client)
-{
- struct pca953x_platform_data *pdata = client->dev.platform_data;
- struct pca953x_chip *chip = i2c_get_clientdata(client);
- int ret = 0;
-
- if (pdata->teardown) {
- ret = pdata->teardown(client, chip->gpio_chip.base,
- chip->gpio_chip.ngpio, pdata->context);
- if (ret < 0) {
- dev_err(&client->dev, "%s failed, %d\n",
- "teardown", ret);
- return ret;
- }
- }
-
- ret = gpiochip_remove(&chip->gpio_chip);
- if (ret) {
- dev_err(&client->dev, "%s failed, %d\n",
- "gpiochip_remove()", ret);
- return ret;
- }
-
- kfree(chip);
- return 0;
-}
-
-static struct i2c_driver pca953x_driver = {
- .driver = {
- .name = "pca953x",
- },
- .probe = pca953x_probe,
- .remove = pca953x_remove,
-};
-
-static int __init pca953x_init(void)
-{
- return i2c_add_driver(&pca953x_driver);
-}
-module_init(pca953x_init);
-
-static void __exit pca953x_exit(void)
-{
- i2c_del_driver(&pca953x_driver);
-}
-module_exit(pca953x_exit);
-
-MODULE_AUTHOR("eric miao ");
-MODULE_DESCRIPTION("GPIO expander driver for PCA953x");
-MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c
index 6daea896c5db..fd0ef8268950 100644
--- a/trunk/drivers/ide/ide-probe.c
+++ b/trunk/drivers/ide/ide-probe.c
@@ -1049,7 +1049,7 @@ static int init_irq (ide_hwif_t *hwif)
*/
if (!match || match->irq != hwif->irq) {
int sa = 0;
-#if defined(__mc68000__)
+#if defined(__mc68000__) || defined(CONFIG_APUS)
sa = IRQF_SHARED;
#endif /* __mc68000__ || CONFIG_APUS */
@@ -1072,7 +1072,7 @@ static int init_irq (ide_hwif_t *hwif)
hwif->rqsize = 65536;
}
-#if !defined(__mc68000__)
+#if !defined(__mc68000__) && !defined(CONFIG_APUS)
printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
hwif->io_ports[IDE_DATA_OFFSET],
hwif->io_ports[IDE_DATA_OFFSET]+7,
@@ -1080,7 +1080,7 @@ static int init_irq (ide_hwif_t *hwif)
#else
printk("%s at 0x%08lx on irq %d", hwif->name,
hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);
-#endif /* __mc68000__ */
+#endif /* __mc68000__ && CONFIG_APUS */
if (match)
printk(" (%sed with %s)",
hwif->sharing_irq ? "shar" : "serializ", match->name);
diff --git a/trunk/drivers/input/touchscreen/h3600_ts_input.c b/trunk/drivers/input/touchscreen/h3600_ts_input.c
index 28ae15ed12c5..2ae6c6016a86 100644
--- a/trunk/drivers/input/touchscreen/h3600_ts_input.c
+++ b/trunk/drivers/input/touchscreen/h3600_ts_input.c
@@ -109,7 +109,7 @@ struct h3600_dev {
static irqreturn_t action_button_handler(int irq, void *dev_id)
{
int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
- struct input_dev *dev = dev_id;
+ struct input_dev *dev = (struct input_dev *) dev_id;
input_report_key(dev, KEY_ENTER, down);
input_sync(dev);
@@ -120,7 +120,7 @@ static irqreturn_t action_button_handler(int irq, void *dev_id)
static irqreturn_t npower_button_handler(int irq, void *dev_id)
{
int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
- struct input_dev *dev = dev_id;
+ struct input_dev *dev = (struct input_dev *) dev_id;
/*
* This interrupt is only called when we release the key. So we have
diff --git a/trunk/drivers/isdn/act2000/module.c b/trunk/drivers/isdn/act2000/module.c
index 8325022e2bed..ee2b0b9f8f46 100644
--- a/trunk/drivers/isdn/act2000/module.c
+++ b/trunk/drivers/isdn/act2000/module.c
@@ -310,7 +310,7 @@ act2000_command(act2000_card * card, isdn_ctrl * c)
}
break;
case ISDN_CMD_DIAL:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
if (!(chan = find_channel(card, c->arg & 0x0f)))
break;
@@ -339,7 +339,7 @@ act2000_command(act2000_card * card, isdn_ctrl * c)
}
return ret;
case ISDN_CMD_ACCEPTD:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
if (!(chan = find_channel(card, c->arg & 0x0f)))
break;
@@ -347,11 +347,11 @@ act2000_command(act2000_card * card, isdn_ctrl * c)
actcapi_select_b2_protocol_req(card, chan);
return 0;
case ISDN_CMD_ACCEPTB:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
return 0;
case ISDN_CMD_HANGUP:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
if (!(chan = find_channel(card, c->arg & 0x0f)))
break;
@@ -366,7 +366,7 @@ act2000_command(act2000_card * card, isdn_ctrl * c)
}
return 0;
case ISDN_CMD_SETEAZ:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
if (!(chan = find_channel(card, c->arg & 0x0f)))
break;
@@ -386,7 +386,7 @@ act2000_command(act2000_card * card, isdn_ctrl * c)
actcapi_listen_req(card);
return 0;
case ISDN_CMD_CLREAZ:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
if (!(chan = find_channel(card, c->arg & 0x0f)))
break;
@@ -394,14 +394,14 @@ act2000_command(act2000_card * card, isdn_ctrl * c)
actcapi_listen_req(card);
return 0;
case ISDN_CMD_SETL2:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
if (!(chan = find_channel(card, c->arg & 0x0f)))
break;
chan->l2prot = (c->arg >> 8);
return 0;
case ISDN_CMD_SETL3:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) {
printk(KERN_WARNING "L3 protocol unknown\n");
@@ -524,7 +524,7 @@ if_writecmd(const u_char __user *buf, int len, int id, int channel)
act2000_card *card = act2000_findcard(id);
if (card) {
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
return (len);
}
@@ -539,7 +539,7 @@ if_readstatus(u_char __user * buf, int len, int id, int channel)
act2000_card *card = act2000_findcard(id);
if (card) {
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
return (act2000_readstatus(buf, len, card));
}
@@ -554,7 +554,7 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
act2000_card *card = act2000_findcard(id);
if (card) {
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
+ if (!card->flags & ACT2000_FLAGS_RUNNING)
return -ENODEV;
return (act2000_sendbuf(card, channel, ack, skb));
}
diff --git a/trunk/drivers/isdn/gigaset/asyncdata.c b/trunk/drivers/isdn/gigaset/asyncdata.c
index 091deb9d1c47..00a3be5b862b 100644
--- a/trunk/drivers/isdn/gigaset/asyncdata.c
+++ b/trunk/drivers/isdn/gigaset/asyncdata.c
@@ -350,8 +350,8 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
unsigned char *src, c;
int procbytes;
- head = inbuf->head;
- tail = inbuf->tail;
+ head = atomic_read(&inbuf->head);
+ tail = atomic_read(&inbuf->tail);
gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
if (head != tail) {
@@ -361,7 +361,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
while (numbytes) {
- if (cs->mstate == MS_LOCKED) {
+ if (atomic_read(&cs->mstate) == MS_LOCKED) {
procbytes = lock_loop(src, numbytes, inbuf);
src += procbytes;
numbytes -= procbytes;
@@ -436,7 +436,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
}
gig_dbg(DEBUG_INTR, "setting head to %u", head);
- inbuf->head = head;
+ atomic_set(&inbuf->head, head);
}
}
EXPORT_SYMBOL_GPL(gigaset_m10x_input);
diff --git a/trunk/drivers/isdn/gigaset/bas-gigaset.c b/trunk/drivers/isdn/gigaset/bas-gigaset.c
index 5255b5e20e13..af7648274b38 100644
--- a/trunk/drivers/isdn/gigaset/bas-gigaset.c
+++ b/trunk/drivers/isdn/gigaset/bas-gigaset.c
@@ -73,14 +73,6 @@ static int gigaset_probe(struct usb_interface *interface,
/* Function will be called if the device is unplugged */
static void gigaset_disconnect(struct usb_interface *interface);
-/* functions called before/after suspend */
-static int gigaset_suspend(struct usb_interface *intf, pm_message_t message);
-static int gigaset_resume(struct usb_interface *intf);
-
-/* functions called before/after device reset */
-static int gigaset_pre_reset(struct usb_interface *intf);
-static int gigaset_post_reset(struct usb_interface *intf);
-
static int atread_submit(struct cardstate *, int);
static void stopurbs(struct bas_bc_state *);
static int req_submit(struct bc_state *, int, int, int);
@@ -113,9 +105,8 @@ struct bas_cardstate {
unsigned char int_in_buf[3];
spinlock_t lock; /* locks all following */
- int basstate; /* bitmap (BS_*) */
+ atomic_t basstate; /* bitmap (BS_*) */
int pending; /* uncompleted base request */
- wait_queue_head_t waitqueue;
int rcvbuf_size; /* size of AT receive buffer */
/* 0: no receive in progress */
int retry_cmd_in; /* receive req retry count */
@@ -130,10 +121,10 @@ struct bas_cardstate {
#define BS_ATTIMER 0x020 /* waiting for HD_READY_SEND_ATDATA */
#define BS_ATRDPEND 0x040 /* urb_cmd_in in use */
#define BS_ATWRPEND 0x080 /* urb_cmd_out in use */
-#define BS_SUSPEND 0x100 /* USB port suspended */
static struct gigaset_driver *driver = NULL;
+static struct cardstate *cardstate = NULL;
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver gigaset_usb_driver = {
@@ -141,11 +132,6 @@ static struct usb_driver gigaset_usb_driver = {
.probe = gigaset_probe,
.disconnect = gigaset_disconnect,
.id_table = gigaset_table,
- .suspend = gigaset_suspend,
- .resume = gigaset_resume,
- .reset_resume = gigaset_post_reset,
- .pre_reset = gigaset_pre_reset,
- .post_reset = gigaset_post_reset,
};
/* get message text for usb_submit_urb return code
@@ -262,12 +248,12 @@ static inline void dump_urb(enum debuglevel level, const char *tag,
if (urb) {
gig_dbg(level,
" dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, "
- "hcpriv=0x%08lx, transfer_flags=0x%x,",
+ "status=%d, hcpriv=0x%08lx, transfer_flags=0x%x,",
(unsigned long) urb->dev,
usb_pipetype_str(urb->pipe),
usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe),
usb_pipein(urb->pipe) ? "in" : "out",
- (unsigned long) urb->hcpriv,
+ urb->status, (unsigned long) urb->hcpriv,
urb->transfer_flags);
gig_dbg(level,
" transfer_buffer=0x%08lx[%d], actual_length=%d, "
@@ -369,27 +355,27 @@ static void check_pending(struct bas_cardstate *ucs)
case 0:
break;
case HD_OPEN_ATCHANNEL:
- if (ucs->basstate & BS_ATOPEN)
+ if (atomic_read(&ucs->basstate) & BS_ATOPEN)
ucs->pending = 0;
break;
case HD_OPEN_B1CHANNEL:
- if (ucs->basstate & BS_B1OPEN)
+ if (atomic_read(&ucs->basstate) & BS_B1OPEN)
ucs->pending = 0;
break;
case HD_OPEN_B2CHANNEL:
- if (ucs->basstate & BS_B2OPEN)
+ if (atomic_read(&ucs->basstate) & BS_B2OPEN)
ucs->pending = 0;
break;
case HD_CLOSE_ATCHANNEL:
- if (!(ucs->basstate & BS_ATOPEN))
+ if (!(atomic_read(&ucs->basstate) & BS_ATOPEN))
ucs->pending = 0;
break;
case HD_CLOSE_B1CHANNEL:
- if (!(ucs->basstate & BS_B1OPEN))
+ if (!(atomic_read(&ucs->basstate) & BS_B1OPEN))
ucs->pending = 0;
break;
case HD_CLOSE_B2CHANNEL:
- if (!(ucs->basstate & BS_B2OPEN))
+ if (!(atomic_read(&ucs->basstate) & BS_B2OPEN))
ucs->pending = 0;
break;
case HD_DEVICE_INIT_ACK: /* no reply expected */
@@ -455,8 +441,8 @@ inline static int update_basstate(struct bas_cardstate *ucs,
int state;
spin_lock_irqsave(&ucs->lock, flags);
- state = ucs->basstate;
- ucs->basstate = (state & ~clear) | set;
+ state = atomic_read(&ucs->basstate);
+ atomic_set(&ucs->basstate, (state & ~clear) | set);
spin_unlock_irqrestore(&ucs->lock, flags);
return state;
}
@@ -473,13 +459,11 @@ static void read_ctrl_callback(struct urb *urb)
struct inbuf_t *inbuf = urb->context;
struct cardstate *cs = inbuf->cs;
struct bas_cardstate *ucs = cs->hw.bas;
- int status = urb->status;
int have_data = 0;
unsigned numbytes;
int rc;
update_basstate(ucs, 0, BS_ATRDPEND);
- wake_up(&ucs->waitqueue);
if (!ucs->rcvbuf_size) {
dev_warn(cs->dev, "%s: no receive in progress\n", __func__);
@@ -488,7 +472,7 @@ static void read_ctrl_callback(struct urb *urb)
del_timer(&ucs->timer_cmd_in);
- switch (status) {
+ switch (urb->status) {
case 0: /* normal completion */
numbytes = urb->actual_length;
if (unlikely(numbytes != ucs->rcvbuf_size)) {
@@ -522,12 +506,12 @@ static void read_ctrl_callback(struct urb *urb)
case -ESHUTDOWN: /* device shut down */
/* no action necessary */
gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
+ __func__, get_usb_statmsg(urb->status));
break;
default: /* severe trouble */
dev_warn(cs->dev, "control read: %s\n",
- get_usb_statmsg(status));
+ get_usb_statmsg(urb->status));
if (ucs->retry_cmd_in++ < BAS_RETRY) {
dev_notice(cs->dev, "control read: retry %d\n",
ucs->retry_cmd_in);
@@ -566,28 +550,17 @@ static void read_ctrl_callback(struct urb *urb)
static int atread_submit(struct cardstate *cs, int timeout)
{
struct bas_cardstate *ucs = cs->hw.bas;
- int basstate;
int ret;
gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)",
ucs->rcvbuf_size);
- basstate = update_basstate(ucs, BS_ATRDPEND, 0);
- if (basstate & BS_ATRDPEND) {
+ if (update_basstate(ucs, BS_ATRDPEND, 0) & BS_ATRDPEND) {
dev_err(cs->dev,
"could not submit HD_READ_ATMESSAGE: URB busy\n");
return -EBUSY;
}
- if (basstate & BS_SUSPEND) {
- dev_notice(cs->dev,
- "HD_READ_ATMESSAGE not submitted, "
- "suspend in progress\n");
- update_basstate(ucs, 0, BS_ATRDPEND);
- /* treat like disconnect */
- return -ENODEV;
- }
-
ucs->dr_cmd_in.bRequestType = IN_VENDOR_REQ;
ucs->dr_cmd_in.bRequest = HD_READ_ATMESSAGE;
ucs->dr_cmd_in.wValue = 0;
@@ -628,13 +601,12 @@ static void read_int_callback(struct urb *urb)
struct cardstate *cs = urb->context;
struct bas_cardstate *ucs = cs->hw.bas;
struct bc_state *bcs;
- int status = urb->status;
unsigned long flags;
int rc;
unsigned l;
int channel;
- switch (status) {
+ switch (urb->status) {
case 0: /* success */
break;
case -ENOENT: /* cancelled */
@@ -642,7 +614,7 @@ static void read_int_callback(struct urb *urb)
case -EINPROGRESS: /* pending */
/* ignore silently */
gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
+ __func__, get_usb_statmsg(urb->status));
return;
case -ENODEV: /* device removed */
case -ESHUTDOWN: /* device shut down */
@@ -651,7 +623,7 @@ static void read_int_callback(struct urb *urb)
return;
default: /* severe trouble */
dev_warn(cs->dev, "interrupt read: %s\n",
- get_usb_statmsg(status));
+ get_usb_statmsg(urb->status));
//FIXME corrective action? resubmission always ok?
goto resubmit;
}
@@ -773,7 +745,6 @@ static void read_int_callback(struct urb *urb)
}
check_pending(ucs);
- wake_up(&ucs->waitqueue);
resubmit:
rc = usb_submit_urb(urb, GFP_ATOMIC);
@@ -795,18 +766,17 @@ static void read_iso_callback(struct urb *urb)
{
struct bc_state *bcs;
struct bas_bc_state *ubc;
- int status = urb->status;
unsigned long flags;
int i, rc;
/* status codes not worth bothering the tasklet with */
- if (unlikely(status == -ENOENT ||
- status == -ECONNRESET ||
- status == -EINPROGRESS ||
- status == -ENODEV ||
- status == -ESHUTDOWN)) {
+ if (unlikely(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -EINPROGRESS ||
+ urb->status == -ENODEV ||
+ urb->status == -ESHUTDOWN)) {
gig_dbg(DEBUG_ISO, "%s: %s",
- __func__, get_usb_statmsg(status));
+ __func__, get_usb_statmsg(urb->status));
return;
}
@@ -817,11 +787,10 @@ static void read_iso_callback(struct urb *urb)
if (likely(ubc->isoindone == NULL)) {
/* pass URB to tasklet */
ubc->isoindone = urb;
- ubc->isoinstatus = status;
tasklet_schedule(&ubc->rcvd_tasklet);
} else {
/* tasklet still busy, drop data and resubmit URB */
- ubc->loststatus = status;
+ ubc->loststatus = urb->status;
for (i = 0; i < BAS_NUMFRAMES; i++) {
ubc->isoinlost += urb->iso_frame_desc[i].actual_length;
if (unlikely(urb->iso_frame_desc[i].status != 0 &&
@@ -831,7 +800,7 @@ static void read_iso_callback(struct urb *urb)
urb->iso_frame_desc[i].status = 0;
urb->iso_frame_desc[i].actual_length = 0;
}
- if (likely(ubc->running)) {
+ if (likely(atomic_read(&ubc->running))) {
/* urb->dev is clobbered by USB subsystem */
urb->dev = bcs->cs->hw.bas->udev;
urb->transfer_flags = URB_ISO_ASAP;
@@ -862,24 +831,22 @@ static void write_iso_callback(struct urb *urb)
{
struct isow_urbctx_t *ucx;
struct bas_bc_state *ubc;
- int status = urb->status;
unsigned long flags;
/* status codes not worth bothering the tasklet with */
- if (unlikely(status == -ENOENT ||
- status == -ECONNRESET ||
- status == -EINPROGRESS ||
- status == -ENODEV ||
- status == -ESHUTDOWN)) {
+ if (unlikely(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -EINPROGRESS ||
+ urb->status == -ENODEV ||
+ urb->status == -ESHUTDOWN)) {
gig_dbg(DEBUG_ISO, "%s: %s",
- __func__, get_usb_statmsg(status));
+ __func__, get_usb_statmsg(urb->status));
return;
}
/* pass URB context to tasklet */
ucx = urb->context;
ubc = ucx->bcs->hw.bas;
- ucx->status = status;
spin_lock_irqsave(&ubc->isooutlock, flags);
ubc->isooutovfl = ubc->isooutdone;
@@ -908,7 +875,7 @@ static int starturbs(struct bc_state *bcs)
bcs->inputstate |= INS_flag_hunt;
/* submit all isochronous input URBs */
- ubc->running = 1;
+ atomic_set(&ubc->running, 1);
for (k = 0; k < BAS_INURBS; k++) {
urb = ubc->isoinurbs[k];
if (!urb) {
@@ -965,15 +932,15 @@ static int starturbs(struct bc_state *bcs)
ubc->isoouturbs[k].limit = -1;
}
- /* keep one URB free, submit the others */
- for (k = 0; k < BAS_OUTURBS-1; ++k) {
+ /* submit two URBs, keep third one */
+ for (k = 0; k < 2; ++k) {
dump_urb(DEBUG_ISO, "Initial isoc write", urb);
rc = usb_submit_urb(ubc->isoouturbs[k].urb, GFP_ATOMIC);
if (rc != 0)
goto error;
}
dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb);
- ubc->isooutfree = &ubc->isoouturbs[BAS_OUTURBS-1];
+ ubc->isooutfree = &ubc->isoouturbs[2];
ubc->isooutdone = ubc->isooutovfl = NULL;
return 0;
error:
@@ -991,7 +958,7 @@ static void stopurbs(struct bas_bc_state *ubc)
{
int k, rc;
- ubc->running = 0;
+ atomic_set(&ubc->running, 0);
for (k = 0; k < BAS_INURBS; ++k) {
rc = usb_unlink_urb(ubc->isoinurbs[k]);
@@ -1067,7 +1034,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
}
break;
}
- ucx->limit = ubc->isooutbuf->nextread;
+ ucx->limit = atomic_read(&ubc->isooutbuf->nextread);
ifd->status = 0;
ifd->actual_length = 0;
}
@@ -1103,7 +1070,6 @@ static void write_iso_tasklet(unsigned long data)
struct cardstate *cs = bcs->cs;
struct isow_urbctx_t *done, *next, *ovfl;
struct urb *urb;
- int status;
struct usb_iso_packet_descriptor *ifd;
int offset;
unsigned long flags;
@@ -1114,7 +1080,7 @@ static void write_iso_tasklet(unsigned long data)
/* loop while completed URBs arrive in time */
for (;;) {
- if (unlikely(!(ubc->running))) {
+ if (unlikely(!(atomic_read(&ubc->running)))) {
gig_dbg(DEBUG_ISO, "%s: not running", __func__);
return;
}
@@ -1160,8 +1126,7 @@ static void write_iso_tasklet(unsigned long data)
/* process completed URB */
urb = done->urb;
- status = done->status;
- switch (status) {
+ switch (urb->status) {
case -EXDEV: /* partial completion */
gig_dbg(DEBUG_ISO, "%s: URB partially completed",
__func__);
@@ -1214,12 +1179,12 @@ static void write_iso_tasklet(unsigned long data)
break;
default: /* severe trouble */
dev_warn(cs->dev, "isochronous write: %s\n",
- get_usb_statmsg(status));
+ get_usb_statmsg(urb->status));
}
/* mark the write buffer area covered by this URB as free */
if (done->limit >= 0)
- ubc->isooutbuf->read = done->limit;
+ atomic_set(&ubc->isooutbuf->read, done->limit);
/* mark URB as free */
spin_lock_irqsave(&ubc->isooutlock, flags);
@@ -1268,7 +1233,6 @@ static void read_iso_tasklet(unsigned long data)
struct bas_bc_state *ubc = bcs->hw.bas;
struct cardstate *cs = bcs->cs;
struct urb *urb;
- int status;
char *rcvbuf;
unsigned long flags;
int totleft, numbytes, offset, frame, rc;
@@ -1281,7 +1245,6 @@ static void read_iso_tasklet(unsigned long data)
spin_unlock_irqrestore(&ubc->isoinlock, flags);
return;
}
- status = ubc->isoinstatus;
ubc->isoindone = NULL;
if (unlikely(ubc->loststatus != -EINPROGRESS)) {
dev_warn(cs->dev,
@@ -1293,15 +1256,15 @@ static void read_iso_tasklet(unsigned long data)
}
spin_unlock_irqrestore(&ubc->isoinlock, flags);
- if (unlikely(!(ubc->running))) {
+ if (unlikely(!(atomic_read(&ubc->running)))) {
gig_dbg(DEBUG_ISO,
"%s: channel not running, "
"dropped URB with status: %s",
- __func__, get_usb_statmsg(status));
+ __func__, get_usb_statmsg(urb->status));
return;
}
- switch (status) {
+ switch (urb->status) {
case 0: /* normal completion */
break;
case -EXDEV: /* inspect individual frames
@@ -1313,7 +1276,7 @@ static void read_iso_tasklet(unsigned long data)
case -ECONNRESET:
case -EINPROGRESS:
gig_dbg(DEBUG_ISO, "%s: %s",
- __func__, get_usb_statmsg(status));
+ __func__, get_usb_statmsg(urb->status));
continue; /* -> skip */
case -EPIPE:
dev_err(cs->dev, "isochronous read stalled\n");
@@ -1321,7 +1284,7 @@ static void read_iso_tasklet(unsigned long data)
continue; /* -> skip */
default: /* severe trouble */
dev_warn(cs->dev, "isochronous read: %s\n",
- get_usb_statmsg(status));
+ get_usb_statmsg(urb->status));
goto error;
}
@@ -1443,8 +1406,6 @@ static void req_timeout(unsigned long data)
dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n",
pending);
}
-
- wake_up(&ucs->waitqueue);
}
/* write_ctrl_callback
@@ -1457,12 +1418,11 @@ static void req_timeout(unsigned long data)
static void write_ctrl_callback(struct urb *urb)
{
struct bas_cardstate *ucs = urb->context;
- int status = urb->status;
int rc;
unsigned long flags;
/* check status */
- switch (status) {
+ switch (urb->status) {
case 0: /* normal completion */
spin_lock_irqsave(&ucs->lock, flags);
switch (ucs->pending) {
@@ -1481,22 +1441,20 @@ static void write_ctrl_callback(struct urb *urb)
case -ESHUTDOWN: /* device shut down */
/* ignore silently */
gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
+ __func__, get_usb_statmsg(urb->status));
break;
default: /* any failure */
- /* don't retry if suspend requested */
- if (++ucs->retry_ctrl > BAS_RETRY ||
- (ucs->basstate & BS_SUSPEND)) {
+ if (++ucs->retry_ctrl > BAS_RETRY) {
dev_err(&ucs->interface->dev,
"control request 0x%02x failed: %s\n",
ucs->dr_ctrl.bRequest,
- get_usb_statmsg(status));
+ get_usb_statmsg(urb->status));
break; /* give up */
}
dev_notice(&ucs->interface->dev,
"control request 0x%02x: %s, retry %d\n",
- ucs->dr_ctrl.bRequest, get_usb_statmsg(status),
+ ucs->dr_ctrl.bRequest, get_usb_statmsg(urb->status),
ucs->retry_ctrl);
/* urb->dev is clobbered by USB subsystem */
urb->dev = ucs->udev;
@@ -1516,7 +1474,6 @@ static void write_ctrl_callback(struct urb *urb)
del_timer(&ucs->timer_ctrl);
ucs->pending = 0;
spin_unlock_irqrestore(&ucs->lock, flags);
- wake_up(&ucs->waitqueue);
}
/* req_submit
@@ -1591,46 +1548,37 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
*/
static int gigaset_init_bchannel(struct bc_state *bcs)
{
- struct cardstate *cs = bcs->cs;
int req, ret;
unsigned long flags;
- spin_lock_irqsave(&cs->lock, flags);
- if (unlikely(!cs->connected)) {
+ spin_lock_irqsave(&bcs->cs->lock, flags);
+ if (unlikely(!bcs->cs->connected)) {
gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
- spin_unlock_irqrestore(&cs->lock, flags);
+ spin_unlock_irqrestore(&bcs->cs->lock, flags);
return -ENODEV;
}
- if (cs->hw.bas->basstate & BS_SUSPEND) {
- dev_notice(cs->dev,
- "not starting isochronous I/O, "
- "suspend in progress\n");
- spin_unlock_irqrestore(&cs->lock, flags);
- return -EHOSTUNREACH;
- }
-
if ((ret = starturbs(bcs)) < 0) {
- dev_err(cs->dev,
+ dev_err(bcs->cs->dev,
"could not start isochronous I/O for channel B%d: %s\n",
bcs->channel + 1,
ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret));
if (ret != -ENODEV)
error_hangup(bcs);
- spin_unlock_irqrestore(&cs->lock, flags);
+ spin_unlock_irqrestore(&bcs->cs->lock, flags);
return ret;
}
req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL;
if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) {
- dev_err(cs->dev, "could not open channel B%d\n",
+ dev_err(bcs->cs->dev, "could not open channel B%d\n",
bcs->channel + 1);
stopurbs(bcs->hw.bas);
if (ret != -ENODEV)
error_hangup(bcs);
}
- spin_unlock_irqrestore(&cs->lock, flags);
+ spin_unlock_irqrestore(&bcs->cs->lock, flags);
return ret;
}
@@ -1646,20 +1594,20 @@ static int gigaset_init_bchannel(struct bc_state *bcs)
*/
static int gigaset_close_bchannel(struct bc_state *bcs)
{
- struct cardstate *cs = bcs->cs;
int req, ret;
unsigned long flags;
- spin_lock_irqsave(&cs->lock, flags);
- if (unlikely(!cs->connected)) {
- spin_unlock_irqrestore(&cs->lock, flags);
+ spin_lock_irqsave(&bcs->cs->lock, flags);
+ if (unlikely(!bcs->cs->connected)) {
+ spin_unlock_irqrestore(&bcs->cs->lock, flags);
gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
return -ENODEV;
}
- if (!(cs->hw.bas->basstate & (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) {
+ if (!(atomic_read(&bcs->cs->hw.bas->basstate) &
+ (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) {
/* channel not running: just signal common.c */
- spin_unlock_irqrestore(&cs->lock, flags);
+ spin_unlock_irqrestore(&bcs->cs->lock, flags);
gigaset_bchannel_down(bcs);
return 0;
}
@@ -1667,10 +1615,10 @@ static int gigaset_close_bchannel(struct bc_state *bcs)
/* channel running: tell device to close it */
req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL;
if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0)
- dev_err(cs->dev, "closing channel B%d failed\n",
+ dev_err(bcs->cs->dev, "closing channel B%d failed\n",
bcs->channel + 1);
- spin_unlock_irqrestore(&cs->lock, flags);
+ spin_unlock_irqrestore(&bcs->cs->lock, flags);
return ret;
}
@@ -1717,14 +1665,12 @@ static void write_command_callback(struct urb *urb)
{
struct cardstate *cs = urb->context;
struct bas_cardstate *ucs = cs->hw.bas;
- int status = urb->status;
unsigned long flags;
update_basstate(ucs, 0, BS_ATWRPEND);
- wake_up(&ucs->waitqueue);
/* check status */
- switch (status) {
+ switch (urb->status) {
case 0: /* normal completion */
break;
case -ENOENT: /* cancelled */
@@ -1734,33 +1680,26 @@ static void write_command_callback(struct urb *urb)
case -ESHUTDOWN: /* device shut down */
/* ignore silently */
gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(status));
+ __func__, get_usb_statmsg(urb->status));
return;
default: /* any failure */
if (++ucs->retry_cmd_out > BAS_RETRY) {
dev_warn(cs->dev,
"command write: %s, "
"giving up after %d retries\n",
- get_usb_statmsg(status),
+ get_usb_statmsg(urb->status),
ucs->retry_cmd_out);
break;
}
- if (ucs->basstate & BS_SUSPEND) {
- dev_warn(cs->dev,
- "command write: %s, "
- "won't retry - suspend requested\n",
- get_usb_statmsg(status));
- break;
- }
if (cs->cmdbuf == NULL) {
dev_warn(cs->dev,
"command write: %s, "
"cannot retry - cmdbuf gone\n",
- get_usb_statmsg(status));
+ get_usb_statmsg(urb->status));
break;
}
dev_notice(cs->dev, "command write: %s, retry %d\n",
- get_usb_statmsg(status), ucs->retry_cmd_out);
+ get_usb_statmsg(urb->status), ucs->retry_cmd_out);
if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0)
/* resubmitted - bypass regular exit block */
return;
@@ -1860,14 +1799,8 @@ static int start_cbsend(struct cardstate *cs)
int rc;
int retval = 0;
- /* check if suspend requested */
- if (ucs->basstate & BS_SUSPEND) {
- gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "suspending");
- return -EHOSTUNREACH;
- }
-
/* check if AT channel is open */
- if (!(ucs->basstate & BS_ATOPEN)) {
+ if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) {
gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open");
rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT);
if (rc < 0) {
@@ -1883,7 +1816,8 @@ static int start_cbsend(struct cardstate *cs)
/* try to send first command in queue */
spin_lock_irqsave(&cs->cmdlock, flags);
- while ((cb = cs->cmdbuf) != NULL && (ucs->basstate & BS_ATREADY)) {
+ while ((cb = cs->cmdbuf) != NULL &&
+ atomic_read(&ucs->basstate) & BS_ATREADY) {
ucs->retry_cmd_out = 0;
rc = atwrite_submit(cs, cb->buf, cb->len);
if (unlikely(rc)) {
@@ -1921,7 +1855,7 @@ static int gigaset_write_cmd(struct cardstate *cs,
unsigned long flags;
int rc;
- gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
+ gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
"CMD Transmit", len, buf);
@@ -2036,7 +1970,7 @@ static int gigaset_freebcshw(struct bc_state *bcs)
return 0;
/* kill URBs and tasklets before freeing - better safe than sorry */
- ubc->running = 0;
+ atomic_set(&ubc->running, 0);
gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__);
for (i = 0; i < BAS_OUTURBS; ++i) {
usb_kill_urb(ubc->isoouturbs[i].urb);
@@ -2071,7 +2005,7 @@ static int gigaset_initbcshw(struct bc_state *bcs)
return 0;
}
- ubc->running = 0;
+ atomic_set(&ubc->running, 0);
atomic_set(&ubc->corrbytes, 0);
spin_lock_init(&ubc->isooutlock);
for (i = 0; i < BAS_OUTURBS; ++i) {
@@ -2116,7 +2050,7 @@ static void gigaset_reinitbcshw(struct bc_state *bcs)
{
struct bas_bc_state *ubc = bcs->hw.bas;
- bcs->hw.bas->running = 0;
+ atomic_set(&bcs->hw.bas->running, 0);
atomic_set(&bcs->hw.bas->corrbytes, 0);
bcs->hw.bas->numsub = 0;
spin_lock_init(&ubc->isooutlock);
@@ -2147,11 +2081,10 @@ static int gigaset_initcshw(struct cardstate *cs)
spin_lock_init(&ucs->lock);
ucs->pending = 0;
- ucs->basstate = 0;
+ atomic_set(&ucs->basstate, 0);
init_timer(&ucs->timer_ctrl);
init_timer(&ucs->timer_atrdy);
init_timer(&ucs->timer_cmd_in);
- init_waitqueue_head(&ucs->waitqueue);
return 1;
}
@@ -2169,7 +2102,7 @@ static void freeurbs(struct cardstate *cs)
int i, j;
gig_dbg(DEBUG_INIT, "%s: killing URBs", __func__);
- for (j = 0; j < BAS_CHANNELS; ++j) {
+ for (j = 0; j < 2; ++j) {
ubc = cs->bcs[j].hw.bas;
for (i = 0; i < BAS_OUTURBS; ++i) {
usb_kill_urb(ubc->isoouturbs[i].urb);
@@ -2246,11 +2179,11 @@ static int gigaset_probe(struct usb_interface *interface,
__func__, le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
- /* allocate memory for our device state and intialize it */
- cs = gigaset_initcs(driver, BAS_CHANNELS, 0, 0, cidmode,
- GIGASET_MODULENAME);
- if (!cs)
+ cs = gigaset_getunassignedcs(driver);
+ if (!cs) {
+ dev_err(&udev->dev, "no free cardstate\n");
return -ENODEV;
+ }
ucs = cs->hw.bas;
/* save off device structure ptrs for later use */
@@ -2270,7 +2203,7 @@ static int gigaset_probe(struct usb_interface *interface,
!(ucs->urb_ctrl = usb_alloc_urb(0, GFP_KERNEL)))
goto allocerr;
- for (j = 0; j < BAS_CHANNELS; ++j) {
+ for (j = 0; j < 2; ++j) {
ubc = cs->bcs[j].hw.bas;
for (i = 0; i < BAS_OUTURBS; ++i)
if (!(ubc->isoouturbs[i].urb =
@@ -2304,7 +2237,7 @@ static int gigaset_probe(struct usb_interface *interface,
/* tell common part that the device is ready */
if (startmode == SM_LOCKED)
- cs->mstate = MS_LOCKED;
+ atomic_set(&cs->mstate, MS_LOCKED);
/* save address of controller structure */
usb_set_intfdata(interface, cs);
@@ -2319,7 +2252,7 @@ static int gigaset_probe(struct usb_interface *interface,
error:
freeurbs(cs);
usb_set_intfdata(interface, NULL);
- gigaset_freecs(cs);
+ gigaset_unassign(cs);
return -ENODEV;
}
@@ -2339,10 +2272,11 @@ static void gigaset_disconnect(struct usb_interface *interface)
dev_info(cs->dev, "disconnecting Gigaset base\n");
/* mark base as not ready, all channels disconnected */
- ucs->basstate = 0;
+ atomic_set(&ucs->basstate, 0);
/* tell LL all channels are down */
- for (j = 0; j < BAS_CHANNELS; ++j)
+ //FIXME shouldn't gigaset_stop() do this?
+ for (j = 0; j < 2; ++j)
gigaset_bchannel_down(cs->bcs + j);
/* stop driver (common part) */
@@ -2361,113 +2295,9 @@ static void gigaset_disconnect(struct usb_interface *interface)
ucs->interface = NULL;
ucs->udev = NULL;
cs->dev = NULL;
- gigaset_freecs(cs);
+ gigaset_unassign(cs);
}
-/* gigaset_suspend
- * This function is called before the USB connection is suspended.
- */
-static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct cardstate *cs = usb_get_intfdata(intf);
- struct bas_cardstate *ucs = cs->hw.bas;
- int rc;
-
- /* set suspend flag; this stops AT command/response traffic */
- if (update_basstate(ucs, BS_SUSPEND, 0) & BS_SUSPEND) {
- gig_dbg(DEBUG_SUSPEND, "already suspended");
- return 0;
- }
-
- /* wait a bit for blocking conditions to go away */
- rc = wait_event_timeout(ucs->waitqueue,
- !(ucs->basstate &
- (BS_B1OPEN|BS_B2OPEN|BS_ATRDPEND|BS_ATWRPEND)),
- BAS_TIMEOUT*HZ/10);
- gig_dbg(DEBUG_SUSPEND, "wait_event_timeout() -> %d", rc);
-
- /* check for conditions preventing suspend */
- if (ucs->basstate & (BS_B1OPEN|BS_B2OPEN|BS_ATRDPEND|BS_ATWRPEND)) {
- dev_warn(cs->dev, "cannot suspend:\n");
- if (ucs->basstate & BS_B1OPEN)
- dev_warn(cs->dev, " B channel 1 open\n");
- if (ucs->basstate & BS_B2OPEN)
- dev_warn(cs->dev, " B channel 2 open\n");
- if (ucs->basstate & BS_ATRDPEND)
- dev_warn(cs->dev, " receiving AT reply\n");
- if (ucs->basstate & BS_ATWRPEND)
- dev_warn(cs->dev, " sending AT command\n");
- update_basstate(ucs, 0, BS_SUSPEND);
- return -EBUSY;
- }
-
- /* close AT channel if open */
- if (ucs->basstate & BS_ATOPEN) {
- gig_dbg(DEBUG_SUSPEND, "closing AT channel");
- rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, 0);
- if (rc) {
- update_basstate(ucs, 0, BS_SUSPEND);
- return rc;
- }
- wait_event_timeout(ucs->waitqueue, !ucs->pending,
- BAS_TIMEOUT*HZ/10);
- /* in case of timeout, proceed anyway */
- }
-
- /* kill all URBs and timers that might still be pending */
- usb_kill_urb(ucs->urb_ctrl);
- usb_kill_urb(ucs->urb_int_in);
- del_timer_sync(&ucs->timer_ctrl);
-
- gig_dbg(DEBUG_SUSPEND, "suspend complete");
- return 0;
-}
-
-/* gigaset_resume
- * This function is called after the USB connection has been resumed.
- */
-static int gigaset_resume(struct usb_interface *intf)
-{
- struct cardstate *cs = usb_get_intfdata(intf);
- struct bas_cardstate *ucs = cs->hw.bas;
- int rc;
-
- /* resubmit interrupt URB for spontaneous messages from base */
- rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL);
- if (rc) {
- dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
- get_usb_rcmsg(rc));
- return rc;
- }
-
- /* clear suspend flag to reallow activity */
- update_basstate(ucs, 0, BS_SUSPEND);
-
- gig_dbg(DEBUG_SUSPEND, "resume complete");
- return 0;
-}
-
-/* gigaset_pre_reset
- * This function is called before the USB connection is reset.
- */
-static int gigaset_pre_reset(struct usb_interface *intf)
-{
- /* handle just like suspend */
- return gigaset_suspend(intf, PMSG_ON);
-}
-
-/* gigaset_post_reset
- * This function is called after the USB connection has been reset.
- */
-static int gigaset_post_reset(struct usb_interface *intf)
-{
- /* FIXME: send HD_DEVICE_INIT_ACK? */
-
- /* resume operations */
- return gigaset_resume(intf);
-}
-
-
static const struct gigaset_ops gigops = {
gigaset_write_cmd,
gigaset_write_room,
@@ -2500,6 +2330,12 @@ static int __init bas_gigaset_init(void)
&gigops, THIS_MODULE)) == NULL)
goto error;
+ /* allocate memory for our device state and intialize it */
+ cardstate = gigaset_initcs(driver, 2, 0, 0, cidmode,
+ GIGASET_MODULENAME);
+ if (!cardstate)
+ goto error;
+
/* register this driver with the USB subsystem */
result = usb_register(&gigaset_usb_driver);
if (result < 0) {
@@ -2511,7 +2347,9 @@ static int __init bas_gigaset_init(void)
info(DRIVER_DESC);
return 0;
-error:
+error: if (cardstate)
+ gigaset_freecs(cardstate);
+ cardstate = NULL;
if (driver)
gigaset_freedriver(driver);
driver = NULL;
@@ -2523,50 +2361,43 @@ static int __init bas_gigaset_init(void)
*/
static void __exit bas_gigaset_exit(void)
{
- struct bas_cardstate *ucs;
- int i;
+ struct bas_cardstate *ucs = cardstate->hw.bas;
gigaset_blockdriver(driver); /* => probe will fail
* => no gigaset_start any more
*/
- /* stop all connected devices */
- for (i = 0; i < driver->minors; i++) {
- if (gigaset_shutdown(driver->cs + i) < 0)
- continue; /* no device */
- /* from now on, no isdn callback should be possible */
-
- /* close all still open channels */
- ucs = driver->cs[i].hw.bas;
- if (ucs->basstate & BS_B1OPEN) {
- gig_dbg(DEBUG_INIT, "closing B1 channel");
- usb_control_msg(ucs->udev,
- usb_sndctrlpipe(ucs->udev, 0),
- HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ,
- 0, 0, NULL, 0, BAS_TIMEOUT);
- }
- if (ucs->basstate & BS_B2OPEN) {
- gig_dbg(DEBUG_INIT, "closing B2 channel");
- usb_control_msg(ucs->udev,
- usb_sndctrlpipe(ucs->udev, 0),
- HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ,
- 0, 0, NULL, 0, BAS_TIMEOUT);
- }
- if (ucs->basstate & BS_ATOPEN) {
- gig_dbg(DEBUG_INIT, "closing AT channel");
- usb_control_msg(ucs->udev,
- usb_sndctrlpipe(ucs->udev, 0),
- HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ,
- 0, 0, NULL, 0, BAS_TIMEOUT);
- }
- ucs->basstate = 0;
+ gigaset_shutdown(cardstate);
+ /* from now on, no isdn callback should be possible */
+
+ /* close all still open channels */
+ if (atomic_read(&ucs->basstate) & BS_B1OPEN) {
+ gig_dbg(DEBUG_INIT, "closing B1 channel");
+ usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
+ HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ, 0, 0,
+ NULL, 0, BAS_TIMEOUT);
+ }
+ if (atomic_read(&ucs->basstate) & BS_B2OPEN) {
+ gig_dbg(DEBUG_INIT, "closing B2 channel");
+ usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
+ HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ, 0, 0,
+ NULL, 0, BAS_TIMEOUT);
+ }
+ if (atomic_read(&ucs->basstate) & BS_ATOPEN) {
+ gig_dbg(DEBUG_INIT, "closing AT channel");
+ usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
+ HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ, 0, 0,
+ NULL, 0, BAS_TIMEOUT);
}
+ atomic_set(&ucs->basstate, 0);
/* deregister this driver with the USB subsystem */
usb_deregister(&gigaset_usb_driver);
/* this will call the disconnect-callback */
/* from now on, no disconnect/probe callback should be running */
+ gigaset_freecs(cardstate);
+ cardstate = NULL;
gigaset_freedriver(driver);
driver = NULL;
}
diff --git a/trunk/drivers/isdn/gigaset/common.c b/trunk/drivers/isdn/gigaset/common.c
index aacedec4986f..acd417197d03 100644
--- a/trunk/drivers/isdn/gigaset/common.c
+++ b/trunk/drivers/isdn/gigaset/common.c
@@ -31,6 +31,7 @@ MODULE_PARM_DESC(debug, "debug level");
/* driver state flags */
#define VALID_MINOR 0x01
#define VALID_ID 0x02
+#define ASSIGNED 0x04
void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
size_t len, const unsigned char *buf)
@@ -177,7 +178,7 @@ int gigaset_get_channel(struct bc_state *bcs)
unsigned long flags;
spin_lock_irqsave(&bcs->cs->lock, flags);
- if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) {
+ if (bcs->use_count) {
gig_dbg(DEBUG_ANY, "could not allocate channel %d",
bcs->channel);
spin_unlock_irqrestore(&bcs->cs->lock, flags);
@@ -202,7 +203,6 @@ void gigaset_free_channel(struct bc_state *bcs)
}
--bcs->use_count;
bcs->busy = 0;
- module_put(bcs->cs->driver->owner);
gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel);
spin_unlock_irqrestore(&bcs->cs->lock, flags);
}
@@ -356,28 +356,31 @@ static struct cardstate *alloc_cs(struct gigaset_driver *drv)
{
unsigned long flags;
unsigned i;
- struct cardstate *cs;
struct cardstate *ret = NULL;
spin_lock_irqsave(&drv->lock, flags);
- if (drv->blocked)
- goto exit;
for (i = 0; i < drv->minors; ++i) {
- cs = drv->cs + i;
- if (!(cs->flags & VALID_MINOR)) {
- cs->flags = VALID_MINOR;
- ret = cs;
+ if (!(drv->flags[i] & VALID_MINOR)) {
+ if (try_module_get(drv->owner)) {
+ drv->flags[i] = VALID_MINOR;
+ ret = drv->cs + i;
+ }
break;
}
}
-exit:
spin_unlock_irqrestore(&drv->lock, flags);
return ret;
}
static void free_cs(struct cardstate *cs)
{
- cs->flags = 0;
+ unsigned long flags;
+ struct gigaset_driver *drv = cs->driver;
+ spin_lock_irqsave(&drv->lock, flags);
+ if (drv->flags[cs->minor_index] & VALID_MINOR)
+ module_put(drv->owner);
+ drv->flags[cs->minor_index] = 0;
+ spin_unlock_irqrestore(&drv->lock, flags);
}
static void make_valid(struct cardstate *cs, unsigned mask)
@@ -385,7 +388,7 @@ static void make_valid(struct cardstate *cs, unsigned mask)
unsigned long flags;
struct gigaset_driver *drv = cs->driver;
spin_lock_irqsave(&drv->lock, flags);
- cs->flags |= mask;
+ drv->flags[cs->minor_index] |= mask;
spin_unlock_irqrestore(&drv->lock, flags);
}
@@ -394,7 +397,7 @@ static void make_invalid(struct cardstate *cs, unsigned mask)
unsigned long flags;
struct gigaset_driver *drv = cs->driver;
spin_lock_irqsave(&drv->lock, flags);
- cs->flags &= ~mask;
+ drv->flags[cs->minor_index] &= ~mask;
spin_unlock_irqrestore(&drv->lock, flags);
}
@@ -498,11 +501,11 @@ static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs,
struct cardstate *cs, int inputstate)
/* inbuf->read must be allocated before! */
{
- inbuf->head = 0;
- inbuf->tail = 0;
+ atomic_set(&inbuf->head, 0);
+ atomic_set(&inbuf->tail, 0);
inbuf->cs = cs;
inbuf->bcs = bcs; /*base driver: NULL*/
- inbuf->rcvbuf = NULL;
+ inbuf->rcvbuf = NULL; //FIXME
inbuf->inputstate = inputstate;
}
@@ -518,8 +521,8 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
return 0;
bytesleft = numbytes;
- tail = inbuf->tail;
- head = inbuf->head;
+ tail = atomic_read(&inbuf->tail);
+ head = atomic_read(&inbuf->head);
gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
while (bytesleft) {
@@ -543,7 +546,7 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
src += n;
}
gig_dbg(DEBUG_INTR, "setting tail to %u", tail);
- inbuf->tail = tail;
+ atomic_set(&inbuf->tail, tail);
return numbytes != bytesleft;
}
EXPORT_SYMBOL_GPL(gigaset_fill_inbuf);
@@ -665,7 +668,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
tasklet_init(&cs->event_tasklet, &gigaset_handle_event,
(unsigned long) cs);
- cs->commands_pending = 0;
+ atomic_set(&cs->commands_pending, 0);
cs->cur_at_seq = 0;
cs->gotfwver = -1;
cs->open_count = 0;
@@ -685,8 +688,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
init_waitqueue_head(&cs->waitqueue);
cs->waiting = 0;
- cs->mode = M_UNKNOWN;
- cs->mstate = MS_UNINITIALIZED;
+ atomic_set(&cs->mode, M_UNKNOWN);
+ atomic_set(&cs->mstate, MS_UNINITIALIZED);
for (i = 0; i < channels; ++i) {
gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i);
@@ -803,8 +806,8 @@ static void cleanup_cs(struct cardstate *cs)
spin_lock_irqsave(&cs->lock, flags);
- cs->mode = M_UNKNOWN;
- cs->mstate = MS_UNINITIALIZED;
+ atomic_set(&cs->mode, M_UNKNOWN);
+ atomic_set(&cs->mstate, MS_UNINITIALIZED);
clear_at_state(&cs->at_state);
dealloc_at_states(cs);
@@ -814,8 +817,8 @@ static void cleanup_cs(struct cardstate *cs)
kfree(cs->inbuf->rcvbuf);
cs->inbuf->rcvbuf = NULL;
cs->inbuf->inputstate = INS_command;
- cs->inbuf->head = 0;
- cs->inbuf->tail = 0;
+ atomic_set(&cs->inbuf->head, 0);
+ atomic_set(&cs->inbuf->tail, 0);
cb = cs->cmdbuf;
while (cb) {
@@ -829,7 +832,7 @@ static void cleanup_cs(struct cardstate *cs)
cs->gotfwver = -1;
cs->dle = 0;
cs->cur_at_seq = 0;
- cs->commands_pending = 0;
+ atomic_set(&cs->commands_pending, 0);
cs->cbytes = 0;
spin_unlock_irqrestore(&cs->lock, flags);
@@ -859,7 +862,7 @@ int gigaset_start(struct cardstate *cs)
cs->connected = 1;
spin_unlock_irqrestore(&cs->lock, flags);
- if (cs->mstate != MS_LOCKED) {
+ if (atomic_read(&cs->mstate) != MS_LOCKED) {
cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS);
cs->ops->baud_rate(cs, B115200);
cs->ops->set_line_ctrl(cs, CS8);
@@ -890,17 +893,10 @@ int gigaset_start(struct cardstate *cs)
}
EXPORT_SYMBOL_GPL(gigaset_start);
-/* gigaset_shutdown
- * check if a device is associated to the cardstate structure and stop it
- * return value: 0 if ok, -1 if no device was associated
- */
-int gigaset_shutdown(struct cardstate *cs)
+void gigaset_shutdown(struct cardstate *cs)
{
mutex_lock(&cs->mutex);
- if (!(cs->flags & VALID_MINOR))
- return -1;
-
cs->waiting = 1;
if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) {
@@ -917,7 +913,6 @@ int gigaset_shutdown(struct cardstate *cs)
exit:
mutex_unlock(&cs->mutex);
- return 0;
}
EXPORT_SYMBOL_GPL(gigaset_shutdown);
@@ -959,11 +954,13 @@ struct cardstate *gigaset_get_cs_by_id(int id)
list_for_each_entry(drv, &drivers, list) {
spin_lock(&drv->lock);
for (i = 0; i < drv->minors; ++i) {
- cs = drv->cs + i;
- if ((cs->flags & VALID_ID) && cs->myid == id) {
- ret = cs;
- break;
+ if (drv->flags[i] & VALID_ID) {
+ cs = drv->cs + i;
+ if (cs->myid == id)
+ ret = cs;
}
+ if (ret)
+ break;
}
spin_unlock(&drv->lock);
if (ret)
@@ -986,9 +983,10 @@ void gigaset_debugdrivers(void)
spin_lock(&drv->lock);
for (i = 0; i < drv->minors; ++i) {
gig_dbg(DEBUG_DRIVER, " index %u", i);
+ gig_dbg(DEBUG_DRIVER, " flags 0x%02x",
+ drv->flags[i]);
cs = drv->cs + i;
gig_dbg(DEBUG_DRIVER, " cardstate %p", cs);
- gig_dbg(DEBUG_DRIVER, " flags 0x%02x", cs->flags);
gig_dbg(DEBUG_DRIVER, " minor_index %u",
cs->minor_index);
gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver);
@@ -1012,7 +1010,7 @@ static struct cardstate *gigaset_get_cs_by_minor(unsigned minor)
continue;
index = minor - drv->minor;
spin_lock(&drv->lock);
- if (drv->cs[index].flags & VALID_MINOR)
+ if (drv->flags[index] & VALID_MINOR)
ret = drv->cs + index;
spin_unlock(&drv->lock);
if (ret)
@@ -1040,6 +1038,7 @@ void gigaset_freedriver(struct gigaset_driver *drv)
gigaset_if_freedriver(drv);
kfree(drv->cs);
+ kfree(drv->flags);
kfree(drv);
}
EXPORT_SYMBOL_GPL(gigaset_freedriver);
@@ -1081,8 +1080,12 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
if (!drv->cs)
goto error;
+ drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL);
+ if (!drv->flags)
+ goto error;
+
for (i = 0; i < minors; ++i) {
- drv->cs[i].flags = 0;
+ drv->flags[i] = 0;
drv->cs[i].driver = drv;
drv->cs[i].ops = drv->ops;
drv->cs[i].minor_index = i;
@@ -1103,9 +1106,53 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
}
EXPORT_SYMBOL_GPL(gigaset_initdriver);
+/* For drivers without fixed assignment device<->cardstate (usb) */
+struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv)
+{
+ unsigned long flags;
+ struct cardstate *cs = NULL;
+ unsigned i;
+
+ spin_lock_irqsave(&drv->lock, flags);
+ if (drv->blocked)
+ goto exit;
+ for (i = 0; i < drv->minors; ++i) {
+ if ((drv->flags[i] & VALID_MINOR) &&
+ !(drv->flags[i] & ASSIGNED)) {
+ drv->flags[i] |= ASSIGNED;
+ cs = drv->cs + i;
+ break;
+ }
+ }
+exit:
+ spin_unlock_irqrestore(&drv->lock, flags);
+ return cs;
+}
+EXPORT_SYMBOL_GPL(gigaset_getunassignedcs);
+
+void gigaset_unassign(struct cardstate *cs)
+{
+ unsigned long flags;
+ unsigned *minor_flags;
+ struct gigaset_driver *drv;
+
+ if (!cs)
+ return;
+ drv = cs->driver;
+ spin_lock_irqsave(&drv->lock, flags);
+ minor_flags = drv->flags + cs->minor_index;
+ if (*minor_flags & VALID_MINOR)
+ *minor_flags &= ~ASSIGNED;
+ spin_unlock_irqrestore(&drv->lock, flags);
+}
+EXPORT_SYMBOL_GPL(gigaset_unassign);
+
void gigaset_blockdriver(struct gigaset_driver *drv)
{
+ unsigned long flags;
+ spin_lock_irqsave(&drv->lock, flags);
drv->blocked = 1;
+ spin_unlock_irqrestore(&drv->lock, flags);
}
EXPORT_SYMBOL_GPL(gigaset_blockdriver);
diff --git a/trunk/drivers/isdn/gigaset/ev-layer.c b/trunk/drivers/isdn/gigaset/ev-layer.c
index 5cbf64d850ee..cec1ef342fcc 100644
--- a/trunk/drivers/isdn/gigaset/ev-layer.c
+++ b/trunk/drivers/isdn/gigaset/ev-layer.c
@@ -735,7 +735,7 @@ static void disconnect(struct at_state_t **at_state_p)
/* revert to selected idle mode */
if (!cs->cidmode) {
cs->at_state.pending_commands |= PC_UMMODE;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1); //FIXME
gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
}
spin_unlock_irqrestore(&cs->lock, flags);
@@ -793,15 +793,15 @@ static void init_failed(struct cardstate *cs, int mode)
struct at_state_t *at_state;
cs->at_state.pending_commands &= ~PC_INIT;
- cs->mode = mode;
- cs->mstate = MS_UNINITIALIZED;
+ atomic_set(&cs->mode, mode);
+ atomic_set(&cs->mstate, MS_UNINITIALIZED);
gigaset_free_channels(cs);
for (i = 0; i < cs->channels; ++i) {
at_state = &cs->bcs[i].at_state;
if (at_state->pending_commands & PC_CID) {
at_state->pending_commands &= ~PC_CID;
at_state->pending_commands |= PC_NOCID;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
}
}
}
@@ -812,11 +812,11 @@ static void schedule_init(struct cardstate *cs, int state)
gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again");
return;
}
- cs->mstate = state;
- cs->mode = M_UNKNOWN;
+ atomic_set(&cs->mstate, state);
+ atomic_set(&cs->mode, M_UNKNOWN);
gigaset_block_channels(cs);
cs->at_state.pending_commands |= PC_INIT;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
gig_dbg(DEBUG_CMD, "Scheduling PC_INIT");
}
@@ -953,13 +953,13 @@ static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_ind
at_state->pending_commands |= PC_CID;
gig_dbg(DEBUG_CMD, "Scheduling PC_CID");
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
return;
error:
at_state->pending_commands |= PC_NOCID;
gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID");
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
return;
}
@@ -973,12 +973,12 @@ static void start_accept(struct at_state_t *at_state)
if (retval == 0) {
at_state->pending_commands |= PC_ACCEPT;
gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT");
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
} else {
- /* error reset */
+ //FIXME
at_state->pending_commands |= PC_HUP;
gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
}
}
@@ -986,7 +986,7 @@ static void do_start(struct cardstate *cs)
{
gigaset_free_channels(cs);
- if (cs->mstate != MS_LOCKED)
+ if (atomic_read(&cs->mstate) != MS_LOCKED)
schedule_init(cs, MS_INIT);
cs->isdn_up = 1;
@@ -1000,9 +1000,9 @@ static void do_start(struct cardstate *cs)
static void finish_shutdown(struct cardstate *cs)
{
- if (cs->mstate != MS_LOCKED) {
- cs->mstate = MS_UNINITIALIZED;
- cs->mode = M_UNKNOWN;
+ if (atomic_read(&cs->mstate) != MS_LOCKED) {
+ atomic_set(&cs->mstate, MS_UNINITIALIZED);
+ atomic_set(&cs->mode, M_UNKNOWN);
}
/* Tell the LL that the device is not available .. */
@@ -1022,10 +1022,10 @@ static void do_shutdown(struct cardstate *cs)
{
gigaset_block_channels(cs);
- if (cs->mstate == MS_READY) {
- cs->mstate = MS_SHUTDOWN;
+ if (atomic_read(&cs->mstate) == MS_READY) {
+ atomic_set(&cs->mstate, MS_SHUTDOWN);
cs->at_state.pending_commands |= PC_SHUTDOWN;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN");
} else
finish_shutdown(cs);
@@ -1120,7 +1120,7 @@ static void handle_icall(struct cardstate *cs, struct bc_state *bcs,
* In fact it doesn't.
*/
at_state->pending_commands |= PC_HUP;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
break;
}
}
@@ -1130,7 +1130,7 @@ static int do_lock(struct cardstate *cs)
int mode;
int i;
- switch (cs->mstate) {
+ switch (atomic_read(&cs->mstate)) {
case MS_UNINITIALIZED:
case MS_READY:
if (cs->cur_at_seq || !list_empty(&cs->temp_at_states) ||
@@ -1152,20 +1152,20 @@ static int do_lock(struct cardstate *cs)
return -EBUSY;
}
- mode = cs->mode;
- cs->mstate = MS_LOCKED;
- cs->mode = M_UNKNOWN;
+ mode = atomic_read(&cs->mode);
+ atomic_set(&cs->mstate, MS_LOCKED);
+ atomic_set(&cs->mode, M_UNKNOWN);
return mode;
}
static int do_unlock(struct cardstate *cs)
{
- if (cs->mstate != MS_LOCKED)
+ if (atomic_read(&cs->mstate) != MS_LOCKED)
return -EINVAL;
- cs->mstate = MS_UNINITIALIZED;
- cs->mode = M_UNKNOWN;
+ atomic_set(&cs->mstate, MS_UNINITIALIZED);
+ atomic_set(&cs->mode, M_UNKNOWN);
gigaset_free_channels(cs);
if (cs->connected)
schedule_init(cs, MS_INIT);
@@ -1198,17 +1198,17 @@ static void do_action(int action, struct cardstate *cs,
case ACT_INIT:
cs->at_state.pending_commands &= ~PC_INIT;
cs->cur_at_seq = SEQ_NONE;
- cs->mode = M_UNIMODEM;
+ atomic_set(&cs->mode, M_UNIMODEM);
spin_lock_irqsave(&cs->lock, flags);
if (!cs->cidmode) {
spin_unlock_irqrestore(&cs->lock, flags);
gigaset_free_channels(cs);
- cs->mstate = MS_READY;
+ atomic_set(&cs->mstate, MS_READY);
break;
}
spin_unlock_irqrestore(&cs->lock, flags);
cs->at_state.pending_commands |= PC_CIDMODE;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
break;
case ACT_FAILINIT:
@@ -1234,20 +1234,22 @@ static void do_action(int action, struct cardstate *cs,
| INS_command;
break;
case ACT_CMODESET:
- if (cs->mstate == MS_INIT || cs->mstate == MS_RECOVER) {
+ if (atomic_read(&cs->mstate) == MS_INIT ||
+ atomic_read(&cs->mstate) == MS_RECOVER) {
gigaset_free_channels(cs);
- cs->mstate = MS_READY;
+ atomic_set(&cs->mstate, MS_READY);
}
- cs->mode = M_CID;
+ atomic_set(&cs->mode, M_CID);
cs->cur_at_seq = SEQ_NONE;
break;
case ACT_UMODESET:
- cs->mode = M_UNIMODEM;
+ atomic_set(&cs->mode, M_UNIMODEM);
cs->cur_at_seq = SEQ_NONE;
break;
case ACT_FAILCMODE:
cs->cur_at_seq = SEQ_NONE;
- if (cs->mstate == MS_INIT || cs->mstate == MS_RECOVER) {
+ if (atomic_read(&cs->mstate) == MS_INIT ||
+ atomic_read(&cs->mstate) == MS_RECOVER) {
init_failed(cs, M_UNKNOWN);
break;
}
@@ -1305,7 +1307,7 @@ static void do_action(int action, struct cardstate *cs,
case ACT_CONNECT:
if (cs->onechannel) {
at_state->pending_commands |= PC_DLE1;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
break;
}
bcs->chstate |= CHS_D_UP;
@@ -1331,7 +1333,7 @@ static void do_action(int action, struct cardstate *cs,
* DLE only used for M10x with one B channel.
*/
at_state->pending_commands |= PC_DLE0;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
} else
disconnect(p_at_state);
break;
@@ -1367,7 +1369,7 @@ static void do_action(int action, struct cardstate *cs,
"Could not enter DLE mode. Trying to hang up.\n");
channel = cs->curchannel;
cs->bcs[channel].at_state.pending_commands |= PC_HUP;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
break;
case ACT_CID: /* got cid; start dialing */
@@ -1377,7 +1379,7 @@ static void do_action(int action, struct cardstate *cs,
cs->bcs[channel].at_state.cid = ev->parameter;
cs->bcs[channel].at_state.pending_commands |=
PC_DIAL;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
break;
}
/* fall through */
@@ -1409,14 +1411,14 @@ static void do_action(int action, struct cardstate *cs,
case ACT_ABORTDIAL: /* error/timeout during dial preparation */
cs->cur_at_seq = SEQ_NONE;
at_state->pending_commands |= PC_HUP;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
break;
case ACT_REMOTEREJECT: /* DISCONNECT_IND after dialling */
case ACT_CONNTIMEOUT: /* timeout waiting for ZSAU=ACTIVE */
case ACT_REMOTEHUP: /* DISCONNECT_IND with established connection */
at_state->pending_commands |= PC_HUP;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
break;
case ACT_GETSTRING: /* warning: RING, ZDLE, ...
are not handled properly anymore */
@@ -1513,7 +1515,7 @@ static void do_action(int action, struct cardstate *cs,
break;
case ACT_HUP:
at_state->pending_commands |= PC_HUP;
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
break;
@@ -1556,7 +1558,7 @@ static void do_action(int action, struct cardstate *cs,
cs->at_state.pending_commands |= PC_UMMODE;
gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
}
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
}
spin_unlock_irqrestore(&cs->lock, flags);
cs->waiting = 0;
@@ -1739,7 +1741,7 @@ static void process_command_flags(struct cardstate *cs)
int sequence;
unsigned long flags;
- cs->commands_pending = 0;
+ atomic_set(&cs->commands_pending, 0);
if (cs->cur_at_seq) {
gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy");
@@ -1777,7 +1779,7 @@ static void process_command_flags(struct cardstate *cs)
~(PC_DLE1 | PC_ACCEPT | PC_DIAL);
if (at_state->cid > 0)
at_state->pending_commands |= PC_HUP;
- if (cs->mstate == MS_RECOVER) {
+ if (atomic_read(&cs->mstate) == MS_RECOVER) {
if (at_state->pending_commands & PC_CID) {
at_state->pending_commands |= PC_NOCID;
at_state->pending_commands &= ~PC_CID;
@@ -1791,7 +1793,7 @@ static void process_command_flags(struct cardstate *cs)
if (cs->at_state.pending_commands == PC_UMMODE
&& !cs->cidmode
&& list_empty(&cs->temp_at_states)
- && cs->mode == M_CID) {
+ && atomic_read(&cs->mode) == M_CID) {
sequence = SEQ_UMMODE;
at_state = &cs->at_state;
for (i = 0; i < cs->channels; ++i) {
@@ -1858,7 +1860,7 @@ static void process_command_flags(struct cardstate *cs)
}
if (cs->at_state.pending_commands & PC_CIDMODE) {
cs->at_state.pending_commands &= ~PC_CIDMODE;
- if (cs->mode == M_UNIMODEM) {
+ if (atomic_read(&cs->mode) == M_UNIMODEM) {
cs->retry_count = 1;
schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE);
return;
@@ -1884,11 +1886,11 @@ static void process_command_flags(struct cardstate *cs)
return;
}
if (bcs->at_state.pending_commands & PC_CID) {
- switch (cs->mode) {
+ switch (atomic_read(&cs->mode)) {
case M_UNIMODEM:
cs->at_state.pending_commands |= PC_CIDMODE;
gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
- cs->commands_pending = 1;
+ atomic_set(&cs->commands_pending, 1);
return;
#ifdef GIG_MAYINITONDIAL
case M_UNKNOWN:
@@ -1924,7 +1926,7 @@ static void process_events(struct cardstate *cs)
for (i = 0; i < 2 * MAX_EVENTS; ++i) {
tail = cs->ev_tail;
if (tail == head) {
- if (!check_flags && !cs->commands_pending)
+ if (!check_flags && !atomic_read(&cs->commands_pending))
break;
check_flags = 0;
spin_unlock_irqrestore(&cs->ev_lock, flags);
@@ -1932,7 +1934,7 @@ static void process_events(struct cardstate *cs)
spin_lock_irqsave(&cs->ev_lock, flags);
tail = cs->ev_tail;
if (tail == head) {
- if (!cs->commands_pending)
+ if (!atomic_read(&cs->commands_pending))
break;
continue;
}
@@ -1969,7 +1971,7 @@ void gigaset_handle_event(unsigned long data)
struct cardstate *cs = (struct cardstate *) data;
/* handle incoming data on control/common channel */
- if (cs->inbuf->head != cs->inbuf->tail) {
+ if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) {
gig_dbg(DEBUG_INTR, "processing new data");
cs->ops->handle_input(cs->inbuf);
}
diff --git a/trunk/drivers/isdn/gigaset/gigaset.h b/trunk/drivers/isdn/gigaset/gigaset.h
index f365993161fc..02bdaf22d7ea 100644
--- a/trunk/drivers/isdn/gigaset/gigaset.h
+++ b/trunk/drivers/isdn/gigaset/gigaset.h
@@ -70,13 +70,22 @@
extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */
-/* debug flags, combine by adding/bitwise OR */
+/* any combination of these can be given with the 'debug=' parameter to insmod,
+ * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and
+ * DEBUG_INTR.
+ */
enum debuglevel {
- DEBUG_INTR = 0x00008, /* interrupt processing */
+ DEBUG_REG = 0x0002, /* serial port I/O register operations */
+ DEBUG_OPEN = 0x0004, /* open/close serial port */
+ DEBUG_INTR = 0x0008, /* interrupt processing */
+ DEBUG_INTR_DUMP = 0x0010, /* Activating hexdump debug output on
+ interrupt requests, not available as
+ run-time option */
DEBUG_CMD = 0x00020, /* sent/received LL commands */
DEBUG_STREAM = 0x00040, /* application data stream I/O events */
DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */
DEBUG_LLDATA = 0x00100, /* sent/received LL data */
+ DEBUG_INTR_0 = 0x00200, /* serial port interrupt processing */
DEBUG_DRIVER = 0x00400, /* driver structure */
DEBUG_HDLC = 0x00800, /* M10x HDLC processing */
DEBUG_WRITE = 0x01000, /* M105 data write */
@@ -84,7 +93,7 @@ enum debuglevel {
DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */
DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data
structures */
- DEBUG_SUSPEND = 0x10000, /* suspend/resume processing */
+ DEBUG_LOCK = 0x10000, /* semaphore operations */
DEBUG_OUTPUT = 0x20000, /* output to device */
DEBUG_ISO = 0x40000, /* isochronous transfers */
DEBUG_IF = 0x80000, /* character device operations */
@@ -182,9 +191,6 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
#define HD_OPEN_ATCHANNEL (0x28) // 3070
#define HD_CLOSE_ATCHANNEL (0x29) // 3070
-/* number of B channels supported by base driver */
-#define BAS_CHANNELS 2
-
/* USB frames for isochronous transfer */
#define BAS_FRAMETIME 1 /* number of milliseconds between frames */
#define BAS_NUMFRAMES 8 /* number of frames per URB */
@@ -307,7 +313,7 @@ struct inbuf_t {
struct bc_state *bcs;
struct cardstate *cs;
int inputstate;
- int head, tail;
+ atomic_t head, tail;
unsigned char data[RBUFSIZE];
};
@@ -329,9 +335,9 @@ struct inbuf_t {
* are also filled with that value
*/
struct isowbuf_t {
- int read;
- int nextread;
- int write;
+ atomic_t read;
+ atomic_t nextread;
+ atomic_t write;
atomic_t writesem;
int wbits;
unsigned char data[BAS_OUTBUFSIZE + BAS_OUTBUFPAD];
@@ -344,13 +350,11 @@ struct isowbuf_t {
* - urb: pointer to the URB itself
* - bcs: pointer to the B Channel control structure
* - limit: end of write buffer area covered by this URB
- * - status: URB completion status
*/
struct isow_urbctx_t {
struct urb *urb;
struct bc_state *bcs;
int limit;
- int status;
};
/* AT state structure
@@ -435,15 +439,14 @@ struct cardstate {
unsigned minor_index;
struct device *dev;
struct device *tty_dev;
- unsigned flags;
const struct gigaset_ops *ops;
/* Stuff to handle communication */
wait_queue_head_t waitqueue;
int waiting;
- int mode; /* see M_XXXX */
- int mstate; /* Modem state: see MS_XXXX */
+ atomic_t mode; /* see M_XXXX */
+ atomic_t mstate; /* Modem state: see MS_XXXX */
/* only changed by the event layer */
int cmd_result;
@@ -500,7 +503,7 @@ struct cardstate {
processed */
int curchannel; /* channel those commands are meant
for */
- int commands_pending; /* flag(s) in xxx.commands_pending have
+ atomic_t commands_pending; /* flag(s) in xxx.commands_pending have
been set */
struct tasklet_struct event_tasklet;
/* tasklet for serializing AT commands.
@@ -540,6 +543,7 @@ struct gigaset_driver {
unsigned minor;
unsigned minors;
struct cardstate *cs;
+ unsigned *flags;
int blocked;
const struct gigaset_ops *ops;
@@ -555,7 +559,7 @@ struct cmdbuf_t {
struct bas_bc_state {
/* isochronous output state */
- int running;
+ atomic_t running;
atomic_t corrbytes;
spinlock_t isooutlock;
struct isow_urbctx_t isoouturbs[BAS_OUTURBS];
@@ -570,7 +574,6 @@ struct bas_bc_state {
struct urb *isoinurbs[BAS_INURBS];
unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS];
struct urb *isoindone; /* completed isoc read URB */
- int isoinstatus; /* status of completed URB */
int loststatus; /* status of dropped URB */
unsigned isoinlost; /* number of bytes lost */
/* state of bit unstuffing algorithm
@@ -767,6 +770,10 @@ void gigaset_freedriver(struct gigaset_driver *drv);
void gigaset_debugdrivers(void);
struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty);
struct cardstate *gigaset_get_cs_by_id(int id);
+
+/* For drivers without fixed assignment device<->cardstate (usb) */
+struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv);
+void gigaset_unassign(struct cardstate *cs);
void gigaset_blockdriver(struct gigaset_driver *drv);
/* Allocate and initialize card state. Calls hardware dependent
@@ -785,7 +792,7 @@ int gigaset_start(struct cardstate *cs);
void gigaset_stop(struct cardstate *cs);
/* Tell common.c that the driver is being unloaded. */
-int gigaset_shutdown(struct cardstate *cs);
+void gigaset_shutdown(struct cardstate *cs);
/* Tell common.c that an skb has been sent. */
void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
diff --git a/trunk/drivers/isdn/gigaset/interface.c b/trunk/drivers/isdn/gigaset/interface.c
index af195b07c191..eb50f3dab5f7 100644
--- a/trunk/drivers/isdn/gigaset/interface.c
+++ b/trunk/drivers/isdn/gigaset/interface.c
@@ -28,11 +28,12 @@ static int if_lock(struct cardstate *cs, int *arg)
return -EINVAL;
if (cmd < 0) {
- *arg = cs->mstate == MS_LOCKED;
+ *arg = atomic_read(&cs->mstate) == MS_LOCKED; //FIXME remove?
return 0;
}
- if (!cmd && cs->mstate == MS_LOCKED && cs->connected) {
+ if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED
+ && cs->connected) {
cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS);
cs->ops->baud_rate(cs, B115200);
cs->ops->set_line_ctrl(cs, CS8);
@@ -103,7 +104,7 @@ static int if_config(struct cardstate *cs, int *arg)
if (*arg != 1)
return -EINVAL;
- if (cs->mstate != MS_LOCKED)
+ if (atomic_read(&cs->mstate) != MS_LOCKED)
return -EBUSY;
if (!cs->connected) {
@@ -161,7 +162,7 @@ static int if_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = NULL;
cs = gigaset_get_cs_by_tty(tty);
- if (!cs || !try_module_get(cs->driver->owner))
+ if (!cs)
return -ENODEV;
if (mutex_lock_interruptible(&cs->mutex))
@@ -207,8 +208,6 @@ static void if_close(struct tty_struct *tty, struct file *filp)
}
mutex_unlock(&cs->mutex);
-
- module_put(cs->driver->owner);
}
static int if_ioctl(struct tty_struct *tty, struct file *file,
@@ -365,7 +364,7 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
if (!cs->open_count)
warn("%s: device not opened", __func__);
- else if (cs->mstate != MS_LOCKED) {
+ else if (atomic_read(&cs->mstate) != MS_LOCKED) {
warn("can't write to unlocked device");
retval = -EBUSY;
} else if (!cs->connected) {
@@ -399,9 +398,9 @@ static int if_write_room(struct tty_struct *tty)
if (!cs->open_count)
warn("%s: device not opened", __func__);
- else if (cs->mstate != MS_LOCKED) {
+ else if (atomic_read(&cs->mstate) != MS_LOCKED) {
warn("can't write to unlocked device");
- retval = -EBUSY;
+ retval = -EBUSY; //FIXME
} else if (!cs->connected) {
gig_dbg(DEBUG_ANY, "can't write to unplugged device");
retval = -EBUSY; //FIXME
@@ -431,7 +430,7 @@ static int if_chars_in_buffer(struct tty_struct *tty)
if (!cs->open_count)
warn("%s: device not opened", __func__);
- else if (cs->mstate != MS_LOCKED) {
+ else if (atomic_read(&cs->mstate) != MS_LOCKED) {
warn("can't write to unlocked device");
retval = -EBUSY;
} else if (!cs->connected) {
diff --git a/trunk/drivers/isdn/gigaset/isocdata.c b/trunk/drivers/isdn/gigaset/isocdata.c
index e30a7773f93c..e0505f238807 100644
--- a/trunk/drivers/isdn/gigaset/isocdata.c
+++ b/trunk/drivers/isdn/gigaset/isocdata.c
@@ -23,9 +23,9 @@
*/
void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle)
{
- iwb->read = 0;
- iwb->nextread = 0;
- iwb->write = 0;
+ atomic_set(&iwb->read, 0);
+ atomic_set(&iwb->nextread, 0);
+ atomic_set(&iwb->write, 0);
atomic_set(&iwb->writesem, 1);
iwb->wbits = 0;
iwb->idle = idle;
@@ -39,8 +39,8 @@ static inline int isowbuf_freebytes(struct isowbuf_t *iwb)
{
int read, write, freebytes;
- read = iwb->read;
- write = iwb->write;
+ read = atomic_read(&iwb->read);
+ write = atomic_read(&iwb->write);
if ((freebytes = read - write) > 0) {
/* no wraparound: need padding space within regular area */
return freebytes - BAS_OUTBUFPAD;
@@ -62,7 +62,7 @@ static inline int isowbuf_poscmp(struct isowbuf_t *iwb, int a, int b)
int read;
if (a == b)
return 0;
- read = iwb->read;
+ read = atomic_read(&iwb->read);
if (a < b) {
if (a < read && read <= b)
return +1;
@@ -91,18 +91,18 @@ static inline int isowbuf_startwrite(struct isowbuf_t *iwb)
#ifdef CONFIG_GIGASET_DEBUG
gig_dbg(DEBUG_ISO,
"%s: acquired iso write semaphore, data[write]=%02x, nbits=%d",
- __func__, iwb->data[iwb->write], iwb->wbits);
+ __func__, iwb->data[atomic_read(&iwb->write)], iwb->wbits);
#endif
return 1;
}
/* finish writing
- * release the write semaphore
+ * release the write semaphore and update the maximum buffer fill level
* returns the current write position
*/
static inline int isowbuf_donewrite(struct isowbuf_t *iwb)
{
- int write = iwb->write;
+ int write = atomic_read(&iwb->write);
atomic_inc(&iwb->writesem);
return write;
}
@@ -116,7 +116,7 @@ static inline int isowbuf_donewrite(struct isowbuf_t *iwb)
*/
static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits)
{
- int write = iwb->write;
+ int write = atomic_read(&iwb->write);
data <<= iwb->wbits;
data |= iwb->data[write];
nbits += iwb->wbits;
@@ -128,7 +128,7 @@ static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits)
}
iwb->wbits = nbits;
iwb->data[write] = data & 0xff;
- iwb->write = write;
+ atomic_set(&iwb->write, write);
}
/* put final flag on HDLC bitstream
@@ -142,7 +142,7 @@ static inline void isowbuf_putflag(struct isowbuf_t *iwb)
/* add two flags, thus reliably covering one byte */
isowbuf_putbits(iwb, 0x7e7e, 8);
/* recover the idle flag byte */
- write = iwb->write;
+ write = atomic_read(&iwb->write);
iwb->idle = iwb->data[write];
gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle);
/* mask extraneous bits in buffer */
@@ -160,8 +160,8 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
int read, write, limit, src, dst;
unsigned char pbyte;
- read = iwb->nextread;
- write = iwb->write;
+ read = atomic_read(&iwb->nextread);
+ write = atomic_read(&iwb->write);
if (likely(read == write)) {
/* return idle frame */
return read < BAS_OUTBUFPAD ?
@@ -176,7 +176,7 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
err("invalid size %d", size);
return -EINVAL;
}
- src = iwb->read;
+ src = atomic_read(&iwb->read);
if (unlikely(limit > BAS_OUTBUFSIZE + BAS_OUTBUFPAD ||
(read < src && limit >= src))) {
err("isoc write buffer frame reservation violated");
@@ -191,8 +191,7 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
if (!isowbuf_startwrite(iwb))
return -EBUSY;
/* write position could have changed */
- write = iwb->write;
- if (limit >= write) {
+ if (limit >= (write = atomic_read(&iwb->write))) {
pbyte = iwb->data[write]; /* save
partial byte */
limit = write + BAS_OUTBUFPAD;
@@ -214,7 +213,7 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
__func__, pbyte, limit);
iwb->data[limit] = pbyte; /* restore
partial byte */
- iwb->write = limit;
+ atomic_set(&iwb->write, limit);
}
isowbuf_donewrite(iwb);
}
@@ -234,7 +233,7 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
limit = src;
}
}
- iwb->nextread = limit;
+ atomic_set(&iwb->nextread, limit);
return read;
}
@@ -478,7 +477,7 @@ static inline int trans_buildframe(struct isowbuf_t *iwb,
unsigned char c;
if (unlikely(count <= 0))
- return iwb->write;
+ return atomic_read(&iwb->write); /* better ideas? */
if (isowbuf_freebytes(iwb) < count ||
!isowbuf_startwrite(iwb)) {
@@ -487,13 +486,13 @@ static inline int trans_buildframe(struct isowbuf_t *iwb,
}
gig_dbg(DEBUG_STREAM, "put %d bytes", count);
- write = iwb->write;
+ write = atomic_read(&iwb->write);
do {
c = bitrev8(*in++);
iwb->data[write++] = c;
write %= BAS_OUTBUFSIZE;
} while (--count > 0);
- iwb->write = write;
+ atomic_set(&iwb->write, write);
iwb->idle = c;
return isowbuf_donewrite(iwb);
@@ -948,8 +947,8 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
unsigned tail, head, numbytes;
unsigned char *src;
- head = inbuf->head;
- while (head != (tail = inbuf->tail)) {
+ head = atomic_read(&inbuf->head);
+ while (head != (tail = atomic_read(&inbuf->tail))) {
gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
if (head > tail)
tail = RBUFSIZE;
@@ -957,7 +956,7 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
numbytes = tail - head;
gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
- if (cs->mstate == MS_LOCKED) {
+ if (atomic_read(&cs->mstate) == MS_LOCKED) {
gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
numbytes, src);
gigaset_if_receive(inbuf->cs, src, numbytes);
@@ -971,7 +970,7 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
if (head == RBUFSIZE)
head = 0;
gig_dbg(DEBUG_INTR, "setting head to %u", head);
- inbuf->head = head;
+ atomic_set(&inbuf->head, head);
}
}
diff --git a/trunk/drivers/isdn/gigaset/ser-gigaset.c b/trunk/drivers/isdn/gigaset/ser-gigaset.c
index fceeb1d57682..ea44302e6e7e 100644
--- a/trunk/drivers/isdn/gigaset/ser-gigaset.c
+++ b/trunk/drivers/isdn/gigaset/ser-gigaset.c
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
/* Version Information */
#define DRIVER_AUTHOR "Tilman Schmidt"
@@ -49,7 +48,7 @@ struct ser_cardstate {
struct platform_device dev;
struct tty_struct *tty;
atomic_t refcnt;
- struct completion dead_cmp;
+ struct mutex dead_mutex;
};
static struct platform_driver device_driver = {
@@ -241,7 +240,7 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
struct cmdbuf_t *cb;
unsigned long flags;
- gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
+ gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
"CMD Transmit", len, buf);
@@ -499,7 +498,7 @@ static struct cardstate *cs_get(struct tty_struct *tty)
static void cs_put(struct cardstate *cs)
{
if (atomic_dec_and_test(&cs->hw.ser->refcnt))
- complete(&cs->hw.ser->dead_cmp);
+ mutex_unlock(&cs->hw.ser->dead_mutex);
}
/*
@@ -528,8 +527,8 @@ gigaset_tty_open(struct tty_struct *tty)
cs->dev = &cs->hw.ser->dev.dev;
cs->hw.ser->tty = tty;
+ mutex_init(&cs->hw.ser->dead_mutex);
atomic_set(&cs->hw.ser->refcnt, 1);
- init_completion(&cs->hw.ser->dead_cmp);
tty->disc_data = cs;
@@ -537,13 +536,14 @@ gigaset_tty_open(struct tty_struct *tty)
* startup system and notify the LL that we are ready to run
*/
if (startmode == SM_LOCKED)
- cs->mstate = MS_LOCKED;
+ atomic_set(&cs->mstate, MS_LOCKED);
if (!gigaset_start(cs)) {
tasklet_kill(&cs->write_tasklet);
goto error;
}
gig_dbg(DEBUG_INIT, "Startup of HLL done");
+ mutex_lock(&cs->hw.ser->dead_mutex);
return 0;
error:
@@ -577,7 +577,7 @@ gigaset_tty_close(struct tty_struct *tty)
else {
/* wait for running methods to finish */
if (!atomic_dec_and_test(&cs->hw.ser->refcnt))
- wait_for_completion(&cs->hw.ser->dead_cmp);
+ mutex_lock(&cs->hw.ser->dead_mutex);
}
/* stop operations */
@@ -714,8 +714,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
return;
}
- tail = inbuf->tail;
- head = inbuf->head;
+ tail = atomic_read(&inbuf->tail);
+ head = atomic_read(&inbuf->head);
gig_dbg(DEBUG_INTR, "buffer state: %u -> %u, receive %u bytes",
head, tail, count);
@@ -742,7 +742,7 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
}
gig_dbg(DEBUG_INTR, "setting tail to %u", tail);
- inbuf->tail = tail;
+ atomic_set(&inbuf->tail, tail);
/* Everything was received .. Push data into handler */
gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
diff --git a/trunk/drivers/isdn/gigaset/usb-gigaset.c b/trunk/drivers/isdn/gigaset/usb-gigaset.c
index 77d20ab0cd4d..ca4bee173cfb 100644
--- a/trunk/drivers/isdn/gigaset/usb-gigaset.c
+++ b/trunk/drivers/isdn/gigaset/usb-gigaset.c
@@ -104,17 +104,12 @@ MODULE_DEVICE_TABLE(usb, gigaset_table);
* flags per packet.
*/
-/* functions called if a device of this driver is connected/disconnected */
static int gigaset_probe(struct usb_interface *interface,
const struct usb_device_id *id);
static void gigaset_disconnect(struct usb_interface *interface);
-/* functions called before/after suspend */
-static int gigaset_suspend(struct usb_interface *intf, pm_message_t message);
-static int gigaset_resume(struct usb_interface *intf);
-static int gigaset_pre_reset(struct usb_interface *intf);
-
static struct gigaset_driver *driver = NULL;
+static struct cardstate *cardstate = NULL;
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver gigaset_usb_driver = {
@@ -122,17 +117,12 @@ static struct usb_driver gigaset_usb_driver = {
.probe = gigaset_probe,
.disconnect = gigaset_disconnect,
.id_table = gigaset_table,
- .suspend = gigaset_suspend,
- .resume = gigaset_resume,
- .reset_resume = gigaset_resume,
- .pre_reset = gigaset_pre_reset,
- .post_reset = gigaset_resume,
};
struct usb_cardstate {
struct usb_device *udev; /* usb device pointer */
struct usb_interface *interface; /* interface for this device */
- int busy; /* bulk output in progress */
+ atomic_t busy; /* bulk output in progress */
/* Output buffer */
unsigned char *bulk_out_buffer;
@@ -324,7 +314,7 @@ static void gigaset_modem_fill(unsigned long data)
gig_dbg(DEBUG_OUTPUT, "modem_fill");
- if (cs->hw.usb->busy) {
+ if (atomic_read(&cs->hw.usb->busy)) {
gig_dbg(DEBUG_OUTPUT, "modem_fill: busy");
return;
}
@@ -371,13 +361,18 @@ static void gigaset_read_int_callback(struct urb *urb)
{
struct inbuf_t *inbuf = urb->context;
struct cardstate *cs = inbuf->cs;
- int status = urb->status;
+ int resubmit = 0;
int r;
unsigned numbytes;
unsigned char *src;
unsigned long flags;
- if (!status) {
+ if (!urb->status) {
+ if (!cs->connected) {
+ err("%s: disconnected", __func__); /* should never happen */
+ return;
+ }
+
numbytes = urb->actual_length;
if (numbytes) {
@@ -394,26 +389,28 @@ static void gigaset_read_int_callback(struct urb *urb)
}
} else
gig_dbg(DEBUG_INTR, "Received zero block length");
+ resubmit = 1;
} else {
/* The urb might have been killed. */
- gig_dbg(DEBUG_ANY, "%s - nonzero status received: %d",
- __func__, status);
- if (status == -ENOENT || status == -ESHUTDOWN)
- /* killed or endpoint shutdown: don't resubmit */
- return;
+ gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d",
+ __func__, urb->status);
+ if (urb->status != -ENOENT) { /* not killed */
+ if (!cs->connected) {
+ err("%s: disconnected", __func__); /* should never happen */
+ return;
+ }
+ resubmit = 1;
+ }
}
- /* resubmit URB */
- spin_lock_irqsave(&cs->lock, flags);
- if (!cs->connected) {
+ if (resubmit) {
+ spin_lock_irqsave(&cs->lock, flags);
+ r = cs->connected ? usb_submit_urb(urb, GFP_ATOMIC) : -ENODEV;
spin_unlock_irqrestore(&cs->lock, flags);
- err("%s: disconnected", __func__);
- return;
+ if (r)
+ dev_err(cs->dev, "error %d when resubmitting urb.\n",
+ -r);
}
- r = usb_submit_urb(urb, GFP_ATOMIC);
- spin_unlock_irqrestore(&cs->lock, flags);
- if (r)
- dev_err(cs->dev, "error %d resubmitting URB\n", -r);
}
@@ -421,28 +418,19 @@ static void gigaset_read_int_callback(struct urb *urb)
static void gigaset_write_bulk_callback(struct urb *urb)
{
struct cardstate *cs = urb->context;
- int status = urb->status;
unsigned long flags;
- switch (status) {
- case 0: /* normal completion */
- break;
- case -ENOENT: /* killed */
- gig_dbg(DEBUG_ANY, "%s: killed", __func__);
- cs->hw.usb->busy = 0;
- return;
- default:
+ if (urb->status)
dev_err(cs->dev, "bulk transfer failed (status %d)\n",
- -status);
+ -urb->status);
/* That's all we can do. Communication problems
are handled by timeouts or network protocols. */
- }
spin_lock_irqsave(&cs->lock, flags);
if (!cs->connected) {
err("%s: not connected", __func__);
} else {
- cs->hw.usb->busy = 0;
+ atomic_set(&cs->hw.usb->busy, 0);
tasklet_schedule(&cs->write_tasklet);
}
spin_unlock_irqrestore(&cs->lock, flags);
@@ -490,14 +478,14 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
cb->offset += count;
cb->len -= count;
- ucs->busy = 1;
+ atomic_set(&ucs->busy, 1);
spin_lock_irqsave(&cs->lock, flags);
status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV;
spin_unlock_irqrestore(&cs->lock, flags);
if (status) {
- ucs->busy = 0;
+ atomic_set(&ucs->busy, 0);
err("could not submit urb (error %d)\n",
-status);
cb->len = 0; /* skip urb => remove cb+wakeup
@@ -516,7 +504,7 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
struct cmdbuf_t *cb;
unsigned long flags;
- gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
+ gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
"CMD Transmit", len, buf);
@@ -653,7 +641,7 @@ static int write_modem(struct cardstate *cs)
count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size);
skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count);
skb_pull(bcs->tx_skb, count);
- ucs->busy = 1;
+ atomic_set(&ucs->busy, 1);
gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count);
spin_lock_irqsave(&cs->lock, flags);
@@ -671,7 +659,7 @@ static int write_modem(struct cardstate *cs)
if (ret) {
err("could not submit urb (error %d)\n", -ret);
- ucs->busy = 0;
+ atomic_set(&ucs->busy, 0);
}
if (!bcs->tx_skb->len) {
@@ -692,44 +680,53 @@ static int gigaset_probe(struct usb_interface *interface,
{
int retval;
struct usb_device *udev = interface_to_usbdev(interface);
- struct usb_host_interface *hostif = interface->cur_altsetting;
+ unsigned int ifnum;
+ struct usb_host_interface *hostif;
struct cardstate *cs = NULL;
struct usb_cardstate *ucs = NULL;
struct usb_endpoint_descriptor *endpoint;
int buffer_size;
+ int alt;
- gig_dbg(DEBUG_ANY, "%s: Check if device matches ...", __func__);
+ gig_dbg(DEBUG_ANY,
+ "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
+ __func__, le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+
+ retval = -ENODEV; //FIXME
/* See if the device offered us matches what we can accept */
if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) ||
- (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) {
- gig_dbg(DEBUG_ANY, "device ID (0x%x, 0x%x) not for me - skip",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
+ (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID))
return -ENODEV;
- }
- if (hostif->desc.bInterfaceNumber != 0) {
- gig_dbg(DEBUG_ANY, "interface %d not for me - skip",
- hostif->desc.bInterfaceNumber);
- return -ENODEV;
- }
- if (hostif->desc.bAlternateSetting != 0) {
- dev_notice(&udev->dev, "unsupported altsetting %d - skip",
- hostif->desc.bAlternateSetting);
+
+ /* this starts to become ascii art... */
+ hostif = interface->cur_altsetting;
+ alt = hostif->desc.bAlternateSetting;
+ ifnum = hostif->desc.bInterfaceNumber; // FIXME ?
+
+ if (alt != 0 || ifnum != 0) {
+ dev_warn(&udev->dev, "ifnum %d, alt %d\n", ifnum, alt);
return -ENODEV;
}
+
+ /* Reject application specific intefaces
+ *
+ */
if (hostif->desc.bInterfaceClass != 255) {
- dev_notice(&udev->dev, "unsupported interface class %d - skip",
- hostif->desc.bInterfaceClass);
+ dev_info(&udev->dev,
+ "%s: Device matched but iface_desc[%d]->bInterfaceClass==%d!\n",
+ __func__, ifnum, hostif->desc.bInterfaceClass);
return -ENODEV;
}
dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
- /* allocate memory for our device state and intialize it */
- cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
- if (!cs)
+ cs = gigaset_getunassignedcs(driver);
+ if (!cs) {
+ dev_warn(&udev->dev, "no free cardstate\n");
return -ENODEV;
+ }
ucs = cs->hw.usb;
/* save off device structure ptrs for later use */
@@ -762,7 +759,7 @@ static int gigaset_probe(struct usb_interface *interface,
endpoint = &hostif->endpoint[1].desc;
- ucs->busy = 0;
+ atomic_set(&ucs->busy, 0);
ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!ucs->read_urb) {
@@ -795,7 +792,7 @@ static int gigaset_probe(struct usb_interface *interface,
/* tell common part that the device is ready */
if (startmode == SM_LOCKED)
- cs->mstate = MS_LOCKED;
+ atomic_set(&cs->mstate, MS_LOCKED);
if (!gigaset_start(cs)) {
tasklet_kill(&cs->write_tasklet);
@@ -816,7 +813,7 @@ static int gigaset_probe(struct usb_interface *interface,
usb_put_dev(ucs->udev);
ucs->udev = NULL;
ucs->interface = NULL;
- gigaset_freecs(cs);
+ gigaset_unassign(cs);
return retval;
}
@@ -827,9 +824,6 @@ static void gigaset_disconnect(struct usb_interface *interface)
cs = usb_get_intfdata(interface);
ucs = cs->hw.usb;
-
- dev_info(cs->dev, "disconnecting Gigaset USB adapter\n");
-
usb_kill_urb(ucs->read_urb);
gigaset_stop(cs);
@@ -837,7 +831,7 @@ static void gigaset_disconnect(struct usb_interface *interface)
usb_set_intfdata(interface, NULL);
tasklet_kill(&cs->write_tasklet);
- usb_kill_urb(ucs->bulk_out_urb);
+ usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */
kfree(ucs->bulk_out_buffer);
usb_free_urb(ucs->bulk_out_urb);
@@ -850,53 +844,7 @@ static void gigaset_disconnect(struct usb_interface *interface)
ucs->interface = NULL;
ucs->udev = NULL;
cs->dev = NULL;
- gigaset_freecs(cs);
-}
-
-/* gigaset_suspend
- * This function is called before the USB connection is suspended or reset.
- */
-static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct cardstate *cs = usb_get_intfdata(intf);
-
- /* stop activity */
- cs->connected = 0; /* prevent rescheduling */
- usb_kill_urb(cs->hw.usb->read_urb);
- tasklet_kill(&cs->write_tasklet);
- usb_kill_urb(cs->hw.usb->bulk_out_urb);
-
- gig_dbg(DEBUG_SUSPEND, "suspend complete");
- return 0;
-}
-
-/* gigaset_resume
- * This function is called after the USB connection has been resumed or reset.
- */
-static int gigaset_resume(struct usb_interface *intf)
-{
- struct cardstate *cs = usb_get_intfdata(intf);
- int rc;
-
- /* resubmit interrupt URB */
- cs->connected = 1;
- rc = usb_submit_urb(cs->hw.usb->read_urb, GFP_KERNEL);
- if (rc) {
- dev_err(cs->dev, "Could not submit read URB (error %d)\n", -rc);
- return rc;
- }
-
- gig_dbg(DEBUG_SUSPEND, "resume complete");
- return 0;
-}
-
-/* gigaset_pre_reset
- * This function is called before the USB connection is reset.
- */
-static int gigaset_pre_reset(struct usb_interface *intf)
-{
- /* same as suspend */
- return gigaset_suspend(intf, PMSG_ON);
+ gigaset_unassign(cs);
}
static const struct gigaset_ops ops = {
@@ -932,6 +880,11 @@ static int __init usb_gigaset_init(void)
&ops, THIS_MODULE)) == NULL)
goto error;
+ /* allocate memory for our device state and intialize it */
+ cardstate = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
+ if (!cardstate)
+ goto error;
+
/* register this driver with the USB subsystem */
result = usb_register(&gigaset_usb_driver);
if (result < 0) {
@@ -944,7 +897,9 @@ static int __init usb_gigaset_init(void)
info(DRIVER_DESC);
return 0;
-error:
+error: if (cardstate)
+ gigaset_freecs(cardstate);
+ cardstate = NULL;
if (driver)
gigaset_freedriver(driver);
driver = NULL;
@@ -958,16 +913,11 @@ static int __init usb_gigaset_init(void)
*/
static void __exit usb_gigaset_exit(void)
{
- int i;
-
gigaset_blockdriver(driver); /* => probe will fail
* => no gigaset_start any more
*/
- /* stop all connected devices */
- for (i = 0; i < driver->minors; i++)
- gigaset_shutdown(driver->cs + i);
-
+ gigaset_shutdown(cardstate);
/* from now on, no isdn callback should be possible */
/* deregister this driver with the USB subsystem */
@@ -975,6 +925,8 @@ static void __exit usb_gigaset_exit(void)
/* this will call the disconnect-callback */
/* from now on, no disconnect/probe callback should be running */
+ gigaset_freecs(cardstate);
+ cardstate = NULL;
gigaset_freedriver(driver);
driver = NULL;
}
diff --git a/trunk/drivers/isdn/hardware/eicon/debug.c b/trunk/drivers/isdn/hardware/eicon/debug.c
index 84318ec8d13e..0db9cc661e28 100644
--- a/trunk/drivers/isdn/hardware/eicon/debug.c
+++ b/trunk/drivers/isdn/hardware/eicon/debug.c
@@ -1188,7 +1188,7 @@ int SuperTraceASSIGN (void* AdapterHandle, byte* data) {
if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) &&
(features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) {
- dword uninitialized_var(rx_dma_magic);
+ dword rx_dma_magic;
if ((pC->dma_handle = diva_get_dma_descriptor (pC->request, &rx_dma_magic)) >= 0) {
pC->xbuffer[0] = LLI;
pC->xbuffer[1] = 8;
diff --git a/trunk/drivers/isdn/hardware/eicon/diva.c b/trunk/drivers/isdn/hardware/eicon/diva.c
index 1403a5458e68..ffa2afa77c2f 100644
--- a/trunk/drivers/isdn/hardware/eicon/diva.c
+++ b/trunk/drivers/isdn/hardware/eicon/diva.c
@@ -515,11 +515,12 @@ diva_xdi_read(void *adapter, void *os_handle, void __user *dst,
irqreturn_t diva_os_irq_wrapper(int irq, void *context)
{
- diva_os_xdi_adapter_t *a = context;
+ diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) context;
diva_xdi_clear_interrupts_proc_t clear_int_proc;
- if (!a || !a->xdi_adapter.diva_isr_handler)
+ if (!a || !a->xdi_adapter.diva_isr_handler) {
return IRQ_NONE;
+ }
if ((clear_int_proc = a->clear_interrupts_proc)) {
(*clear_int_proc) (a);
diff --git a/trunk/drivers/isdn/hardware/eicon/message.c b/trunk/drivers/isdn/hardware/eicon/message.c
index 1ff98e7eb794..b9177ca4369a 100644
--- a/trunk/drivers/isdn/hardware/eicon/message.c
+++ b/trunk/drivers/isdn/hardware/eicon/message.c
@@ -9027,7 +9027,7 @@ static byte AddInfo(byte **add_i,
/* facility is a nested structure */
/* FTY can be more than once */
- if (esc_chi[0] && !(esc_chi[esc_chi[0]] & 0x7f))
+ if(esc_chi[0] && !(esc_chi[esc_chi[0]])&0x7f )
{
add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */
}
diff --git a/trunk/drivers/isdn/hisax/avm_pci.c b/trunk/drivers/isdn/hisax/avm_pci.c
index 0f1db1f669b2..035d158779df 100644
--- a/trunk/drivers/isdn/hisax/avm_pci.c
+++ b/trunk/drivers/isdn/hisax/avm_pci.c
@@ -263,7 +263,11 @@ hdlc_empty_fifo(struct BCState *bcs, int count)
outl(idx, cs->hw.avm.cfg_reg + 4);
while (cnt < count) {
#ifdef __powerpc__
+#ifdef CONFIG_APUS
+ *ptr++ = in_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
+#else
*ptr++ = in_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
+#endif /* CONFIG_APUS */
#else
*ptr++ = inl(cs->hw.avm.isac);
#endif /* __powerpc__ */
@@ -324,7 +328,11 @@ hdlc_fill_fifo(struct BCState *bcs)
if (cs->subtyp == AVM_FRITZ_PCI) {
while (cnthw.avm.isac +_IO_BASE), *ptr++);
+#else
out_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
+#endif /* CONFIG_APUS */
#else
outl(*ptr++, cs->hw.avm.isac);
#endif /* __powerpc__ */
diff --git a/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c
index 133eb18e65cc..9cb6e5021adb 100644
--- a/trunk/drivers/isdn/i4l/isdn_tty.c
+++ b/trunk/drivers/isdn/i4l/isdn_tty.c
@@ -1917,6 +1917,7 @@ isdn_tty_modem_init(void)
info->owner = THIS_MODULE;
#endif
spin_lock_init(&info->readlock);
+ init_MUTEX(&info->write_sem);
sprintf(info->last_cause, "0000");
sprintf(info->last_num, "none");
info->last_dir = 0;
diff --git a/trunk/drivers/isdn/i4l/isdn_ttyfax.c b/trunk/drivers/isdn/i4l/isdn_ttyfax.c
index f93de4a30355..a943d078bacc 100644
--- a/trunk/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/trunk/drivers/isdn/i4l/isdn_ttyfax.c
@@ -834,7 +834,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
char *rp = &f->resolution;
p[0] += 2;
- if (!(info->faxonline & 1)) /* not outgoing connection */
+ if (!info->faxonline & 1) /* not outgoing connection */
PARSE_ERROR1;
for (i = 0; (((*p[0] >= '0') && (*p[0] <= '9')) || (*p[0] == ',')) && (i < 4); i++) {
diff --git a/trunk/drivers/isdn/icn/icn.c b/trunk/drivers/isdn/icn/icn.c
index bf7997abc4ac..82d957bde299 100644
--- a/trunk/drivers/isdn/icn/icn.c
+++ b/trunk/drivers/isdn/icn/icn.c
@@ -1302,7 +1302,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
}
break;
case ISDN_CMD_DIAL:
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
if (card->leased)
break;
@@ -1328,7 +1328,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
}
break;
case ISDN_CMD_ACCEPTD:
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
if (c->arg < ICN_BCH) {
a = c->arg + 1;
@@ -1348,7 +1348,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
}
break;
case ISDN_CMD_ACCEPTB:
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
if (c->arg < ICN_BCH) {
a = c->arg + 1;
@@ -1366,7 +1366,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
}
break;
case ISDN_CMD_HANGUP:
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
if (c->arg < ICN_BCH) {
a = c->arg + 1;
@@ -1375,7 +1375,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
}
break;
case ISDN_CMD_SETEAZ:
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
if (card->leased)
break;
@@ -1391,7 +1391,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
}
break;
case ISDN_CMD_CLREAZ:
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
if (card->leased)
break;
@@ -1405,7 +1405,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
}
break;
case ISDN_CMD_SETL2:
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
if ((c->arg & 255) < ICN_BCH) {
a = c->arg;
@@ -1424,7 +1424,7 @@ icn_command(isdn_ctrl * c, icn_card * card)
}
break;
case ISDN_CMD_SETL3:
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
return 0;
default:
@@ -1471,7 +1471,7 @@ if_writecmd(const u_char __user *buf, int len, int id, int channel)
icn_card *card = icn_findcard(id);
if (card) {
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
return (icn_writecmd(buf, len, 1, card));
}
@@ -1486,7 +1486,7 @@ if_readstatus(u_char __user *buf, int len, int id, int channel)
icn_card *card = icn_findcard(id);
if (card) {
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
return (icn_readstatus(buf, len, card));
}
@@ -1501,7 +1501,7 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
icn_card *card = icn_findcard(id);
if (card) {
- if (!(card->flags & ICN_FLAGS_RUNNING))
+ if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
return (icn_sendbuf(channel, ack, skb, card));
}
diff --git a/trunk/drivers/isdn/isdnloop/isdnloop.c b/trunk/drivers/isdn/isdnloop/isdnloop.c
index 655ef9a3f4df..bb92e3cd9334 100644
--- a/trunk/drivers/isdn/isdnloop/isdnloop.c
+++ b/trunk/drivers/isdn/isdnloop/isdnloop.c
@@ -1184,7 +1184,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
}
break;
case ISDN_CMD_DIAL:
- if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+ if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
if (card->leased)
break;
@@ -1210,7 +1210,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
}
break;
case ISDN_CMD_ACCEPTD:
- if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+ if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
if (c->arg < ISDNLOOP_BCH) {
a = c->arg + 1;
@@ -1238,7 +1238,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
}
break;
case ISDN_CMD_ACCEPTB:
- if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+ if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
if (c->arg < ISDNLOOP_BCH) {
a = c->arg + 1;
@@ -1264,7 +1264,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
break;
case ISDN_CMD_HANGUP:
- if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+ if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
if (c->arg < ISDNLOOP_BCH) {
a = c->arg + 1;
@@ -1273,7 +1273,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
}
break;
case ISDN_CMD_SETEAZ:
- if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+ if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
if (card->leased)
break;
@@ -1303,7 +1303,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
}
break;
case ISDN_CMD_SETL2:
- if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+ if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
if ((c->arg & 255) < ISDNLOOP_BCH) {
a = c->arg;
@@ -1395,7 +1395,7 @@ if_readstatus(u_char __user *buf, int len, int id, int channel)
isdnloop_card *card = isdnloop_findcard(id);
if (card) {
- if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+ if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
return (isdnloop_readstatus(buf, len, card));
}
@@ -1410,7 +1410,7 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
isdnloop_card *card = isdnloop_findcard(id);
if (card) {
- if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+ if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
/* ack request stored in skb scratch area */
*(skb->head) = ack;
diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c
index a0585fb6da94..1b1ef3130e6e 100644
--- a/trunk/drivers/md/bitmap.c
+++ b/trunk/drivers/md/bitmap.c
@@ -237,7 +237,7 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
if (!page)
return ERR_PTR(-ENOMEM);
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev, rdev, tmp) {
if (! test_bit(In_sync, &rdev->flags)
|| test_bit(Faulty, &rdev->flags))
continue;
@@ -261,7 +261,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
struct list_head *tmp;
mddev_t *mddev = bitmap->mddev;
- rdev_for_each(rdev, tmp, mddev)
+ ITERATE_RDEV(mddev, rdev, tmp)
if (test_bit(In_sync, &rdev->flags)
&& !test_bit(Faulty, &rdev->flags)) {
int size = PAGE_SIZE;
@@ -1348,38 +1348,14 @@ void bitmap_close_sync(struct bitmap *bitmap)
*/
sector_t sector = 0;
int blocks;
- if (!bitmap)
- return;
+ if (!bitmap) return;
while (sector < bitmap->mddev->resync_max_sectors) {
bitmap_end_sync(bitmap, sector, &blocks, 0);
- sector += blocks;
- }
-}
-
-void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
-{
- sector_t s = 0;
- int blocks;
-
- if (!bitmap)
- return;
- if (sector == 0) {
- bitmap->last_end_sync = jiffies;
- return;
- }
- if (time_before(jiffies, (bitmap->last_end_sync
- + bitmap->daemon_sleep * HZ)))
- return;
- wait_event(bitmap->mddev->recovery_wait,
- atomic_read(&bitmap->mddev->recovery_active) == 0);
-
- sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
- s = 0;
- while (s < sector && s < bitmap->mddev->resync_max_sectors) {
- bitmap_end_sync(bitmap, s, &blocks, 0);
- s += blocks;
+/*
+ if (sector < 500) printk("bitmap_close_sync: sec %llu blks %d\n",
+ (unsigned long long)sector, blocks);
+*/ sector += blocks;
}
- bitmap->last_end_sync = jiffies;
}
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
@@ -1589,4 +1565,3 @@ EXPORT_SYMBOL(bitmap_start_sync);
EXPORT_SYMBOL(bitmap_end_sync);
EXPORT_SYMBOL(bitmap_unplug);
EXPORT_SYMBOL(bitmap_close_sync);
-EXPORT_SYMBOL(bitmap_cond_end_sync);
diff --git a/trunk/drivers/md/faulty.c b/trunk/drivers/md/faulty.c
index d107ddceefcd..cf2ddce34118 100644
--- a/trunk/drivers/md/faulty.c
+++ b/trunk/drivers/md/faulty.c
@@ -294,7 +294,7 @@ static int run(mddev_t *mddev)
}
conf->nfaults = 0;
- rdev_for_each(rdev, tmp, mddev)
+ ITERATE_RDEV(mddev, rdev, tmp)
conf->rdev = rdev;
mddev->array_size = mddev->size;
diff --git a/trunk/drivers/md/linear.c b/trunk/drivers/md/linear.c
index 0b8511776b3e..3dac1cfb8189 100644
--- a/trunk/drivers/md/linear.c
+++ b/trunk/drivers/md/linear.c
@@ -122,7 +122,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
cnt = 0;
conf->array_size = 0;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
int j = rdev->raid_disk;
dev_info_t *disk = conf->disks + j;
diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c
index 5fc326d3970e..c28a120b4161 100644
--- a/trunk/drivers/md/md.c
+++ b/trunk/drivers/md/md.c
@@ -195,7 +195,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
* Any code which breaks out of this loop while own
* a reference to the current mddev and must mddev_put it.
*/
-#define for_each_mddev(mddev,tmp) \
+#define ITERATE_MDDEV(mddev,tmp) \
\
for (({ spin_lock(&all_mddevs_lock); \
tmp = all_mddevs.next; \
@@ -275,7 +275,6 @@ static mddev_t * mddev_find(dev_t unit)
spin_lock_init(&new->write_lock);
init_waitqueue_head(&new->sb_wait);
new->reshape_position = MaxSector;
- new->resync_max = MaxSector;
new->queue = blk_alloc_queue(GFP_KERNEL);
if (!new->queue) {
@@ -311,7 +310,7 @@ static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
mdk_rdev_t * rdev;
struct list_head *tmp;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
if (rdev->desc_nr == nr)
return rdev;
}
@@ -323,7 +322,7 @@ static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev)
struct list_head *tmp;
mdk_rdev_t *rdev;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
if (rdev->bdev->bd_dev == dev)
return rdev;
}
@@ -774,16 +773,12 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
__u64 ev1 = md_event(sb);
rdev->raid_disk = -1;
- clear_bit(Faulty, &rdev->flags);
- clear_bit(In_sync, &rdev->flags);
- clear_bit(WriteMostly, &rdev->flags);
- clear_bit(BarriersNotsupp, &rdev->flags);
-
+ rdev->flags = 0;
if (mddev->raid_disks == 0) {
mddev->major_version = 0;
mddev->minor_version = sb->minor_version;
mddev->patch_version = sb->patch_version;
- mddev->external = 0;
+ mddev->persistent = ! sb->not_persistent;
mddev->chunk_size = sb->chunk_size;
mddev->ctime = sb->ctime;
mddev->utime = sb->utime;
@@ -909,7 +904,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->size = mddev->size;
sb->raid_disks = mddev->raid_disks;
sb->md_minor = mddev->md_minor;
- sb->not_persistent = 0;
+ sb->not_persistent = !mddev->persistent;
sb->utime = mddev->utime;
sb->state = 0;
sb->events_hi = (mddev->events>>32);
@@ -943,7 +938,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->state |= (1<disks[0].state = (1<raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
@@ -1158,15 +1153,11 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
__u64 ev1 = le64_to_cpu(sb->events);
rdev->raid_disk = -1;
- clear_bit(Faulty, &rdev->flags);
- clear_bit(In_sync, &rdev->flags);
- clear_bit(WriteMostly, &rdev->flags);
- clear_bit(BarriersNotsupp, &rdev->flags);
-
+ rdev->flags = 0;
if (mddev->raid_disks == 0) {
mddev->major_version = 1;
mddev->patch_version = 0;
- mddev->external = 0;
+ mddev->persistent = 1;
mddev->chunk_size = le32_to_cpu(sb->chunksize) << 9;
mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1);
mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1);
@@ -1295,7 +1286,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
}
max_dev = 0;
- rdev_for_each(rdev2, tmp, mddev)
+ ITERATE_RDEV(mddev,rdev2,tmp)
if (rdev2->desc_nr+1 > max_dev)
max_dev = rdev2->desc_nr+1;
@@ -1304,7 +1295,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
for (i=0; idev_roles[i] = cpu_to_le16(0xfffe);
- rdev_for_each(rdev2, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev2,tmp) {
i = rdev2->desc_nr;
if (test_bit(Faulty, &rdev2->flags))
sb->dev_roles[i] = cpu_to_le16(0xfffe);
@@ -1342,8 +1333,8 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
struct list_head *tmp, *tmp2;
mdk_rdev_t *rdev, *rdev2;
- rdev_for_each(rdev, tmp, mddev1)
- rdev_for_each(rdev2, tmp2, mddev2)
+ ITERATE_RDEV(mddev1,rdev,tmp)
+ ITERATE_RDEV(mddev2, rdev2, tmp2)
if (rdev->bdev->bd_contains ==
rdev2->bdev->bd_contains)
return 1;
@@ -1410,7 +1401,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
goto fail;
}
list_add(&rdev->same_set, &mddev->disks);
- bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk);
+ bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk);
return 0;
fail:
@@ -1419,11 +1410,10 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
return err;
}
-static void md_delayed_delete(struct work_struct *ws)
+static void delayed_delete(struct work_struct *ws)
{
mdk_rdev_t *rdev = container_of(ws, mdk_rdev_t, del_work);
kobject_del(&rdev->kobj);
- kobject_put(&rdev->kobj);
}
static void unbind_rdev_from_array(mdk_rdev_t * rdev)
@@ -1442,8 +1432,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
/* We need to delay this, otherwise we can deadlock when
* writing to 'remove' to "dev/state"
*/
- INIT_WORK(&rdev->del_work, md_delayed_delete);
- kobject_get(&rdev->kobj);
+ INIT_WORK(&rdev->del_work, delayed_delete);
schedule_work(&rdev->del_work);
}
@@ -1452,7 +1441,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
* otherwise reused by a RAID array (or any other kernel
* subsystem), by bd_claiming the device.
*/
-static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared)
+static int lock_rdev(mdk_rdev_t *rdev, dev_t dev)
{
int err = 0;
struct block_device *bdev;
@@ -1464,15 +1453,13 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared)
__bdevname(dev, b));
return PTR_ERR(bdev);
}
- err = bd_claim(bdev, shared ? (mdk_rdev_t *)lock_rdev : rdev);
+ err = bd_claim(bdev, rdev);
if (err) {
printk(KERN_ERR "md: could not bd_claim %s.\n",
bdevname(bdev, b));
blkdev_put(bdev);
return err;
}
- if (!shared)
- set_bit(AllReserved, &rdev->flags);
rdev->bdev = bdev;
return err;
}
@@ -1516,7 +1503,7 @@ static void export_array(mddev_t *mddev)
struct list_head *tmp;
mdk_rdev_t *rdev;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
if (!rdev->mddev) {
MD_BUG();
continue;
@@ -1594,17 +1581,17 @@ static void md_print_devices(void)
printk("md: **********************************\n");
printk("md: * *\n");
printk("md: **********************************\n");
- for_each_mddev(mddev, tmp) {
+ ITERATE_MDDEV(mddev,tmp) {
if (mddev->bitmap)
bitmap_print_sb(mddev->bitmap);
else
printk("%s: ", mdname(mddev));
- rdev_for_each(rdev, tmp2, mddev)
+ ITERATE_RDEV(mddev,rdev,tmp2)
printk("<%s>", bdevname(rdev->bdev,b));
printk("\n");
- rdev_for_each(rdev, tmp2, mddev)
+ ITERATE_RDEV(mddev,rdev,tmp2)
print_rdev(rdev);
}
printk("md: **********************************\n");
@@ -1623,7 +1610,7 @@ static void sync_sbs(mddev_t * mddev, int nospares)
mdk_rdev_t *rdev;
struct list_head *tmp;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
if (rdev->sb_events == mddev->events ||
(nospares &&
rdev->raid_disk < 0 &&
@@ -1709,20 +1696,18 @@ static void md_update_sb(mddev_t * mddev, int force_change)
MD_BUG();
mddev->events --;
}
+ sync_sbs(mddev, nospares);
/*
* do not write anything to disk if using
* nonpersistent superblocks
*/
if (!mddev->persistent) {
- if (!mddev->external)
- clear_bit(MD_CHANGE_PENDING, &mddev->flags);
-
+ clear_bit(MD_CHANGE_PENDING, &mddev->flags);
spin_unlock_irq(&mddev->write_lock);
wake_up(&mddev->sb_wait);
return;
}
- sync_sbs(mddev, nospares);
spin_unlock_irq(&mddev->write_lock);
dprintk(KERN_INFO
@@ -1730,7 +1715,7 @@ static void md_update_sb(mddev_t * mddev, int force_change)
mdname(mddev),mddev->in_sync);
bitmap_update_sb(mddev->bitmap);
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
char b[BDEVNAME_SIZE];
dprintk(KERN_INFO "md: ");
if (rdev->sb_loaded != 1)
@@ -1800,7 +1785,7 @@ static ssize_t
state_show(mdk_rdev_t *rdev, char *page)
{
char *sep = "";
- size_t len = 0;
+ int len=0;
if (test_bit(Faulty, &rdev->flags)) {
len+= sprintf(page+len, "%sfaulty",sep);
@@ -1902,45 +1887,20 @@ static ssize_t
slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
{
char *e;
- int err;
- char nm[20];
int slot = simple_strtoul(buf, &e, 10);
if (strncmp(buf, "none", 4)==0)
slot = -1;
else if (e==buf || (*e && *e!= '\n'))
return -EINVAL;
- if (rdev->mddev->pers) {
- /* Setting 'slot' on an active array requires also
- * updating the 'rd%d' link, and communicating
- * with the personality with ->hot_*_disk.
- * For now we only support removing
- * failed/spare devices. This normally happens automatically,
- * but not when the metadata is externally managed.
- */
- if (slot != -1)
- return -EBUSY;
- if (rdev->raid_disk == -1)
- return -EEXIST;
- /* personality does all needed checks */
- if (rdev->mddev->pers->hot_add_disk == NULL)
- return -EINVAL;
- err = rdev->mddev->pers->
- hot_remove_disk(rdev->mddev, rdev->raid_disk);
- if (err)
- return err;
- sprintf(nm, "rd%d", rdev->raid_disk);
- sysfs_remove_link(&rdev->mddev->kobj, nm);
- set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery);
- md_wakeup_thread(rdev->mddev->thread);
- } else {
- if (slot >= rdev->mddev->raid_disks)
- return -ENOSPC;
- rdev->raid_disk = slot;
- /* assume it is working */
- clear_bit(Faulty, &rdev->flags);
- clear_bit(WriteMostly, &rdev->flags);
- set_bit(In_sync, &rdev->flags);
- }
+ if (rdev->mddev->pers)
+ /* Cannot set slot in active array (yet) */
+ return -EBUSY;
+ if (slot >= rdev->mddev->raid_disks)
+ return -ENOSPC;
+ rdev->raid_disk = slot;
+ /* assume it is working */
+ rdev->flags = 0;
+ set_bit(In_sync, &rdev->flags);
return len;
}
@@ -1963,10 +1923,6 @@ offset_store(mdk_rdev_t *rdev, const char *buf, size_t len)
return -EINVAL;
if (rdev->mddev->pers)
return -EBUSY;
- if (rdev->size && rdev->mddev->external)
- /* Must set offset before size, so overlap checks
- * can be sane */
- return -EBUSY;
rdev->data_offset = offset;
return len;
}
@@ -1980,69 +1936,16 @@ rdev_size_show(mdk_rdev_t *rdev, char *page)
return sprintf(page, "%llu\n", (unsigned long long)rdev->size);
}
-static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
-{
- /* check if two start/length pairs overlap */
- if (s1+l1 <= s2)
- return 0;
- if (s2+l2 <= s1)
- return 0;
- return 1;
-}
-
static ssize_t
rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
{
char *e;
unsigned long long size = simple_strtoull(buf, &e, 10);
- unsigned long long oldsize = rdev->size;
if (e==buf || (*e && *e != '\n'))
return -EINVAL;
if (rdev->mddev->pers)
return -EBUSY;
rdev->size = size;
- if (size > oldsize && rdev->mddev->external) {
- /* need to check that all other rdevs with the same ->bdev
- * do not overlap. We need to unlock the mddev to avoid
- * a deadlock. We have already changed rdev->size, and if
- * we have to change it back, we will have the lock again.
- */
- mddev_t *mddev;
- int overlap = 0;
- struct list_head *tmp, *tmp2;
-
- mddev_unlock(rdev->mddev);
- for_each_mddev(mddev, tmp) {
- mdk_rdev_t *rdev2;
-
- mddev_lock(mddev);
- rdev_for_each(rdev2, tmp2, mddev)
- if (test_bit(AllReserved, &rdev2->flags) ||
- (rdev->bdev == rdev2->bdev &&
- rdev != rdev2 &&
- overlaps(rdev->data_offset, rdev->size,
- rdev2->data_offset, rdev2->size))) {
- overlap = 1;
- break;
- }
- mddev_unlock(mddev);
- if (overlap) {
- mddev_put(mddev);
- break;
- }
- }
- mddev_lock(rdev->mddev);
- if (overlap) {
- /* Someone else could have slipped in a size
- * change here, but doing so is just silly.
- * We put oldsize back because we *know* it is
- * safe, and trust userspace not to race with
- * itself
- */
- rdev->size = oldsize;
- return -EBUSY;
- }
- }
if (size < rdev->mddev->size || rdev->mddev->size == 0)
rdev->mddev->size = size;
return len;
@@ -2077,18 +1980,12 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
{
struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
- int rv;
if (!entry->store)
return -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- rv = mddev_lock(rdev->mddev);
- if (!rv) {
- rv = entry->store(rdev, page, length);
- mddev_unlock(rdev->mddev);
- }
- return rv;
+ return entry->store(rdev, page, length);
}
static void rdev_free(struct kobject *ko)
@@ -2132,7 +2029,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
if ((err = alloc_disk_sb(rdev)))
goto abort_free;
- err = lock_rdev(rdev, newdev, super_format == -2);
+ err = lock_rdev(rdev, newdev);
if (err)
goto abort_free;
@@ -2202,7 +2099,7 @@ static void analyze_sbs(mddev_t * mddev)
char b[BDEVNAME_SIZE];
freshest = NULL;
- rdev_for_each(rdev, tmp, mddev)
+ ITERATE_RDEV(mddev,rdev,tmp)
switch (super_types[mddev->major_version].
load_super(rdev, freshest, mddev->minor_version)) {
case 1:
@@ -2223,7 +2120,7 @@ static void analyze_sbs(mddev_t * mddev)
validate_super(mddev, freshest);
i = 0;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
if (rdev != freshest)
if (super_types[mddev->major_version].
validate_super(mddev, rdev)) {
@@ -2318,7 +2215,7 @@ level_show(mddev_t *mddev, char *page)
static ssize_t
level_store(mddev_t *mddev, const char *buf, size_t len)
{
- ssize_t rv = len;
+ int rv = len;
if (mddev->pers)
return -EBUSY;
if (len == 0)
@@ -2528,8 +2425,6 @@ array_state_show(mddev_t *mddev, char *page)
case 0:
if (mddev->in_sync)
st = clean;
- else if (test_bit(MD_CHANGE_CLEAN, &mddev->flags))
- st = write_pending;
else if (mddev->safemode)
st = active_idle;
else
@@ -2560,9 +2455,11 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
break;
case clear:
/* stopping an active array */
- if (atomic_read(&mddev->active) > 1)
- return -EBUSY;
- err = do_md_stop(mddev, 0);
+ if (mddev->pers) {
+ if (atomic_read(&mddev->active) > 1)
+ return -EBUSY;
+ err = do_md_stop(mddev, 0);
+ }
break;
case inactive:
/* stopping an active array */
@@ -2570,8 +2467,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
if (atomic_read(&mddev->active) > 1)
return -EBUSY;
err = do_md_stop(mddev, 2);
- } else
- err = 0; /* already inactive */
+ }
break;
case suspended:
break; /* not supported yet */
@@ -2599,15 +2495,9 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
restart_array(mddev);
spin_lock_irq(&mddev->write_lock);
if (atomic_read(&mddev->writes_pending) == 0) {
- if (mddev->in_sync == 0) {
- mddev->in_sync = 1;
- if (mddev->persistent)
- set_bit(MD_CHANGE_CLEAN,
- &mddev->flags);
- }
- err = 0;
- } else
- err = -EBUSY;
+ mddev->in_sync = 1;
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ }
spin_unlock_irq(&mddev->write_lock);
} else {
mddev->ro = 0;
@@ -2618,8 +2508,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
case active:
if (mddev->pers) {
restart_array(mddev);
- if (mddev->external)
- clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
wake_up(&mddev->sb_wait);
err = 0;
} else {
@@ -2685,9 +2574,7 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len)
if (err < 0)
goto out;
}
- } else if (mddev->external)
- rdev = md_import_device(dev, -2, -1);
- else
+ } else
rdev = md_import_device(dev, -1, -1);
if (IS_ERR(rdev))
@@ -2772,9 +2659,7 @@ __ATTR(component_size, S_IRUGO|S_IWUSR, size_show, size_store);
/* Metdata version.
- * This is one of
- * 'none' for arrays with no metadata (good luck...)
- * 'external' for arrays with externally managed metadata,
+ * This is either 'none' for arrays with externally managed metadata,
* or N.M for internally known formats
*/
static ssize_t
@@ -2783,8 +2668,6 @@ metadata_show(mddev_t *mddev, char *page)
if (mddev->persistent)
return sprintf(page, "%d.%d\n",
mddev->major_version, mddev->minor_version);
- else if (mddev->external)
- return sprintf(page, "external:%s\n", mddev->metadata_type);
else
return sprintf(page, "none\n");
}
@@ -2799,21 +2682,6 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
if (cmd_match(buf, "none")) {
mddev->persistent = 0;
- mddev->external = 0;
- mddev->major_version = 0;
- mddev->minor_version = 90;
- return len;
- }
- if (strncmp(buf, "external:", 9) == 0) {
- size_t namelen = len-9;
- if (namelen >= sizeof(mddev->metadata_type))
- namelen = sizeof(mddev->metadata_type)-1;
- strncpy(mddev->metadata_type, buf+9, namelen);
- mddev->metadata_type[namelen] = 0;
- if (namelen && mddev->metadata_type[namelen-1] == '\n')
- mddev->metadata_type[--namelen] = 0;
- mddev->persistent = 0;
- mddev->external = 1;
mddev->major_version = 0;
mddev->minor_version = 90;
return len;
@@ -2830,7 +2698,6 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
mddev->major_version = major;
mddev->minor_version = minor;
mddev->persistent = 1;
- mddev->external = 0;
return len;
}
@@ -2997,43 +2864,6 @@ sync_completed_show(mddev_t *mddev, char *page)
static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
-static ssize_t
-max_sync_show(mddev_t *mddev, char *page)
-{
- if (mddev->resync_max == MaxSector)
- return sprintf(page, "max\n");
- else
- return sprintf(page, "%llu\n",
- (unsigned long long)mddev->resync_max);
-}
-static ssize_t
-max_sync_store(mddev_t *mddev, const char *buf, size_t len)
-{
- if (strncmp(buf, "max", 3) == 0)
- mddev->resync_max = MaxSector;
- else {
- char *ep;
- unsigned long long max = simple_strtoull(buf, &ep, 10);
- if (ep == buf || (*ep != 0 && *ep != '\n'))
- return -EINVAL;
- if (max < mddev->resync_max &&
- test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
- return -EBUSY;
-
- /* Must be a multiple of chunk_size */
- if (mddev->chunk_size) {
- if (max & (sector_t)((mddev->chunk_size>>9)-1))
- return -EINVAL;
- }
- mddev->resync_max = max;
- }
- wake_up(&mddev->recovery_wait);
- return len;
-}
-
-static struct md_sysfs_entry md_max_sync =
-__ATTR(sync_max, S_IRUGO|S_IWUSR, max_sync_show, max_sync_store);
-
static ssize_t
suspend_lo_show(mddev_t *mddev, char *page)
{
@@ -3144,7 +2974,6 @@ static struct attribute *md_redundancy_attrs[] = {
&md_sync_max.attr,
&md_sync_speed.attr,
&md_sync_completed.attr,
- &md_max_sync.attr,
&md_suspend_lo.attr,
&md_suspend_hi.attr,
&md_bitmap.attr,
@@ -3289,11 +3118,8 @@ static int do_md_run(mddev_t * mddev)
/*
* Analyze all RAID superblock(s)
*/
- if (!mddev->raid_disks) {
- if (!mddev->persistent)
- return -EINVAL;
+ if (!mddev->raid_disks)
analyze_sbs(mddev);
- }
chunk_size = mddev->chunk_size;
@@ -3317,7 +3143,7 @@ static int do_md_run(mddev_t * mddev)
}
/* devices must have minimum size of one chunk */
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
if (test_bit(Faulty, &rdev->flags))
continue;
if (rdev->size < chunk_size / 1024) {
@@ -3344,7 +3170,7 @@ static int do_md_run(mddev_t * mddev)
* the only valid external interface is through the md
* device.
*/
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
if (test_bit(Faulty, &rdev->flags))
continue;
sync_blockdev(rdev->bdev);
@@ -3410,8 +3236,8 @@ static int do_md_run(mddev_t * mddev)
mdk_rdev_t *rdev2;
struct list_head *tmp2;
int warned = 0;
- rdev_for_each(rdev, tmp, mddev) {
- rdev_for_each(rdev2, tmp2, mddev) {
+ ITERATE_RDEV(mddev, rdev, tmp) {
+ ITERATE_RDEV(mddev, rdev2, tmp2) {
if (rdev < rdev2 &&
rdev->bdev->bd_contains ==
rdev2->bdev->bd_contains) {
@@ -3471,7 +3297,7 @@ static int do_md_run(mddev_t * mddev)
mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */
mddev->in_sync = 1;
- rdev_for_each(rdev, tmp, mddev)
+ ITERATE_RDEV(mddev,rdev,tmp)
if (rdev->raid_disk >= 0) {
char nm[20];
sprintf(nm, "rd%d", rdev->raid_disk);
@@ -3504,7 +3330,7 @@ static int do_md_run(mddev_t * mddev)
if (mddev->degraded && !mddev->sync_thread) {
struct list_head *rtmp;
int spares = 0;
- rdev_for_each(rdev, rtmp, mddev)
+ ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk >= 0 &&
!test_bit(In_sync, &rdev->flags) &&
!test_bit(Faulty, &rdev->flags))
@@ -3681,14 +3507,14 @@ static int do_md_stop(mddev_t * mddev, int mode)
}
mddev->bitmap_offset = 0;
- rdev_for_each(rdev, tmp, mddev)
+ ITERATE_RDEV(mddev,rdev,tmp)
if (rdev->raid_disk >= 0) {
char nm[20];
sprintf(nm, "rd%d", rdev->raid_disk);
sysfs_remove_link(&mddev->kobj, nm);
}
- /* make sure all md_delayed_delete calls have finished */
+ /* make sure all delayed_delete calls have finished */
flush_scheduled_work();
export_array(mddev);
@@ -3697,10 +3523,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
mddev->size = 0;
mddev->raid_disks = 0;
mddev->recovery_cp = 0;
- mddev->resync_max = MaxSector;
mddev->reshape_position = MaxSector;
- mddev->external = 0;
- mddev->persistent = 0;
} else if (mddev->pers)
printk(KERN_INFO "md: %s switched to read-only mode.\n",
@@ -3723,7 +3546,7 @@ static void autorun_array(mddev_t *mddev)
printk(KERN_INFO "md: running: ");
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
char b[BDEVNAME_SIZE];
printk("<%s>", bdevname(rdev->bdev,b));
}
@@ -3766,7 +3589,7 @@ static void autorun_devices(int part)
printk(KERN_INFO "md: considering %s ...\n",
bdevname(rdev0->bdev,b));
INIT_LIST_HEAD(&candidates);
- rdev_for_each_list(rdev, tmp, pending_raid_disks)
+ ITERATE_RDEV_PENDING(rdev,tmp)
if (super_90_load(rdev, rdev0, 0) >= 0) {
printk(KERN_INFO "md: adding %s ...\n",
bdevname(rdev->bdev,b));
@@ -3809,8 +3632,7 @@ static void autorun_devices(int part)
mddev_unlock(mddev);
} else {
printk(KERN_INFO "md: created %s\n", mdname(mddev));
- mddev->persistent = 1;
- rdev_for_each_list(rdev, tmp, candidates) {
+ ITERATE_RDEV_GENERIC(candidates,rdev,tmp) {
list_del_init(&rdev->same_set);
if (bind_rdev_to_array(rdev, mddev))
export_rdev(rdev);
@@ -3821,7 +3643,7 @@ static void autorun_devices(int part)
/* on success, candidates will be empty, on error
* it won't...
*/
- rdev_for_each_list(rdev, tmp, candidates)
+ ITERATE_RDEV_GENERIC(candidates,rdev,tmp)
export_rdev(rdev);
mddev_put(mddev);
}
@@ -3851,7 +3673,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
struct list_head *tmp;
nr=working=active=failed=spare=0;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
nr++;
if (test_bit(Faulty, &rdev->flags))
failed++;
@@ -4097,6 +3919,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
else
rdev->raid_disk = -1;
+ rdev->flags = 0;
+
if (rdev->raid_disk < mddev->raid_disks)
if (info->state & (1<flags);
@@ -4341,15 +4165,13 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
else
mddev->recovery_cp = 0;
mddev->persistent = ! info->not_persistent;
- mddev->external = 0;
mddev->layout = info->layout;
mddev->chunk_size = info->chunk_size;
mddev->max_disks = MD_SB_DISKS;
- if (mddev->persistent)
- mddev->flags = 0;
+ mddev->flags = 0;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
@@ -4391,7 +4213,7 @@ static int update_size(mddev_t *mddev, unsigned long size)
*/
if (mddev->sync_thread)
return -EBUSY;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
sector_t avail;
avail = rdev->size * 2;
@@ -4649,10 +4471,9 @@ static int md_ioctl(struct inode *inode, struct file *file,
*/
/* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY,
* RUN_ARRAY, and GET_ and SET_BITMAP_FILE are allowed */
- if ((!mddev->raid_disks && !mddev->external)
- && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY
- && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE
- && cmd != GET_BITMAP_FILE) {
+ if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY
+ && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE
+ && cmd != GET_BITMAP_FILE) {
err = -ENODEV;
goto abort_unlock;
}
@@ -4936,7 +4757,7 @@ static void status_unused(struct seq_file *seq)
seq_printf(seq, "unused devices: ");
- rdev_for_each_list(rdev, tmp, pending_raid_disks) {
+ ITERATE_RDEV_PENDING(rdev,tmp) {
char b[BDEVNAME_SIZE];
i++;
seq_printf(seq, "%s ",
@@ -5132,7 +4953,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
}
size = 0;
- rdev_for_each(rdev, tmp2, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp2) {
char b[BDEVNAME_SIZE];
seq_printf(seq, " %s[%d]",
bdevname(rdev->bdev,b), rdev->desc_nr);
@@ -5161,10 +4982,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
mddev->major_version,
mddev->minor_version);
}
- } else if (mddev->external)
- seq_printf(seq, " super external:%s",
- mddev->metadata_type);
- else
+ } else
seq_printf(seq, " super non-persistent");
if (mddev->pers) {
@@ -5288,7 +5106,7 @@ static int is_mddev_idle(mddev_t *mddev)
long curr_events;
idle = 1;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
curr_events = disk_stat_read(disk, sectors[0]) +
disk_stat_read(disk, sectors[1]) -
@@ -5465,7 +5283,7 @@ void md_do_sync(mddev_t *mddev)
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
goto skip;
}
- for_each_mddev(mddev2, tmp) {
+ ITERATE_MDDEV(mddev2,tmp) {
if (mddev2 == mddev)
continue;
if (mddev2->curr_resync &&
@@ -5515,7 +5333,7 @@ void md_do_sync(mddev_t *mddev)
/* recovery follows the physical size of devices */
max_sectors = mddev->size << 1;
j = MaxSector;
- rdev_for_each(rdev, rtmp, mddev)
+ ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk >= 0 &&
!test_bit(Faulty, &rdev->flags) &&
!test_bit(In_sync, &rdev->flags) &&
@@ -5563,16 +5381,8 @@ void md_do_sync(mddev_t *mddev)
sector_t sectors;
skipped = 0;
- if (j >= mddev->resync_max) {
- sysfs_notify(&mddev->kobj, NULL, "sync_completed");
- wait_event(mddev->recovery_wait,
- mddev->resync_max > j
- || kthread_should_stop());
- }
- if (kthread_should_stop())
- goto interrupted;
sectors = mddev->pers->sync_request(mddev, j, &skipped,
- currspeed < speed_min(mddev));
+ currspeed < speed_min(mddev));
if (sectors == 0) {
set_bit(MD_RECOVERY_ERR, &mddev->recovery);
goto out;
@@ -5614,9 +5424,15 @@ void md_do_sync(mddev_t *mddev)
}
- if (kthread_should_stop())
- goto interrupted;
-
+ if (kthread_should_stop()) {
+ /*
+ * got a signal, exit.
+ */
+ printk(KERN_INFO
+ "md: md_do_sync() got signal ... exiting\n");
+ set_bit(MD_RECOVERY_INTR, &mddev->recovery);
+ goto out;
+ }
/*
* this loop exits only if either when we are slower than
@@ -5668,7 +5484,7 @@ void md_do_sync(mddev_t *mddev)
} else {
if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
mddev->curr_resync = MaxSector;
- rdev_for_each(rdev, rtmp, mddev)
+ ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk >= 0 &&
!test_bit(Faulty, &rdev->flags) &&
!test_bit(In_sync, &rdev->flags) &&
@@ -5680,22 +5496,9 @@ void md_do_sync(mddev_t *mddev)
skip:
mddev->curr_resync = 0;
- mddev->resync_max = MaxSector;
- sysfs_notify(&mddev->kobj, NULL, "sync_completed");
wake_up(&resync_wait);
set_bit(MD_RECOVERY_DONE, &mddev->recovery);
md_wakeup_thread(mddev->thread);
- return;
-
- interrupted:
- /*
- * got a signal, exit.
- */
- printk(KERN_INFO
- "md: md_do_sync() got signal ... exiting\n");
- set_bit(MD_RECOVERY_INTR, &mddev->recovery);
- goto out;
-
}
EXPORT_SYMBOL_GPL(md_do_sync);
@@ -5706,9 +5509,8 @@ static int remove_and_add_spares(mddev_t *mddev)
struct list_head *rtmp;
int spares = 0;
- rdev_for_each(rdev, rtmp, mddev)
+ ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk >= 0 &&
- !mddev->external &&
(test_bit(Faulty, &rdev->flags) ||
! test_bit(In_sync, &rdev->flags)) &&
atomic_read(&rdev->nr_pending)==0) {
@@ -5722,7 +5524,7 @@ static int remove_and_add_spares(mddev_t *mddev)
}
if (mddev->degraded) {
- rdev_for_each(rdev, rtmp, mddev)
+ ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk < 0
&& !test_bit(Faulty, &rdev->flags)) {
rdev->recovery_offset = 0;
@@ -5787,7 +5589,7 @@ void md_check_recovery(mddev_t *mddev)
}
if ( ! (
- (mddev->flags && !mddev->external) ||
+ mddev->flags ||
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
(mddev->safemode == 1) ||
@@ -5803,8 +5605,7 @@ void md_check_recovery(mddev_t *mddev)
if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
!mddev->in_sync && mddev->recovery_cp == MaxSector) {
mddev->in_sync = 1;
- if (mddev->persistent)
- set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
}
if (mddev->safemode == 1)
mddev->safemode = 0;
@@ -5836,7 +5637,7 @@ void md_check_recovery(mddev_t *mddev)
* information must be scrapped
*/
if (!mddev->degraded)
- rdev_for_each(rdev, rtmp, mddev)
+ ITERATE_RDEV(mddev,rdev,rtmp)
rdev->saved_raid_disk = -1;
mddev->recovery = 0;
@@ -5913,7 +5714,7 @@ static int md_notify_reboot(struct notifier_block *this,
printk(KERN_INFO "md: stopping all md devices.\n");
- for_each_mddev(mddev, tmp)
+ ITERATE_MDDEV(mddev,tmp)
if (mddev_trylock(mddev)) {
do_md_stop (mddev, 1);
mddev_unlock(mddev);
@@ -6047,7 +5848,7 @@ static __exit void md_exit(void)
unregister_reboot_notifier(&md_notifier);
unregister_sysctl_table(raid_table_header);
remove_proc_entry("mdstat", NULL);
- for_each_mddev(mddev, tmp) {
+ ITERATE_MDDEV(mddev,tmp) {
struct gendisk *disk = mddev->gendisk;
if (!disk)
continue;
diff --git a/trunk/drivers/md/mktables.c b/trunk/drivers/md/mktables.c
index b61d5767aae7..adef299908cf 100644
--- a/trunk/drivers/md/mktables.c
+++ b/trunk/drivers/md/mktables.c
@@ -1,10 +1,13 @@
-/* -*- linux-c -*- ------------------------------------------------------- *
+#ident "$Id: mktables.c,v 1.2 2002/12/12 22:41:27 hpa Exp $"
+/* ----------------------------------------------------------------------- *
*
- * Copyright 2002-2007 H. Peter Anvin - All Rights Reserved
+ * Copyright 2002 H. Peter Anvin - All Rights Reserved
*
- * This file is part of the Linux kernel, and is made available under
- * the terms of the GNU General Public License version 2 or (at your
- * option) any later version; incorporated herein by reference.
+ * 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, Inc., 53 Temple Place Ste 330,
+ * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -23,98 +26,100 @@
static uint8_t gfmul(uint8_t a, uint8_t b)
{
- uint8_t v = 0;
-
- while (b) {
- if (b & 1)
- v ^= a;
- a = (a << 1) ^ (a & 0x80 ? 0x1d : 0);
- b >>= 1;
- }
-
- return v;
+ uint8_t v = 0;
+
+ while ( b ) {
+ if ( b & 1 ) v ^= a;
+ a = (a << 1) ^ (a & 0x80 ? 0x1d : 0);
+ b >>= 1;
+ }
+ return v;
}
static uint8_t gfpow(uint8_t a, int b)
{
- uint8_t v = 1;
-
- b %= 255;
- if (b < 0)
- b += 255;
-
- while (b) {
- if (b & 1)
- v = gfmul(v, a);
- a = gfmul(a, a);
- b >>= 1;
- }
-
- return v;
+ uint8_t v = 1;
+
+ b %= 255;
+ if ( b < 0 )
+ b += 255;
+
+ while ( b ) {
+ if ( b & 1 ) v = gfmul(v,a);
+ a = gfmul(a,a);
+ b >>= 1;
+ }
+ return v;
}
int main(int argc, char *argv[])
{
- int i, j, k;
- uint8_t v;
- uint8_t exptbl[256], invtbl[256];
-
- printf("#include \"raid6.h\"\n");
-
- /* Compute multiplication table */
- printf("\nconst u8 __attribute__((aligned(256)))\n"
- "raid6_gfmul[256][256] =\n"
- "{\n");
- for (i = 0; i < 256; i++) {
- printf("\t{\n");
- for (j = 0; j < 256; j += 8) {
- printf("\t\t");
- for (k = 0; k < 8; k++)
- printf("0x%02x,%c", gfmul(i, j + k),
- (k == 7) ? '\n' : ' ');
- }
- printf("\t},\n");
- }
- printf("};\n");
-
- /* Compute power-of-2 table (exponent) */
- v = 1;
- printf("\nconst u8 __attribute__((aligned(256)))\n"
- "raid6_gfexp[256] =\n" "{\n");
- for (i = 0; i < 256; i += 8) {
- printf("\t");
- for (j = 0; j < 8; j++) {
- exptbl[i + j] = v;
- printf("0x%02x,%c", v, (j == 7) ? '\n' : ' ');
- v = gfmul(v, 2);
- if (v == 1)
- v = 0; /* For entry 255, not a real entry */
- }
- }
- printf("};\n");
-
- /* Compute inverse table x^-1 == x^254 */
- printf("\nconst u8 __attribute__((aligned(256)))\n"
- "raid6_gfinv[256] =\n" "{\n");
- for (i = 0; i < 256; i += 8) {
- printf("\t");
- for (j = 0; j < 8; j++) {
- invtbl[i + j] = v = gfpow(i + j, 254);
- printf("0x%02x,%c", v, (j == 7) ? '\n' : ' ');
- }
- }
- printf("};\n");
-
- /* Compute inv(2^x + 1) (exponent-xor-inverse) table */
- printf("\nconst u8 __attribute__((aligned(256)))\n"
- "raid6_gfexi[256] =\n" "{\n");
- for (i = 0; i < 256; i += 8) {
- printf("\t");
- for (j = 0; j < 8; j++)
- printf("0x%02x,%c", invtbl[exptbl[i + j] ^ 1],
- (j == 7) ? '\n' : ' ');
- }
- printf("};\n");
-
- return 0;
+ int i, j, k;
+ uint8_t v;
+ uint8_t exptbl[256], invtbl[256];
+
+ printf("#include \"raid6.h\"\n");
+
+ /* Compute multiplication table */
+ printf("\nconst u8 __attribute__((aligned(256)))\n"
+ "raid6_gfmul[256][256] =\n"
+ "{\n");
+ for ( i = 0 ; i < 256 ; i++ ) {
+ printf("\t{\n");
+ for ( j = 0 ; j < 256 ; j += 8 ) {
+ printf("\t\t");
+ for ( k = 0 ; k < 8 ; k++ ) {
+ printf("0x%02x, ", gfmul(i,j+k));
+ }
+ printf("\n");
+ }
+ printf("\t},\n");
+ }
+ printf("};\n");
+
+ /* Compute power-of-2 table (exponent) */
+ v = 1;
+ printf("\nconst u8 __attribute__((aligned(256)))\n"
+ "raid6_gfexp[256] =\n"
+ "{\n");
+ for ( i = 0 ; i < 256 ; i += 8 ) {
+ printf("\t");
+ for ( j = 0 ; j < 8 ; j++ ) {
+ exptbl[i+j] = v;
+ printf("0x%02x, ", v);
+ v = gfmul(v,2);
+ if ( v == 1 ) v = 0; /* For entry 255, not a real entry */
+ }
+ printf("\n");
+ }
+ printf("};\n");
+
+ /* Compute inverse table x^-1 == x^254 */
+ printf("\nconst u8 __attribute__((aligned(256)))\n"
+ "raid6_gfinv[256] =\n"
+ "{\n");
+ for ( i = 0 ; i < 256 ; i += 8 ) {
+ printf("\t");
+ for ( j = 0 ; j < 8 ; j++ ) {
+ invtbl[i+j] = v = gfpow(i+j,254);
+ printf("0x%02x, ", v);
+ }
+ printf("\n");
+ }
+ printf("};\n");
+
+ /* Compute inv(2^x + 1) (exponent-xor-inverse) table */
+ printf("\nconst u8 __attribute__((aligned(256)))\n"
+ "raid6_gfexi[256] =\n"
+ "{\n");
+ for ( i = 0 ; i < 256 ; i += 8 ) {
+ printf("\t");
+ for ( j = 0 ; j < 8 ; j++ ) {
+ printf("0x%02x, ", invtbl[exptbl[i+j]^1]);
+ }
+ printf("\n");
+ }
+ printf("};\n\n");
+
+ return 0;
}
diff --git a/trunk/drivers/md/multipath.c b/trunk/drivers/md/multipath.c
index 3f299d835a2b..eb631ebed686 100644
--- a/trunk/drivers/md/multipath.c
+++ b/trunk/drivers/md/multipath.c
@@ -436,7 +436,7 @@ static int multipath_run (mddev_t *mddev)
}
conf->working_disks = 0;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
disk_idx = rdev->raid_disk;
if (disk_idx < 0 ||
disk_idx >= mddev->raid_disks)
diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c
index 818b48284096..f8e591708d1f 100644
--- a/trunk/drivers/md/raid0.c
+++ b/trunk/drivers/md/raid0.c
@@ -72,11 +72,11 @@ static int create_strip_zones (mddev_t *mddev)
*/
conf->nr_strip_zones = 0;
- rdev_for_each(rdev1, tmp1, mddev) {
+ ITERATE_RDEV(mddev,rdev1,tmp1) {
printk("raid0: looking at %s\n",
bdevname(rdev1->bdev,b));
c = 0;
- rdev_for_each(rdev2, tmp2, mddev) {
+ ITERATE_RDEV(mddev,rdev2,tmp2) {
printk("raid0: comparing %s(%llu)",
bdevname(rdev1->bdev,b),
(unsigned long long)rdev1->size);
@@ -124,7 +124,7 @@ static int create_strip_zones (mddev_t *mddev)
cnt = 0;
smallest = NULL;
zone->dev = conf->devlist;
- rdev_for_each(rdev1, tmp1, mddev) {
+ ITERATE_RDEV(mddev, rdev1, tmp1) {
int j = rdev1->raid_disk;
if (j < 0 || j >= mddev->raid_disks) {
@@ -293,7 +293,7 @@ static int raid0_run (mddev_t *mddev)
/* calculate array device size */
mddev->array_size = 0;
- rdev_for_each(rdev, tmp, mddev)
+ ITERATE_RDEV(mddev,rdev,tmp)
mddev->array_size += rdev->size;
printk("raid0 : md_size is %llu blocks.\n",
diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c
index 5c7fef091cec..4a69c416e045 100644
--- a/trunk/drivers/md/raid1.c
+++ b/trunk/drivers/md/raid1.c
@@ -1684,7 +1684,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
if (!go_faster && conf->nr_waiting)
msleep_interruptible(1000);
- bitmap_cond_end_sync(mddev->bitmap, sector_nr);
raise_barrier(conf);
conf->next_resync = sector_nr;
@@ -1767,8 +1766,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return rv;
}
- if (max_sector > mddev->resync_max)
- max_sector = mddev->resync_max; /* Don't do IO beyond here */
nr_sectors = 0;
sync_blocks = 0;
do {
@@ -1887,7 +1884,7 @@ static int run(mddev_t *mddev)
if (!conf->r1bio_pool)
goto out_no_mem;
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev, rdev, tmp) {
disk_idx = rdev->raid_disk;
if (disk_idx >= mddev->raid_disks
|| disk_idx < 0)
diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c
index 017f58113c33..5cdcc9386200 100644
--- a/trunk/drivers/md/raid10.c
+++ b/trunk/drivers/md/raid10.c
@@ -1657,9 +1657,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return (max_sector - sector_nr) + sectors_skipped;
}
- if (max_sector > mddev->resync_max)
- max_sector = mddev->resync_max; /* Don't do IO beyond here */
-
/* make sure whole request will fit in a chunk - if chunks
* are meaningful
*/
@@ -1673,8 +1670,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
if (!go_faster && conf->nr_waiting)
msleep_interruptible(1000);
- bitmap_cond_end_sync(mddev->bitmap, sector_nr);
-
/* Again, very different code for resync and recovery.
* Both must result in an r10bio with a list of bios that
* have bi_end_io, bi_sector, bi_bdev set,
@@ -2026,7 +2021,7 @@ static int run(mddev_t *mddev)
goto out_free_conf;
}
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev, rdev, tmp) {
disk_idx = rdev->raid_disk;
if (disk_idx >= mddev->raid_disks
|| disk_idx < 0)
diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c
index 2d6f1a51359c..e8c8157b02fc 100644
--- a/trunk/drivers/md/raid5.c
+++ b/trunk/drivers/md/raid5.c
@@ -3159,8 +3159,7 @@ static void raid5_activate_delayed(raid5_conf_t *conf)
atomic_inc(&conf->preread_active_stripes);
list_add_tail(&sh->lru, &conf->handle_list);
}
- } else
- blk_plug_device(conf->mddev->queue);
+ }
}
static void activate_bit_delay(raid5_conf_t *conf)
@@ -3550,8 +3549,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
goto retry;
}
finish_wait(&conf->wait_for_overlap, &w);
- set_bit(STRIPE_HANDLE, &sh->state);
- clear_bit(STRIPE_DELAYED, &sh->state);
+ handle_stripe(sh, NULL);
release_stripe(sh);
} else {
/* cannot get stripe for read-ahead, just give-up */
@@ -3700,25 +3698,6 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
release_stripe(sh);
first_sector += STRIPE_SECTORS;
}
- /* If this takes us to the resync_max point where we have to pause,
- * then we need to write out the superblock.
- */
- sector_nr += conf->chunk_size>>9;
- if (sector_nr >= mddev->resync_max) {
- /* Cannot proceed until we've updated the superblock... */
- wait_event(conf->wait_for_overlap,
- atomic_read(&conf->reshape_stripes) == 0);
- mddev->reshape_position = conf->expand_progress;
- set_bit(MD_CHANGE_DEVS, &mddev->flags);
- md_wakeup_thread(mddev->thread);
- wait_event(mddev->sb_wait,
- !test_bit(MD_CHANGE_DEVS, &mddev->flags)
- || kthread_should_stop());
- spin_lock_irq(&conf->device_lock);
- conf->expand_lo = mddev->reshape_position;
- spin_unlock_irq(&conf->device_lock);
- wake_up(&conf->wait_for_overlap);
- }
return conf->chunk_size>>9;
}
@@ -3755,12 +3734,6 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
return reshape_request(mddev, sector_nr, skipped);
- /* No need to check resync_max as we never do more than one
- * stripe, and as resync_max will always be on a chunk boundary,
- * if the check in md_do_sync didn't fire, there is no chance
- * of overstepping resync_max here
- */
-
/* if there is too many failed drives and we are trying
* to resync, then assert that we are finished, because there is
* nothing we can do.
@@ -3780,9 +3753,6 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
}
-
- bitmap_cond_end_sync(mddev->bitmap, sector_nr);
-
pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
if (sh == NULL) {
@@ -3894,7 +3864,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
* During the scan, completed stripes are saved for us by the interrupt
* handler, so that they will not have to wait for our next wakeup.
*/
-static void raid5d(mddev_t *mddev)
+static void raid5d (mddev_t *mddev)
{
struct stripe_head *sh;
raid5_conf_t *conf = mddev_to_conf(mddev);
@@ -3919,6 +3889,12 @@ static void raid5d(mddev_t *mddev)
activate_bit_delay(conf);
}
+ if (list_empty(&conf->handle_list) &&
+ atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD &&
+ !blk_queue_plugged(mddev->queue) &&
+ !list_empty(&conf->delayed_list))
+ raid5_activate_delayed(conf);
+
while ((bio = remove_bio_from_retry(conf))) {
int ok;
spin_unlock_irq(&conf->device_lock);
@@ -4132,7 +4108,7 @@ static int run(mddev_t *mddev)
pr_debug("raid5: run(%s) called.\n", mdname(mddev));
- rdev_for_each(rdev, tmp, mddev) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
raid_disk = rdev->raid_disk;
if (raid_disk >= conf->raid_disks
|| raid_disk < 0)
@@ -4545,7 +4521,7 @@ static int raid5_start_reshape(mddev_t *mddev)
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
return -EBUSY;
- rdev_for_each(rdev, rtmp, mddev)
+ ITERATE_RDEV(mddev, rdev, rtmp)
if (rdev->raid_disk < 0 &&
!test_bit(Faulty, &rdev->flags))
spares++;
@@ -4567,7 +4543,7 @@ static int raid5_start_reshape(mddev_t *mddev)
/* Add some new drives, as many as will fit.
* We know there are enough to make the newly sized array work.
*/
- rdev_for_each(rdev, rtmp, mddev)
+ ITERATE_RDEV(mddev, rdev, rtmp)
if (rdev->raid_disk < 0 &&
!test_bit(Faulty, &rdev->flags)) {
if (raid5_add_disk(mddev, rdev)) {
diff --git a/trunk/drivers/md/raid6test/test.c b/trunk/drivers/md/raid6test/test.c
index 559cc41b2585..0d5cd57accd7 100644
--- a/trunk/drivers/md/raid6test/test.c
+++ b/trunk/drivers/md/raid6test/test.c
@@ -1,10 +1,12 @@
/* -*- linux-c -*- ------------------------------------------------------- *
*
- * Copyright 2002-2007 H. Peter Anvin - All Rights Reserved
+ * Copyright 2002 H. Peter Anvin - All Rights Reserved
*
- * This file is part of the Linux kernel, and is made available under
- * the terms of the GNU General Public License version 2 or (at your
- * option) any later version; incorporated herein by reference.
+ * 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, Inc., 53 Temple Place Ste 330,
+ * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -28,87 +30,67 @@ char *dataptrs[NDISKS];
char data[NDISKS][PAGE_SIZE];
char recovi[PAGE_SIZE], recovj[PAGE_SIZE];
-static void makedata(void)
+void makedata(void)
{
int i, j;
- for (i = 0; i < NDISKS; i++) {
- for (j = 0; j < PAGE_SIZE; j++)
+ for ( i = 0 ; i < NDISKS ; i++ ) {
+ for ( j = 0 ; j < PAGE_SIZE ; j++ ) {
data[i][j] = rand();
-
+ }
dataptrs[i] = data[i];
}
}
-static char disk_type(int d)
-{
- switch (d) {
- case NDISKS-2:
- return 'P';
- case NDISKS-1:
- return 'Q';
- default:
- return 'D';
- }
-}
-
-static int test_disks(int i, int j)
-{
- int erra, errb;
-
- memset(recovi, 0xf0, PAGE_SIZE);
- memset(recovj, 0xba, PAGE_SIZE);
-
- dataptrs[i] = recovi;
- dataptrs[j] = recovj;
-
- raid6_dual_recov(NDISKS, PAGE_SIZE, i, j, (void **)&dataptrs);
-
- erra = memcmp(data[i], recovi, PAGE_SIZE);
- errb = memcmp(data[j], recovj, PAGE_SIZE);
-
- if (i < NDISKS-2 && j == NDISKS-1) {
- /* We don't implement the DQ failure scenario, since it's
- equivalent to a RAID-5 failure (XOR, then recompute Q) */
- erra = errb = 0;
- } else {
- printf("algo=%-8s faila=%3d(%c) failb=%3d(%c) %s\n",
- raid6_call.name,
- i, disk_type(i),
- j, disk_type(j),
- (!erra && !errb) ? "OK" :
- !erra ? "ERRB" :
- !errb ? "ERRA" : "ERRAB");
- }
-
- dataptrs[i] = data[i];
- dataptrs[j] = data[j];
-
- return erra || errb;
-}
-
int main(int argc, char *argv[])
{
- const struct raid6_calls *const *algo;
+ const struct raid6_calls * const * algo;
int i, j;
- int err = 0;
+ int erra, errb;
makedata();
- for (algo = raid6_algos; *algo; algo++) {
- if (!(*algo)->valid || (*algo)->valid()) {
+ for ( algo = raid6_algos ; *algo ; algo++ ) {
+ if ( !(*algo)->valid || (*algo)->valid() ) {
raid6_call = **algo;
/* Nuke syndromes */
memset(data[NDISKS-2], 0xee, 2*PAGE_SIZE);
/* Generate assumed good syndrome */
- raid6_call.gen_syndrome(NDISKS, PAGE_SIZE,
- (void **)&dataptrs);
-
- for (i = 0; i < NDISKS-1; i++)
- for (j = i+1; j < NDISKS; j++)
- err += test_disks(i, j);
+ raid6_call.gen_syndrome(NDISKS, PAGE_SIZE, (void **)&dataptrs);
+
+ for ( i = 0 ; i < NDISKS-1 ; i++ ) {
+ for ( j = i+1 ; j < NDISKS ; j++ ) {
+ memset(recovi, 0xf0, PAGE_SIZE);
+ memset(recovj, 0xba, PAGE_SIZE);
+
+ dataptrs[i] = recovi;
+ dataptrs[j] = recovj;
+
+ raid6_dual_recov(NDISKS, PAGE_SIZE, i, j, (void **)&dataptrs);
+
+ erra = memcmp(data[i], recovi, PAGE_SIZE);
+ errb = memcmp(data[j], recovj, PAGE_SIZE);
+
+ if ( i < NDISKS-2 && j == NDISKS-1 ) {
+ /* We don't implement the DQ failure scenario, since it's
+ equivalent to a RAID-5 failure (XOR, then recompute Q) */
+ } else {
+ printf("algo=%-8s faila=%3d(%c) failb=%3d(%c) %s\n",
+ raid6_call.name,
+ i, (i==NDISKS-2)?'P':'D',
+ j, (j==NDISKS-1)?'Q':(j==NDISKS-2)?'P':'D',
+ (!erra && !errb) ? "OK" :
+ !erra ? "ERRB" :
+ !errb ? "ERRA" :
+ "ERRAB");
+ }
+
+ dataptrs[i] = data[i];
+ dataptrs[j] = data[j];
+ }
+ }
}
printf("\n");
}
@@ -117,8 +99,5 @@ int main(int argc, char *argv[])
/* Pick the best algorithm test */
raid6_select_algo();
- if (err)
- printf("\n*** ERRORS FOUND ***\n");
-
- return err;
+ return 0;
}
diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile
index 850b8c6f4577..28ddd146c1c5 100644
--- a/trunk/drivers/media/video/Makefile
+++ b/trunk/drivers/media/video/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
+obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
diff --git a/trunk/drivers/media/video/tvmixer.c b/trunk/drivers/media/video/tvmixer.c
new file mode 100644
index 000000000000..9fa5b702e073
--- /dev/null
+++ b/trunk/drivers/media/video/tvmixer.c
@@ -0,0 +1,336 @@
+/*
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+
+#define DEV_MAX 4
+
+static int devnr = -1;
+module_param(devnr, int, 0644);
+
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
+
+/* ----------------------------------------------------------------------- */
+
+struct TVMIXER {
+ struct i2c_client *dev;
+ int minor;
+ int count;
+};
+
+static struct TVMIXER devices[DEV_MAX];
+
+static int tvmixer_adapters(struct i2c_adapter *adap);
+static int tvmixer_clients(struct i2c_client *client);
+
+/* ----------------------------------------------------------------------- */
+
+static int mix_to_v4l(int i)
+{
+ int r;
+
+ r = ((i & 0xff) * 65536 + 50) / 100;
+ if (r > 65535) r = 65535;
+ if (r < 0) r = 0;
+ return r;
+}
+
+static int v4l_to_mix(int i)
+{
+ int r;
+
+ r = (i * 100 + 32768) / 65536;
+ if (r > 100) r = 100;
+ if (r < 0) r = 0;
+ return r | (r << 8);
+}
+
+static int v4l_to_mix2(int l, int r)
+{
+ r = (r * 100 + 32768) / 65536;
+ if (r > 100) r = 100;
+ if (r < 0) r = 0;
+ l = (l * 100 + 32768) / 65536;
+ if (l > 100) l = 100;
+ if (l < 0) l = 0;
+ return (r << 8) | l;
+}
+
+static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct video_audio va;
+ int left,right,ret,val = 0;
+ struct TVMIXER *mix = file->private_data;
+ struct i2c_client *client = mix->dev;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+
+ if (NULL == client)
+ return -ENODEV;
+
+ if (cmd == SOUND_MIXER_INFO) {
+ mixer_info info;
+ strlcpy(info.id, "tv card", sizeof(info.id));
+ strlcpy(info.name, client->name, sizeof(info.name));
+ info.modify_counter = 42 /* FIXME */;
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+ if (cmd == SOUND_OLD_MIXER_INFO) {
+ _old_mixer_info info;
+ strlcpy(info.id, "tv card", sizeof(info.id));
+ strlcpy(info.name, client->name, sizeof(info.name));
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+ if (cmd == OSS_GETVERSION)
+ return put_user(SOUND_VERSION, p);
+
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE)
+ if (get_user(val, p))
+ return -EFAULT;
+
+ /* read state */
+ memset(&va,0,sizeof(va));
+ client->driver->command(client,VIDIOCGAUDIO,&va);
+
+ switch (cmd) {
+ case MIXER_READ(SOUND_MIXER_RECMASK):
+ case MIXER_READ(SOUND_MIXER_CAPS):
+ case MIXER_READ(SOUND_MIXER_RECSRC):
+ case MIXER_WRITE(SOUND_MIXER_RECSRC):
+ ret = 0;
+ break;
+
+ case MIXER_READ(SOUND_MIXER_STEREODEVS):
+ ret = SOUND_MASK_VOLUME;
+ break;
+ case MIXER_READ(SOUND_MIXER_DEVMASK):
+ ret = SOUND_MASK_VOLUME;
+ if (va.flags & VIDEO_AUDIO_BASS)
+ ret |= SOUND_MASK_BASS;
+ if (va.flags & VIDEO_AUDIO_TREBLE)
+ ret |= SOUND_MASK_TREBLE;
+ break;
+
+ case MIXER_WRITE(SOUND_MIXER_VOLUME):
+ left = mix_to_v4l(val);
+ right = mix_to_v4l(val >> 8);
+ va.volume = max(left,right);
+ va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1);
+ va.balance = (leftdriver->command(client,VIDIOCSAUDIO,&va);
+ client->driver->command(client,VIDIOCGAUDIO,&va);
+ /* fall throuth */
+ case MIXER_READ(SOUND_MIXER_VOLUME):
+ left = (min(65536 - va.balance,32768) *
+ va.volume) / 32768;
+ right = (min(va.balance,(u16)32768) *
+ va.volume) / 32768;
+ ret = v4l_to_mix2(left,right);
+ break;
+
+ case MIXER_WRITE(SOUND_MIXER_BASS):
+ va.bass = mix_to_v4l(val);
+ client->driver->command(client,VIDIOCSAUDIO,&va);
+ client->driver->command(client,VIDIOCGAUDIO,&va);
+ /* fall throuth */
+ case MIXER_READ(SOUND_MIXER_BASS):
+ ret = v4l_to_mix(va.bass);
+ break;
+
+ case MIXER_WRITE(SOUND_MIXER_TREBLE):
+ va.treble = mix_to_v4l(val);
+ client->driver->command(client,VIDIOCSAUDIO,&va);
+ client->driver->command(client,VIDIOCGAUDIO,&va);
+ /* fall throuth */
+ case MIXER_READ(SOUND_MIXER_TREBLE):
+ ret = v4l_to_mix(va.treble);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ if (put_user(ret, p))
+ return -EFAULT;
+ return 0;
+}
+
+static int tvmixer_open(struct inode *inode, struct file *file)
+{
+ int i, minor = iminor(inode);
+ struct TVMIXER *mix = NULL;
+ struct i2c_client *client = NULL;
+
+ for (i = 0; i < DEV_MAX; i++) {
+ if (devices[i].minor == minor) {
+ mix = devices+i;
+ client = mix->dev;
+ break;
+ }
+ }
+
+ if (NULL == client)
+ return -ENODEV;
+
+ /* lock bttv in memory while the mixer is in use */
+ file->private_data = mix;
+ if (client->adapter->owner)
+ try_module_get(client->adapter->owner);
+ return 0;
+}
+
+static int tvmixer_release(struct inode *inode, struct file *file)
+{
+ struct TVMIXER *mix = file->private_data;
+ struct i2c_client *client;
+
+ client = mix->dev;
+ if (NULL == client) {
+ return -ENODEV;
+ }
+
+ module_put(client->adapter->owner);
+ return 0;
+}
+
+static struct i2c_driver driver = {
+ .driver = {
+ .name = "tvmixer",
+ },
+ .id = I2C_DRIVERID_TVMIXER,
+ .detach_adapter = tvmixer_adapters,
+ .attach_adapter = tvmixer_adapters,
+ .detach_client = tvmixer_clients,
+};
+
+static const struct file_operations tvmixer_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .ioctl = tvmixer_ioctl,
+ .open = tvmixer_open,
+ .release = tvmixer_release,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int tvmixer_adapters(struct i2c_adapter *adap)
+{
+ struct i2c_client *client;
+
+ list_for_each_entry(client, &adap->clients, list)
+ tvmixer_clients(client);
+ return 0;
+}
+
+static int tvmixer_clients(struct i2c_client *client)
+{
+ struct video_audio va;
+ int i,minor;
+
+ if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
+ return -1;
+
+ /* unregister ?? */
+ for (i = 0; i < DEV_MAX; i++) {
+ if (devices[i].dev == client) {
+ /* unregister */
+ unregister_sound_mixer(devices[i].minor);
+ devices[i].dev = NULL;
+ devices[i].minor = -1;
+ printk("tvmixer: %s unregistered (#1)\n",
+ client->name);
+ return 0;
+ }
+ }
+
+ /* look for a free slot */
+ for (i = 0; i < DEV_MAX; i++)
+ if (NULL == devices[i].dev)
+ break;
+ if (i == DEV_MAX) {
+ printk(KERN_WARNING "tvmixer: DEV_MAX too small\n");
+ return -1;
+ }
+
+ /* audio chip with mixer ??? */
+ if (NULL == client->driver->command)
+ return -1;
+ memset(&va,0,sizeof(va));
+ if (0 != client->driver->command(client,VIDIOCGAUDIO,&va))
+ return -1;
+ if (0 == (va.flags & VIDEO_AUDIO_VOLUME))
+ return -1;
+
+ /* everything is fine, register */
+ if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) {
+ printk(KERN_ERR "tvmixer: cannot allocate mixer device\n");
+ return -1;
+ }
+
+ devices[i].minor = minor;
+ devices[i].count = 0;
+ devices[i].dev = client;
+ printk("tvmixer: %s (%s) registered with minor %d\n",
+ client->name,client->adapter->name,minor);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int __init tvmixer_init_module(void)
+{
+ int i;
+
+ for (i = 0; i < DEV_MAX; i++)
+ devices[i].minor = -1;
+
+ return i2c_add_driver(&driver);
+}
+
+static void __exit tvmixer_cleanup_module(void)
+{
+ int i;
+
+ i2c_del_driver(&driver);
+ for (i = 0; i < DEV_MAX; i++) {
+ if (devices[i].minor != -1) {
+ unregister_sound_mixer(devices[i].minor);
+ printk("tvmixer: %s unregistered (#2)\n",
+ devices[i].dev->name);
+ }
+ }
+}
+
+module_init(tvmixer_init_module);
+module_exit(tvmixer_cleanup_module);
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/trunk/drivers/misc/asus-laptop.c b/trunk/drivers/misc/asus-laptop.c
index 0846c33296bc..7dce318df1bd 100644
--- a/trunk/drivers/misc/asus-laptop.c
+++ b/trunk/drivers/misc/asus-laptop.c
@@ -33,6 +33,7 @@
* Sam Lin - GPS support
*/
+#include
#include
#include
#include
diff --git a/trunk/drivers/misc/fujitsu-laptop.c b/trunk/drivers/misc/fujitsu-laptop.c
index 1cfd7f3f1294..c8d62c268b11 100644
--- a/trunk/drivers/misc/fujitsu-laptop.c
+++ b/trunk/drivers/misc/fujitsu-laptop.c
@@ -50,6 +50,7 @@
#include
#include
#include
+#include
#define FUJITSU_DRIVER_VERSION "0.3"
diff --git a/trunk/drivers/misc/lkdtm.c b/trunk/drivers/misc/lkdtm.c
index c884730c5eaf..552b7957a92a 100644
--- a/trunk/drivers/misc/lkdtm.c
+++ b/trunk/drivers/misc/lkdtm.c
@@ -129,28 +129,27 @@ module_param(cpoint_count, int, 0644);
MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\
"crash point is to be hit to trigger action");
-static unsigned int jp_do_irq(unsigned int irq)
+unsigned int jp_do_irq(unsigned int irq)
{
lkdtm_handler();
jprobe_return();
return 0;
}
-static irqreturn_t jp_handle_irq_event(unsigned int irq,
- struct irqaction *action)
+irqreturn_t jp_handle_irq_event(unsigned int irq, struct irqaction *action)
{
lkdtm_handler();
jprobe_return();
return 0;
}
-static void jp_tasklet_action(struct softirq_action *a)
+void jp_tasklet_action(struct softirq_action *a)
{
lkdtm_handler();
jprobe_return();
}
-static void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
+void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
{
lkdtm_handler();
jprobe_return();
@@ -158,24 +157,23 @@ static void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
struct scan_control;
-static unsigned long jp_shrink_inactive_list(unsigned long max_scan,
- struct zone *zone,
- struct scan_control *sc)
+unsigned long jp_shrink_inactive_list(unsigned long max_scan,
+ struct zone *zone, struct scan_control *sc)
{
lkdtm_handler();
jprobe_return();
return 0;
}
-static int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim,
- const enum hrtimer_mode mode)
+int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim,
+ const enum hrtimer_mode mode)
{
lkdtm_handler();
jprobe_return();
return 0;
}
-static int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd)
+int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd)
{
lkdtm_handler();
jprobe_return();
@@ -272,7 +270,7 @@ void lkdtm_handler(void)
}
}
-static int __init lkdtm_module_init(void)
+int lkdtm_module_init(void)
{
int ret;
@@ -333,7 +331,7 @@ static int __init lkdtm_module_init(void)
return 0;
}
-static void __exit lkdtm_module_exit(void)
+void lkdtm_module_exit(void)
{
unregister_jprobe(&lkdtm);
printk(KERN_INFO "lkdtm : Crash point unregistered\n");
diff --git a/trunk/drivers/misc/msi-laptop.c b/trunk/drivers/misc/msi-laptop.c
index de898c6938f3..83679c762925 100644
--- a/trunk/drivers/misc/msi-laptop.c
+++ b/trunk/drivers/misc/msi-laptop.c
@@ -58,6 +58,7 @@
#include
#include
#include
+#include
#define MSI_DRIVER_VERSION "0.5"
diff --git a/trunk/drivers/misc/phantom.c b/trunk/drivers/misc/phantom.c
index 7fa61e907e1c..cd221fd0fb94 100644
--- a/trunk/drivers/misc/phantom.c
+++ b/trunk/drivers/misc/phantom.c
@@ -25,7 +25,7 @@
#include
#include
-#define PHANTOM_VERSION "n0.9.8"
+#define PHANTOM_VERSION "n0.9.7"
#define PHANTOM_MAX_MINORS 8
@@ -456,9 +456,8 @@ static int phantom_resume(struct pci_dev *pdev)
#endif
static struct pci_device_id phantom_pci_tbl[] __devinitdata = {
- { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9050,
- .subvendor = PCI_VENDOR_ID_PLX, .subdevice = PCI_DEVICE_ID_PLX_9050,
- .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 },
+ { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050),
+ .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, phantom_pci_tbl);
diff --git a/trunk/drivers/mtd/devices/block2mtd.c b/trunk/drivers/mtd/devices/block2mtd.c
index eeaaa9dce6ef..be4b9948c762 100644
--- a/trunk/drivers/mtd/devices/block2mtd.c
+++ b/trunk/drivers/mtd/devices/block2mtd.c
@@ -4,7 +4,7 @@
* block2mtd.c - create an mtd from a block device
*
* Copyright (C) 2001,2002 Simon Evans
- * Copyright (C) 2004-2006 Joern Engel
+ * Copyright (C) 2004-2006 Jörn Engel
*
* Licence: GPL
*/
@@ -485,5 +485,5 @@ module_init(block2mtd_init);
module_exit(block2mtd_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Joern Engel ");
+MODULE_AUTHOR("Simon Evans and others");
MODULE_DESCRIPTION("Emulate an MTD using a block device");
diff --git a/trunk/drivers/mtd/devices/phram.c b/trunk/drivers/mtd/devices/phram.c
index 180298b92a7a..56cc1ca7ffd5 100644
--- a/trunk/drivers/mtd/devices/phram.c
+++ b/trunk/drivers/mtd/devices/phram.c
@@ -2,7 +2,7 @@
* $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $
*
* Copyright (c) ???? Jochen Schäuble
- * Copyright (c) 2003-2004 Joern Engel
+ * Copyright (c) 2003-2004 Jörn Engel
*
* Usage:
*
@@ -299,5 +299,5 @@ module_init(init_phram);
module_exit(cleanup_phram);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Joern Engel ");
+MODULE_AUTHOR("Jörn Engel ");
MODULE_DESCRIPTION("MTD driver for physical RAM");
diff --git a/trunk/drivers/mtd/maps/mtx-1_flash.c b/trunk/drivers/mtd/maps/mtx-1_flash.c
index 2a8fde9b92f0..d884f2be28f6 100644
--- a/trunk/drivers/mtd/maps/mtx-1_flash.c
+++ b/trunk/drivers/mtd/maps/mtx-1_flash.c
@@ -4,7 +4,7 @@
* $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
*
* (C) 2005 Bruno Randolf
- * (C) 2005 Joern Engel
+ * (C) 2005 Jörn Engel
*
*/
diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c
index 238628d3a854..e9743d3efaf6 100644
--- a/trunk/drivers/parport/parport_pc.c
+++ b/trunk/drivers/parport/parport_pc.c
@@ -1540,38 +1540,6 @@ static void __devinit detect_and_report_smsc (void)
smsc_check(0x3f0,0x44);
smsc_check(0x370,0x44);
}
-
-static void __devinit detect_and_report_it87(void)
-{
- u16 dev;
- u8 r;
- if (verbose_probing)
- printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
- if (!request_region(0x2e, 1, __FUNCTION__))
- return;
- outb(0x87, 0x2e);
- outb(0x01, 0x2e);
- outb(0x55, 0x2e);
- outb(0x55, 0x2e);
- outb(0x20, 0x2e);
- dev = inb(0x2f) << 8;
- outb(0x21, 0x2e);
- dev |= inb(0x2f);
- if (dev == 0x8712 || dev == 0x8705 || dev == 0x8715 ||
- dev == 0x8716 || dev == 0x8718 || dev == 0x8726) {
- printk(KERN_INFO "IT%04X SuperIO detected.\n", dev);
- outb(0x07, 0x2E); /* Parallel Port */
- outb(0x03, 0x2F);
- outb(0xF0, 0x2E); /* BOOT 0x80 off */
- r = inb(0x2f);
- outb(0xF0, 0x2E);
- outb(r | 8, 0x2F);
- outb(0x02, 0x2E); /* Lock */
- outb(0x02, 0x2F);
-
- release_region(0x2e, 1);
- }
-}
#endif /* CONFIG_PARPORT_PC_SUPERIO */
static int get_superio_dma (struct parport *p)
@@ -2799,7 +2767,6 @@ enum parport_pc_pci_cards {
netmos_9755,
netmos_9805,
netmos_9815,
- quatech_sppxp100,
};
@@ -2876,7 +2843,6 @@ static struct parport_pc_pci {
/* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */
/* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */
/* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
- /* quatech_sppxp100 */ { 1, { { 0, 1 }, } },
};
static const struct pci_device_id parport_pc_pci_tbl[] = {
@@ -2960,9 +2926,6 @@ static const struct pci_device_id parport_pc_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 },
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 },
- /* Quatech SPPXP-100 Parallel port PCI ExpressCard */
- { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 },
{ 0, } /* terminate list */
};
MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
@@ -3196,25 +3159,24 @@ static void __init parport_pc_find_ports (int autoirq, int autodma)
int count = 0, err;
#ifdef CONFIG_PARPORT_PC_SUPERIO
- detect_and_report_it87();
- detect_and_report_winbond();
- detect_and_report_smsc();
+ detect_and_report_winbond ();
+ detect_and_report_smsc ();
#endif
/* Onboard SuperIO chipsets that show themselves on the PCI bus. */
- count += parport_pc_init_superio(autoirq, autodma);
+ count += parport_pc_init_superio (autoirq, autodma);
/* PnP ports, skip detection if SuperIO already found them */
if (!count) {
- err = pnp_register_driver(&parport_pc_pnp_driver);
+ err = pnp_register_driver (&parport_pc_pnp_driver);
if (!err)
pnp_registered_parport = 1;
}
/* ISA ports and whatever (see asm/parport.h). */
- parport_pc_find_nonpci_ports(autoirq, autodma);
+ parport_pc_find_nonpci_ports (autoirq, autodma);
- err = pci_register_driver(&parport_pc_pci_driver);
+ err = pci_register_driver (&parport_pc_pci_driver);
if (!err)
pci_registered_parport = 1;
}
diff --git a/trunk/drivers/parport/parport_serial.c b/trunk/drivers/parport/parport_serial.c
index e2e95b36a603..bd6ad8b38168 100644
--- a/trunk/drivers/parport/parport_serial.c
+++ b/trunk/drivers/parport/parport_serial.c
@@ -77,7 +77,7 @@ static struct parport_pc_pci cards[] __devinitdata = {
/* titan_110l */ { 1, { { 3, -1 }, } },
/* titan_210l */ { 1, { { 3, -1 }, } },
/* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init },
- /* netmos_9855 */ { 1, { { 2, -1 }, }, netmos_parallel_init },
+ /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init },
/* avlab_1s1p */ { 1, { { 1, 2}, } },
/* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} },
/* avlab_2s1p */ { 1, { { 2, 3}, } },
@@ -185,7 +185,7 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = {
.uart_offset = 8,
},
[netmos_9855] = {
- .flags = FL_BASE4 | FL_BASE_BARS,
+ .flags = FL_BASE2 | FL_BASE_BARS,
.num_ports = 1,
.base_baud = 115200,
.uart_offset = 8,
diff --git a/trunk/drivers/pci/dmar.c b/trunk/drivers/pci/dmar.c
index 8ed26480371f..91b2dc956be5 100644
--- a/trunk/drivers/pci/dmar.c
+++ b/trunk/drivers/pci/dmar.c
@@ -26,7 +26,6 @@
#include
#include
#include "iova.h"
-#include "intel-iommu.h"
#undef PREFIX
#define PREFIX "DMAR:"
diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c
index 31fa6c92aa5e..4e01df99681a 100644
--- a/trunk/drivers/pci/intel-iommu.c
+++ b/trunk/drivers/pci/intel-iommu.c
@@ -1088,7 +1088,7 @@ static void dmar_init_reserved_ranges(void)
int i;
u64 addr, size;
- init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN);
+ init_iova_domain(&reserved_iova_list);
/* IOAPIC ranges shouldn't be accessed by DMA */
iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
@@ -1142,7 +1142,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
int adjust_width, agaw;
unsigned long sagaw;
- init_iova_domain(&domain->iovad, DMA_32BIT_PFN);
+ init_iova_domain(&domain->iovad);
spin_lock_init(&domain->mapping_lock);
domain_reserve_special_ranges(domain);
diff --git a/trunk/drivers/pci/intel-iommu.h b/trunk/drivers/pci/intel-iommu.h
index 0e4862675ad2..459ad1f9dc54 100644
--- a/trunk/drivers/pci/intel-iommu.h
+++ b/trunk/drivers/pci/intel-iommu.h
@@ -23,23 +23,9 @@
#include
#include
-#include
#include "iova.h"
#include
-/*
- * We need a fixed PAGE_SIZE of 4K irrespective of
- * arch PAGE_SIZE for IOMMU page tables.
- */
-#define PAGE_SHIFT_4K (12)
-#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K)
-#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K)
-#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
-
-#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K)
-#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK)
-#define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK)
-
/*
* Intel IOMMU register specification per version 1.0 public spec.
*/
diff --git a/trunk/drivers/pci/iova.c b/trunk/drivers/pci/iova.c
index 8de7ab6c6d0c..a84571c29360 100644
--- a/trunk/drivers/pci/iova.c
+++ b/trunk/drivers/pci/iova.c
@@ -9,19 +9,19 @@
#include "iova.h"
void
-init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit)
+init_iova_domain(struct iova_domain *iovad)
{
spin_lock_init(&iovad->iova_alloc_lock);
spin_lock_init(&iovad->iova_rbtree_lock);
iovad->rbroot = RB_ROOT;
iovad->cached32_node = NULL;
- iovad->dma_32bit_pfn = pfn_32bit;
+
}
static struct rb_node *
__get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn)
{
- if ((*limit_pfn != iovad->dma_32bit_pfn) ||
+ if ((*limit_pfn != DMA_32BIT_PFN) ||
(iovad->cached32_node == NULL))
return rb_last(&iovad->rbroot);
else {
@@ -37,7 +37,7 @@ static void
__cached_rbnode_insert_update(struct iova_domain *iovad,
unsigned long limit_pfn, struct iova *new)
{
- if (limit_pfn != iovad->dma_32bit_pfn)
+ if (limit_pfn != DMA_32BIT_PFN)
return;
iovad->cached32_node = &new->node;
}
diff --git a/trunk/drivers/pci/iova.h b/trunk/drivers/pci/iova.h
index d521b5b7319c..ae3028d5a941 100644
--- a/trunk/drivers/pci/iova.h
+++ b/trunk/drivers/pci/iova.h
@@ -15,9 +15,22 @@
#include
#include
+/*
+ * We need a fixed PAGE_SIZE of 4K irrespective of
+ * arch PAGE_SIZE for IOMMU page tables.
+ */
+#define PAGE_SHIFT_4K (12)
+#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K)
+#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K)
+#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
+
/* IO virtual address start page frame number */
#define IOVA_START_PFN (1)
+#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K)
+#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK)
+#define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK)
+
/* iova structure */
struct iova {
struct rb_node node;
@@ -31,7 +44,6 @@ struct iova_domain {
spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */
struct rb_root rbroot; /* iova domain rbtree root */
struct rb_node *cached32_node; /* Save last alloced node */
- unsigned long dma_32bit_pfn;
};
struct iova *alloc_iova_mem(void);
@@ -44,7 +56,7 @@ struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
unsigned long pfn_hi);
void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
-void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit);
+void init_iova_domain(struct iova_domain *iovad);
struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
void put_iova_domain(struct iova_domain *iovad);
diff --git a/trunk/drivers/pnp/driver.c b/trunk/drivers/pnp/driver.c
index 12a1645a2e43..a262762c5b88 100644
--- a/trunk/drivers/pnp/driver.c
+++ b/trunk/drivers/pnp/driver.c
@@ -161,7 +161,8 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state)
return error;
}
- if (pnp_can_disable(pnp_dev)) {
+ if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) &&
+ pnp_can_disable(pnp_dev)) {
error = pnp_stop_dev(pnp_dev);
if (error)
return error;
@@ -184,17 +185,14 @@ static int pnp_bus_resume(struct device *dev)
if (pnp_dev->protocol && pnp_dev->protocol->resume)
pnp_dev->protocol->resume(pnp_dev);
- if (pnp_can_write(pnp_dev)) {
+ if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
error = pnp_start_dev(pnp_dev);
if (error)
return error;
}
- if (pnp_drv->resume) {
- error = pnp_drv->resume(pnp_dev);
- if (error)
- return error;
- }
+ if (pnp_drv->resume)
+ return pnp_drv->resume(pnp_dev);
return 0;
}
diff --git a/trunk/drivers/pnp/interface.c b/trunk/drivers/pnp/interface.c
index 982658477a58..31548044fdde 100644
--- a/trunk/drivers/pnp/interface.c
+++ b/trunk/drivers/pnp/interface.c
@@ -10,12 +10,9 @@
#include
#include
#include
-#include
#include
#include
#include
-#include
-
#include
#include "base.h"
@@ -318,6 +315,8 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
return ret;
}
+extern struct semaphore pnp_res_mutex;
+
static ssize_t
pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
const char *ubuf, size_t count)
@@ -362,10 +361,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
goto done;
}
if (!strnicmp(buf, "get", 3)) {
- mutex_lock(&pnp_res_mutex);
+ down(&pnp_res_mutex);
if (pnp_can_read(dev))
dev->protocol->get(dev, &dev->res);
- mutex_unlock(&pnp_res_mutex);
+ up(&pnp_res_mutex);
goto done;
}
if (!strnicmp(buf, "set", 3)) {
@@ -374,7 +373,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
goto done;
buf += 3;
pnp_init_resource_table(&dev->res);
- mutex_lock(&pnp_res_mutex);
+ down(&pnp_res_mutex);
while (1) {
while (isspace(*buf))
++buf;
@@ -456,7 +455,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
}
break;
}
- mutex_unlock(&pnp_res_mutex);
+ up(&pnp_res_mutex);
goto done;
}
diff --git a/trunk/drivers/pnp/manager.c b/trunk/drivers/pnp/manager.c
index c28caf272c11..c6b3d4e63ccc 100644
--- a/trunk/drivers/pnp/manager.c
+++ b/trunk/drivers/pnp/manager.c
@@ -12,10 +12,9 @@
#include
#include
#include
-#include
#include "base.h"
-DEFINE_MUTEX(pnp_res_mutex);
+DECLARE_MUTEX(pnp_res_mutex);
static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
{
@@ -298,7 +297,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
if (!pnp_can_configure(dev))
return -ENODEV;
- mutex_lock(&pnp_res_mutex);
+ down(&pnp_res_mutex);
pnp_clean_resource_table(&dev->res); /* start with a fresh slate */
if (dev->independent) {
port = dev->independent->port;
@@ -367,12 +366,12 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
} else if (dev->dependent)
goto fail;
- mutex_unlock(&pnp_res_mutex);
+ up(&pnp_res_mutex);
return 1;
fail:
pnp_clean_resource_table(&dev->res);
- mutex_unlock(&pnp_res_mutex);
+ up(&pnp_res_mutex);
return 0;
}
@@ -397,7 +396,7 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
return -ENOMEM;
*bak = dev->res;
- mutex_lock(&pnp_res_mutex);
+ down(&pnp_res_mutex);
dev->res = *res;
if (!(mode & PNP_CONFIG_FORCE)) {
for (i = 0; i < PNP_MAX_PORT; i++) {
@@ -417,14 +416,14 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
goto fail;
}
}
- mutex_unlock(&pnp_res_mutex);
+ up(&pnp_res_mutex);
kfree(bak);
return 0;
fail:
dev->res = *bak;
- mutex_unlock(&pnp_res_mutex);
+ up(&pnp_res_mutex);
kfree(bak);
return -EINVAL;
}
@@ -514,7 +513,7 @@ int pnp_activate_dev(struct pnp_dev *dev)
int error;
if (dev->active)
- return 0;
+ return 0; /* the device is already active */
/* ensure resources are allocated */
if (pnp_auto_config_dev(dev))
@@ -525,7 +524,7 @@ int pnp_activate_dev(struct pnp_dev *dev)
return error;
dev->active = 1;
- return 0;
+ return 1;
}
/**
@@ -539,7 +538,7 @@ int pnp_disable_dev(struct pnp_dev *dev)
int error;
if (!dev->active)
- return 0;
+ return 0; /* the device is already disabled */
error = pnp_stop_dev(dev);
if (error)
@@ -548,11 +547,11 @@ int pnp_disable_dev(struct pnp_dev *dev)
dev->active = 0;
/* release the resources so that other devices can use them */
- mutex_lock(&pnp_res_mutex);
+ down(&pnp_res_mutex);
pnp_clean_resource_table(&dev->res);
- mutex_unlock(&pnp_res_mutex);
+ up(&pnp_res_mutex);
- return 0;
+ return 1;
}
/**
diff --git a/trunk/drivers/pnp/pnpacpi/rsparser.c b/trunk/drivers/pnp/pnpacpi/rsparser.c
index 6aa231ef642d..6b9840cce0f4 100644
--- a/trunk/drivers/pnp/pnpacpi/rsparser.c
+++ b/trunk/drivers/pnp/pnpacpi/rsparser.c
@@ -391,8 +391,8 @@ acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle,
pnpacpi_allocated_resource, res);
}
-static __init void pnpacpi_parse_dma_option(struct pnp_option *option,
- struct acpi_resource_dma *p)
+static void pnpacpi_parse_dma_option(struct pnp_option *option,
+ struct acpi_resource_dma *p)
{
int i;
struct pnp_dma *dma;
@@ -411,8 +411,8 @@ static __init void pnpacpi_parse_dma_option(struct pnp_option *option,
pnp_register_dma_resource(option, dma);
}
-static __init void pnpacpi_parse_irq_option(struct pnp_option *option,
- struct acpi_resource_irq *p)
+static void pnpacpi_parse_irq_option(struct pnp_option *option,
+ struct acpi_resource_irq *p)
{
int i;
struct pnp_irq *irq;
@@ -431,8 +431,8 @@ static __init void pnpacpi_parse_irq_option(struct pnp_option *option,
pnp_register_irq_resource(option, irq);
}
-static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
- struct acpi_resource_extended_irq *p)
+static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
+ struct acpi_resource_extended_irq *p)
{
int i;
struct pnp_irq *irq;
@@ -451,8 +451,8 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
pnp_register_irq_resource(option, irq);
}
-static __init void pnpacpi_parse_port_option(struct pnp_option *option,
- struct acpi_resource_io *io)
+static void pnpacpi_parse_port_option(struct pnp_option *option,
+ struct acpi_resource_io *io)
{
struct pnp_port *port;
@@ -470,8 +470,8 @@ static __init void pnpacpi_parse_port_option(struct pnp_option *option,
pnp_register_port_resource(option, port);
}
-static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
- struct acpi_resource_fixed_io *io)
+static void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
+ struct acpi_resource_fixed_io *io)
{
struct pnp_port *port;
@@ -487,8 +487,8 @@ static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
pnp_register_port_resource(option, port);
}
-static __init void pnpacpi_parse_mem24_option(struct pnp_option *option,
- struct acpi_resource_memory24 *p)
+static void pnpacpi_parse_mem24_option(struct pnp_option *option,
+ struct acpi_resource_memory24 *p)
{
struct pnp_mem *mem;
@@ -508,8 +508,8 @@ static __init void pnpacpi_parse_mem24_option(struct pnp_option *option,
pnp_register_mem_resource(option, mem);
}
-static __init void pnpacpi_parse_mem32_option(struct pnp_option *option,
- struct acpi_resource_memory32 *p)
+static void pnpacpi_parse_mem32_option(struct pnp_option *option,
+ struct acpi_resource_memory32 *p)
{
struct pnp_mem *mem;
@@ -529,8 +529,8 @@ static __init void pnpacpi_parse_mem32_option(struct pnp_option *option,
pnp_register_mem_resource(option, mem);
}
-static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
- struct acpi_resource_fixed_memory32 *p)
+static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
+ struct acpi_resource_fixed_memory32 *p)
{
struct pnp_mem *mem;
@@ -549,8 +549,8 @@ static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
pnp_register_mem_resource(option, mem);
}
-static __init void pnpacpi_parse_address_option(struct pnp_option *option,
- struct acpi_resource *r)
+static void pnpacpi_parse_address_option(struct pnp_option *option,
+ struct acpi_resource *r)
{
struct acpi_resource_address64 addr, *p = &addr;
acpi_status status;
@@ -596,8 +596,8 @@ struct acpipnp_parse_option_s {
struct pnp_dev *dev;
};
-static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
- void *data)
+static acpi_status pnpacpi_option_resource(struct acpi_resource *res,
+ void *data)
{
int priority = 0;
struct acpipnp_parse_option_s *parse_data = data;
@@ -696,8 +696,8 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
return AE_OK;
}
-acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle,
- struct pnp_dev *dev)
+acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle,
+ struct pnp_dev * dev)
{
acpi_status status;
struct acpipnp_parse_option_s parse_data;
diff --git a/trunk/drivers/pnp/pnpbios/core.c b/trunk/drivers/pnp/pnpbios/core.c
index f7e67197a568..e33e03f71084 100644
--- a/trunk/drivers/pnp/pnpbios/core.c
+++ b/trunk/drivers/pnp/pnpbios/core.c
@@ -315,7 +315,7 @@ struct pnp_protocol pnpbios_protocol = {
.disable = pnpbios_disable_resources,
};
-static int __init insert_device(struct pnp_bios_node *node)
+static int insert_device(struct pnp_bios_node *node)
{
struct list_head *pos;
struct pnp_dev *dev;
diff --git a/trunk/drivers/pnp/pnpbios/rsparser.c b/trunk/drivers/pnp/pnpbios/rsparser.c
index caade3531416..3fabf11b0027 100644
--- a/trunk/drivers/pnp/pnpbios/rsparser.c
+++ b/trunk/drivers/pnp/pnpbios/rsparser.c
@@ -262,8 +262,8 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
* Resource Configuration Options
*/
-static __init void pnpbios_parse_mem_option(unsigned char *p, int size,
- struct pnp_option *option)
+static void pnpbios_parse_mem_option(unsigned char *p, int size,
+ struct pnp_option *option)
{
struct pnp_mem *mem;
@@ -278,8 +278,8 @@ static __init void pnpbios_parse_mem_option(unsigned char *p, int size,
pnp_register_mem_resource(option, mem);
}
-static __init void pnpbios_parse_mem32_option(unsigned char *p, int size,
- struct pnp_option *option)
+static void pnpbios_parse_mem32_option(unsigned char *p, int size,
+ struct pnp_option *option)
{
struct pnp_mem *mem;
@@ -294,8 +294,8 @@ static __init void pnpbios_parse_mem32_option(unsigned char *p, int size,
pnp_register_mem_resource(option, mem);
}
-static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size,
- struct pnp_option *option)
+static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size,
+ struct pnp_option *option)
{
struct pnp_mem *mem;
@@ -309,7 +309,7 @@ static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size,
pnp_register_mem_resource(option, mem);
}
-static __init void pnpbios_parse_irq_option(unsigned char *p, int size,
+static void pnpbios_parse_irq_option(unsigned char *p, int size,
struct pnp_option *option)
{
struct pnp_irq *irq;
@@ -327,7 +327,7 @@ static __init void pnpbios_parse_irq_option(unsigned char *p, int size,
pnp_register_irq_resource(option, irq);
}
-static __init void pnpbios_parse_dma_option(unsigned char *p, int size,
+static void pnpbios_parse_dma_option(unsigned char *p, int size,
struct pnp_option *option)
{
struct pnp_dma *dma;
@@ -340,8 +340,8 @@ static __init void pnpbios_parse_dma_option(unsigned char *p, int size,
pnp_register_dma_resource(option, dma);
}
-static __init void pnpbios_parse_port_option(unsigned char *p, int size,
- struct pnp_option *option)
+static void pnpbios_parse_port_option(unsigned char *p, int size,
+ struct pnp_option *option)
{
struct pnp_port *port;
@@ -356,8 +356,8 @@ static __init void pnpbios_parse_port_option(unsigned char *p, int size,
pnp_register_port_resource(option, port);
}
-static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size,
- struct pnp_option *option)
+static void pnpbios_parse_fixed_port_option(unsigned char *p, int size,
+ struct pnp_option *option)
{
struct pnp_port *port;
@@ -371,9 +371,9 @@ static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size,
pnp_register_port_resource(option, port);
}
-static __init unsigned char *
-pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
- struct pnp_dev *dev)
+static unsigned char *pnpbios_parse_resource_option_data(unsigned char *p,
+ unsigned char *end,
+ struct pnp_dev *dev)
{
unsigned int len, tag;
int priority = 0;
@@ -781,8 +781,7 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
* Core Parsing Functions
*/
-int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
- struct pnp_bios_node *node)
+int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node *node)
{
unsigned char *p = (char *)node->data;
unsigned char *end = (char *)(node->data + node->size);
diff --git a/trunk/drivers/pnp/quirks.c b/trunk/drivers/pnp/quirks.c
index 4065139753b6..e903b8c2b1fa 100644
--- a/trunk/drivers/pnp/quirks.c
+++ b/trunk/drivers/pnp/quirks.c
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include "base.h"
@@ -109,46 +108,6 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
"pnp: SB audio device quirk - increasing port range\n");
}
-static void quirk_supermicro_h8dce_system(struct pnp_dev *dev)
-{
- int i;
- static struct dmi_system_id supermicro_h8dce[] = {
- {
- .ident = "Supermicro H8DCE",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
- DMI_MATCH(DMI_PRODUCT_NAME, "H8DCE"),
- },
- },
- { }
- };
-
- if (!dmi_check_system(supermicro_h8dce))
- return;
-
- /*
- * On the Supermicro H8DCE, there's a system device with resources
- * that overlap BAR 6 of the built-in SATA PCI adapter. If the PNP
- * system device claims them, the sata_nv driver won't be able to.
- * More details at:
- * https://bugzilla.redhat.com/show_bug.cgi?id=280641
- * https://bugzilla.redhat.com/show_bug.cgi?id=313491
- * http://lkml.org/lkml/2008/1/9/449
- * http://thread.gmane.org/gmane.linux.acpi.devel/27312
- */
- for (i = 0; i < PNP_MAX_MEM; i++) {
- if (pnp_mem_valid(dev, i) && pnp_mem_len(dev, i) &&
- (pnp_mem_start(dev, i) & 0xdfef0000) == 0xdfef0000) {
- dev_warn(&dev->dev, "disabling 0x%llx-0x%llx to prevent"
- " conflict with sata_nv PCI device\n",
- (unsigned long long) pnp_mem_start(dev, i),
- (unsigned long long) (pnp_mem_start(dev, i) +
- pnp_mem_len(dev, i) - 1));
- pnp_mem_flags(dev, i) = 0;
- }
- }
-}
-
/*
* PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info
@@ -169,8 +128,6 @@ static struct pnp_fixup pnp_fixups[] = {
{"CTL0043", quirk_sb16audio_resources},
{"CTL0044", quirk_sb16audio_resources},
{"CTL0045", quirk_sb16audio_resources},
- {"PNP0c01", quirk_supermicro_h8dce_system},
- {"PNP0c02", quirk_supermicro_h8dce_system},
{""}
};
diff --git a/trunk/drivers/ps3/ps3av.c b/trunk/drivers/ps3/ps3av.c
index 6f2f90ebb020..87b3493d88e5 100644
--- a/trunk/drivers/ps3/ps3av.c
+++ b/trunk/drivers/ps3/ps3av.c
@@ -78,21 +78,23 @@ static const struct avset_video_mode {
u32 aspect;
u32 x;
u32 y;
+ u32 interlace;
+ u32 freq;
} video_mode_table[] = {
{ 0, }, /* auto */
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080},
- {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080},
- { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768},
- { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA, A_N, 1280, 1024},
- { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA, A_W, 1920, 1200},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480, 1, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480, 0, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720, 0, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080, 1, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080, 0, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576, 1, 50},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576, 0, 50},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720, 0, 50},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080, 1, 50},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080, 0, 50},
+ { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768, 0, 60},
+ { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA, A_N, 1280, 1024, 0, 60},
+ { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA, A_W, 1920, 1200, 0, 60},
};
/* supported CIDs */
@@ -542,7 +544,7 @@ static void ps3av_set_videomode_packet(u32 id)
static void ps3av_set_videomode_cont(u32 id, u32 old_id)
{
- static int vesa;
+ static int vesa = 0;
int res;
/* video signal off */
@@ -552,9 +554,9 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
* AV backend needs non-VESA mode setting at least one time
* when VESA mode is used.
*/
- if (vesa == 0 && (id & PS3AV_MODE_MASK) >= PS3AV_MODE_WXGA) {
+ if (vesa == 0 && (id & PS3AV_MODE_MASK) >= 11) {
/* vesa mode */
- ps3av_set_videomode_packet(PS3AV_MODE_480P);
+ ps3av_set_videomode_packet(2); /* 480P */
}
vesa = 1;
@@ -594,21 +596,20 @@ static const struct {
unsigned mask : 19;
unsigned id : 4;
} ps3av_preferred_modes[] = {
- { PS3AV_RESBIT_WUXGA << SHIFT_VESA, PS3AV_MODE_WUXGA },
- { PS3AV_RESBIT_1920x1080P << SHIFT_60, PS3AV_MODE_1080P60 },
- { PS3AV_RESBIT_1920x1080P << SHIFT_50, PS3AV_MODE_1080P50 },
- { PS3AV_RESBIT_1920x1080I << SHIFT_60, PS3AV_MODE_1080I60 },
- { PS3AV_RESBIT_1920x1080I << SHIFT_50, PS3AV_MODE_1080I50 },
- { PS3AV_RESBIT_SXGA << SHIFT_VESA, PS3AV_MODE_SXGA },
- { PS3AV_RESBIT_WXGA << SHIFT_VESA, PS3AV_MODE_WXGA },
- { PS3AV_RESBIT_1280x720P << SHIFT_60, PS3AV_MODE_720P60 },
- { PS3AV_RESBIT_1280x720P << SHIFT_50, PS3AV_MODE_720P50 },
- { PS3AV_RESBIT_720x480P << SHIFT_60, PS3AV_MODE_480P },
- { PS3AV_RESBIT_720x576P << SHIFT_50, PS3AV_MODE_576P },
+ { .mask = PS3AV_RESBIT_WUXGA << SHIFT_VESA, .id = 13 },
+ { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_60, .id = 5 },
+ { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_50, .id = 10 },
+ { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_60, .id = 4 },
+ { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_50, .id = 9 },
+ { .mask = PS3AV_RESBIT_SXGA << SHIFT_VESA, .id = 12 },
+ { .mask = PS3AV_RESBIT_WXGA << SHIFT_VESA, .id = 11 },
+ { .mask = PS3AV_RESBIT_1280x720P << SHIFT_60, .id = 3 },
+ { .mask = PS3AV_RESBIT_1280x720P << SHIFT_50, .id = 8 },
+ { .mask = PS3AV_RESBIT_720x480P << SHIFT_60, .id = 2 },
+ { .mask = PS3AV_RESBIT_720x576P << SHIFT_50, .id = 7 },
};
-static enum ps3av_mode_num ps3av_resbit2id(u32 res_50, u32 res_60,
- u32 res_vesa)
+static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa)
{
unsigned int i;
u32 res_all;
@@ -637,9 +638,9 @@ static enum ps3av_mode_num ps3av_resbit2id(u32 res_50, u32 res_60,
return 0;
}
-static enum ps3av_mode_num ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
+static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
{
- enum ps3av_mode_num id;
+ int id;
if (safe_mode)
return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
@@ -853,7 +854,7 @@ int ps3av_set_video_mode(u32 id)
/* auto mode */
option = id & ~PS3AV_MODE_MASK;
- if ((id & PS3AV_MODE_MASK) == PS3AV_MODE_AUTO) {
+ if ((id & PS3AV_MODE_MASK) == 0) {
id = ps3av_auto_videomode(&ps3av->av_hw_conf);
if (id < 1) {
printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
@@ -888,6 +889,36 @@ int ps3av_get_mode(void)
EXPORT_SYMBOL_GPL(ps3av_get_mode);
+int ps3av_get_scanmode(int id)
+{
+ int size;
+
+ id = id & PS3AV_MODE_MASK;
+ size = ARRAY_SIZE(video_mode_table);
+ if (id > size - 1 || id < 0) {
+ printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
+ return -EINVAL;
+ }
+ return video_mode_table[id].interlace;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_get_scanmode);
+
+int ps3av_get_refresh_rate(int id)
+{
+ int size;
+
+ id = id & PS3AV_MODE_MASK;
+ size = ARRAY_SIZE(video_mode_table);
+ if (id > size - 1 || id < 0) {
+ printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
+ return -EINVAL;
+ }
+ return video_mode_table[id].freq;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_get_refresh_rate);
+
/* get resolution by video_mode */
int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres)
{
@@ -959,7 +990,7 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
return -ENOMEM;
mutex_init(&ps3av->mutex);
- ps3av->ps3av_mode = PS3AV_MODE_AUTO;
+ ps3av->ps3av_mode = 0;
ps3av->dev = dev;
INIT_WORK(&ps3av->work, ps3avd);
diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig
index 6402d699072b..45e4b9648176 100644
--- a/trunk/drivers/rtc/Kconfig
+++ b/trunk/drivers/rtc/Kconfig
@@ -20,10 +20,6 @@ menuconfig RTC_CLASS
if RTC_CLASS
-if GEN_RTC || RTC
-comment "Conflicting RTC option has been selected, check GEN_RTC and RTC"
-endif
-
config RTC_HCTOSYS
bool "Set system time from RTC on startup and resume"
depends on RTC_CLASS = y
@@ -53,7 +49,7 @@ config RTC_HCTOSYS_DEVICE
If the clock you specify here is not battery backed, it may still
be useful to reinitialize system time when resuming from system
- sleep states. Do not specify an RTC here unless it stays powered
+ sleep states. Do not specify an RTC here unless it stays powered
during all this system's supported sleep states.
config RTC_DEBUG
@@ -146,7 +142,7 @@ config RTC_DRV_DS1307
will be called rtc-ds1307.
config RTC_DRV_DS1374
- tristate "Dallas/Maxim DS1374"
+ tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
depends on RTC_CLASS && I2C
help
If you say yes here you get support for Dallas Semiconductor
@@ -166,7 +162,7 @@ config RTC_DRV_DS1672
will be called rtc-ds1672.
config RTC_DRV_MAX6900
- tristate "Maxim MAX6900"
+ tristate "Maxim 6900"
help
If you say yes here you will get support for the
Maxim MAX6900 I2C RTC chip.
@@ -184,10 +180,10 @@ config RTC_DRV_RS5C372
will be called rtc-rs5c372.
config RTC_DRV_ISL1208
- tristate "Intersil ISL1208"
+ tristate "Intersil 1208"
help
If you say yes here you get support for the
- Intersil ISL1208 RTC chip.
+ Intersil 1208 RTC chip.
This driver can also be built as a module. If so, the module
will be called rtc-isl1208.
@@ -224,7 +220,7 @@ config RTC_DRV_PCF8583
will be called rtc-pcf8583.
config RTC_DRV_M41T80
- tristate "ST M41T80/81/82/83/84/85/87"
+ tristate "ST M41T80 series RTC"
help
If you say Y here you will get support for the
ST M41T80 RTC chips series. Currently following chips are
@@ -256,24 +252,6 @@ comment "SPI RTC drivers"
if SPI_MASTER
-config RTC_DRV_MAX6902
- tristate "Maxim MAX6902"
- help
- If you say yes here you will get support for the
- Maxim MAX6902 SPI RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-max6902.
-
-config RTC_DRV_R9701
- tristate "Epson RTC-9701JE"
- help
- If you say yes here you will get support for the
- Epson RTC-9701JE SPI RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-r9701.
-
config RTC_DRV_RS5C348
tristate "Ricoh RS5C348A/B"
help
@@ -283,6 +261,15 @@ config RTC_DRV_RS5C348
This driver can also be built as a module. If so, the module
will be called rtc-rs5c348.
+config RTC_DRV_MAX6902
+ tristate "Maxim 6902"
+ help
+ If you say yes here you will get support for the
+ Maxim MAX6902 SPI RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-max6902.
+
endif # SPI_MASTER
comment "Platform RTC drivers"
@@ -315,40 +302,15 @@ config RTC_DRV_DS1216
help
If you say yes here you get support for the Dallas DS1216 RTC chips.
-config RTC_DRV_DS1302
- tristate "Dallas DS1302"
- depends on SH_SECUREEDGE5410
- help
- If you say yes here you get support for the Dallas DS1302 RTC chips.
-
-config RTC_DRV_DS1511
- tristate "Dallas DS1511"
- depends on RTC_CLASS
- help
- If you say yes here you get support for the
- Dallas DS1511 timekeeping/watchdog chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-ds1511.
-
config RTC_DRV_DS1553
- tristate "Maxim/Dallas DS1553"
+ tristate "Dallas DS1553"
help
If you say yes here you get support for the
- Maxim/Dallas DS1553 timekeeping chip.
+ Dallas DS1553 timekeeping chip.
This driver can also be built as a module. If so, the module
will be called rtc-ds1553.
-config RTC_DRV_DS1742
- tristate "Maxim/Dallas DS1742/1743"
- help
- If you say yes here you get support for the
- Maxim/Dallas DS1742/1743 timekeeping chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-ds1742.
-
config RTC_DRV_STK17TA8
tristate "Simtek STK17TA8"
depends on RTC_CLASS
@@ -359,6 +321,15 @@ config RTC_DRV_STK17TA8
This driver can also be built as a module. If so, the module
will be called rtc-stk17ta8.
+config RTC_DRV_DS1742
+ tristate "Dallas DS1742/1743"
+ help
+ If you say yes here you get support for the
+ Dallas DS1742/1743 timekeeping chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds1742.
+
config RTC_DRV_M48T86
tristate "ST M48T86/Dallas DS12887"
help
@@ -469,47 +440,10 @@ config RTC_DRV_AT32AP700X
AT32AP700x family processors.
config RTC_DRV_AT91RM9200
- tristate "AT91RM9200 or AT91SAM9RL"
- depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL
- help
- Driver for the internal RTC (Realtime Clock) module found on
- Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips
- this is powered by the backup power supply.
-
-config RTC_DRV_AT91SAM9
- tristate "AT91SAM9x"
- depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40)
- help
- RTC driver for the Atmel AT91SAM9x internal RTT (Real Time Timer).
- These timers are powered by the backup power supply (such as a
- small coin cell battery), but do not need to be used as RTCs.
-
- (On AT91SAM9rl chips you probably want to use the dedicated RTC
- module and leave the RTT available for other uses.)
-
-config RTC_DRV_AT91SAM9_RTT
- int
- range 0 1
- default 0
- prompt "RTT module Number" if ARCH_AT91SAM9263
- depends on RTC_DRV_AT91SAM9
- help
- More than one RTT module is available. You can choose which
- one will be used as an RTC. The default of zero is normally
- OK to use, though some systems use that for non-RTC purposes.
-
-config RTC_DRV_AT91SAM9_GPBR
- int
- range 0 3 if !ARCH_AT91SAM9263
- range 0 15 if ARCH_AT91SAM9263
- default 0
- prompt "Backup Register Number"
- depends on RTC_DRV_AT91SAM9
- help
- The RTC driver needs to use one of the General Purpose Backup
- Registers (GPBRs) as well as the RTT. You can choose which one
- will be used. The default of zero is normally OK to use, but
- on some systems other software needs to use that register.
+ tristate "AT91RM9200"
+ depends on ARCH_AT91RM9200
+ help
+ Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock).
config RTC_DRV_BFIN
tristate "Blackfin On-Chip RTC"
diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile
index ec703f34ab86..465db4dd50b2 100644
--- a/trunk/drivers/rtc/Makefile
+++ b/trunk/drivers/rtc/Makefile
@@ -19,14 +19,11 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
-obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
-obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o
obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
-obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
@@ -41,7 +38,6 @@ obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
-obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
diff --git a/trunk/drivers/rtc/rtc-at91sam9.c b/trunk/drivers/rtc/rtc-at91sam9.c
deleted file mode 100644
index bbf10ecf416c..000000000000
--- a/trunk/drivers/rtc/rtc-at91sam9.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * "RTT as Real Time Clock" driver for AT91SAM9 SoC family
- *
- * (C) 2007 Michel Benoit
- *
- * Based on rtc-at91rm9200.c by Rick Bronson
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-
-/*
- * This driver uses two configurable hardware resources that live in the
- * AT91SAM9 backup power domain (intended to be powered at all times)
- * to implement the Real Time Clock interfaces
- *
- * - A "Real-time Timer" (RTT) counts up in seconds from a base time.
- * We can't assign the counter value (CRTV) ... but we can reset it.
- *
- * - One of the "General Purpose Backup Registers" (GPBRs) holds the
- * base time, normally an offset from the beginning of the POSIX
- * epoch (1970-Jan-1 00:00:00 UTC). Some systems also include the
- * local timezone's offset.
- *
- * The RTC's value is the RTT counter plus that offset. The RTC's alarm
- * is likewise a base (ALMV) plus that offset.
- *
- * Not all RTTs will be used as RTCs; some systems have multiple RTTs to
- * choose from, or a "real" RTC module. All systems have multiple GPBR
- * registers available, likewise usable for more than "RTC" support.
- */
-
-/*
- * We store ALARM_DISABLED in ALMV to record that no alarm is set.
- * It's also the reset value for that field.
- */
-#define ALARM_DISABLED ((u32)~0)
-
-
-struct sam9_rtc {
- void __iomem *rtt;
- struct rtc_device *rtcdev;
- u32 imr;
-};
-
-#define rtt_readl(rtc, field) \
- __raw_readl((rtc)->rtt + AT91_RTT_ ## field)
-#define rtt_writel(rtc, field, val) \
- __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field)
-
-#define gpbr_readl(rtc) \
- at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR)
-#define gpbr_writel(rtc, val) \
- at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val))
-
-/*
- * Read current time and date in RTC
- */
-static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
-{
- struct sam9_rtc *rtc = dev_get_drvdata(dev);
- u32 secs, secs2;
- u32 offset;
-
- /* read current time offset */
- offset = gpbr_readl(rtc);
- if (offset == 0)
- return -EILSEQ;
-
- /* reread the counter to help sync the two clock domains */
- secs = rtt_readl(rtc, VR);
- secs2 = rtt_readl(rtc, VR);
- if (secs != secs2)
- secs = rtt_readl(rtc, VR);
-
- rtc_time_to_tm(offset + secs, tm);
-
- dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readtime",
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- return 0;
-}
-
-/*
- * Set current time and date in RTC
- */
-static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
-{
- struct sam9_rtc *rtc = dev_get_drvdata(dev);
- int err;
- u32 offset, alarm, mr;
- unsigned long secs;
-
- dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "settime",
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- err = rtc_tm_to_time(tm, &secs);
- if (err != 0)
- return err;
-
- mr = rtt_readl(rtc, MR);
-
- /* disable interrupts */
- rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN));
-
- /* read current time offset */
- offset = gpbr_readl(rtc);
-
- /* store the new base time in a battery backup register */
- secs += 1;
- gpbr_writel(rtc, secs);
-
- /* adjust the alarm time for the new base */
- alarm = rtt_readl(rtc, AR);
- if (alarm != ALARM_DISABLED) {
- if (offset > secs) {
- /* time jumped backwards, increase time until alarm */
- alarm += (offset - secs);
- } else if ((alarm + offset) > secs) {
- /* time jumped forwards, decrease time until alarm */
- alarm -= (secs - offset);
- } else {
- /* time jumped past the alarm, disable alarm */
- alarm = ALARM_DISABLED;
- mr &= ~AT91_RTT_ALMIEN;
- }
- rtt_writel(rtc, AR, alarm);
- }
-
- /* reset the timer, and re-enable interrupts */
- rtt_writel(rtc, MR, mr | AT91_RTT_RTTRST);
-
- return 0;
-}
-
-static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct sam9_rtc *rtc = dev_get_drvdata(dev);
- struct rtc_time *tm = &alrm->time;
- u32 alarm = rtt_readl(rtc, AR);
- u32 offset;
-
- offset = gpbr_readl(rtc);
- if (offset == 0)
- return -EILSEQ;
-
- memset(alrm, 0, sizeof(alrm));
- if (alarm != ALARM_DISABLED && offset != 0) {
- rtc_time_to_tm(offset + alarm, tm);
-
- dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readalarm",
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- if (rtt_readl(rtc, MR) & AT91_RTT_ALMIEN)
- alrm->enabled = 1;
- }
-
- return 0;
-}
-
-static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct sam9_rtc *rtc = dev_get_drvdata(dev);
- struct rtc_time *tm = &alrm->time;
- unsigned long secs;
- u32 offset;
- u32 mr;
- int err;
-
- err = rtc_tm_to_time(tm, &secs);
- if (err != 0)
- return err;
-
- offset = gpbr_readl(rtc);
- if (offset == 0) {
- /* time is not set */
- return -EILSEQ;
- }
- mr = rtt_readl(rtc, MR);
- rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN);
-
- /* alarm in the past? finish and leave disabled */
- if (secs <= offset) {
- rtt_writel(rtc, AR, ALARM_DISABLED);
- return 0;
- }
-
- /* else set alarm and maybe enable it */
- rtt_writel(rtc, AR, secs - offset);
- if (alrm->enabled)
- rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
-
- dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "setalarm",
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
- tm->tm_min, tm->tm_sec);
-
- return 0;
-}
-
-/*
- * Handle commands from user-space
- */
-static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
- unsigned long arg)
-{
- struct sam9_rtc *rtc = dev_get_drvdata(dev);
- int ret = 0;
- u32 mr = rtt_readl(rtc, MR);
-
- dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr);
-
- switch (cmd) {
- case RTC_AIE_OFF: /* alarm off */
- rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN);
- break;
- case RTC_AIE_ON: /* alarm on */
- rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
- break;
- case RTC_UIE_OFF: /* update off */
- rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN);
- break;
- case RTC_UIE_ON: /* update on */
- rtt_writel(rtc, MR, mr | AT91_RTT_RTTINCIEN);
- break;
- default:
- ret = -ENOIOCTLCMD;
- break;
- }
-
- return ret;
-}
-
-/*
- * Provide additional RTC information in /proc/driver/rtc
- */
-static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
-{
- struct sam9_rtc *rtc = dev_get_drvdata(dev);
- u32 mr = mr = rtt_readl(rtc, MR);
-
- seq_printf(seq, "update_IRQ\t: %s\n",
- (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no");
- return 0;
-}
-
-/*
- * IRQ handler for the RTC
- */
-static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
-{
- struct sam9_rtc *rtc = _rtc;
- u32 sr, mr;
- unsigned long events = 0;
-
- /* Shared interrupt may be for another device. Note: reading
- * SR clears it, so we must only read it in this irq handler!
- */
- mr = rtt_readl(rtc, MR) & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
- sr = rtt_readl(rtc, SR) & mr;
- if (!sr)
- return IRQ_NONE;
-
- /* alarm status */
- if (sr & AT91_RTT_ALMS)
- events |= (RTC_AF | RTC_IRQF);
-
- /* timer update/increment */
- if (sr & AT91_RTT_RTTINC)
- events |= (RTC_UF | RTC_IRQF);
-
- rtc_update_irq(rtc->rtcdev, 1, events);
-
- pr_debug("%s: num=%ld, events=0x%02lx\n", __FUNCTION__,
- events >> 8, events & 0x000000FF);
-
- return IRQ_HANDLED;
-}
-
-static const struct rtc_class_ops at91_rtc_ops = {
- .ioctl = at91_rtc_ioctl,
- .read_time = at91_rtc_readtime,
- .set_time = at91_rtc_settime,
- .read_alarm = at91_rtc_readalarm,
- .set_alarm = at91_rtc_setalarm,
- .proc = at91_rtc_proc,
-};
-
-/*
- * Initialize and install RTC driver
- */
-static int __init at91_rtc_probe(struct platform_device *pdev)
-{
- struct resource *r;
- struct sam9_rtc *rtc;
- int ret;
- u32 mr;
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r)
- return -ENODEV;
-
- rtc = kzalloc(sizeof *rtc, GFP_KERNEL);
- if (!rtc)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, rtc);
- rtc->rtt = (void __force __iomem *) (AT91_VA_BASE_SYS - AT91_BASE_SYS);
- rtc->rtt += r->start;
-
- mr = rtt_readl(rtc, MR);
-
- /* unless RTT is counting at 1 Hz, re-initialize it */
- if ((mr & AT91_RTT_RTPRES) != AT91_SLOW_CLOCK) {
- mr = AT91_RTT_RTTRST | (AT91_SLOW_CLOCK & AT91_RTT_RTPRES);
- gpbr_writel(rtc, 0);
- }
-
- /* disable all interrupts (same as on shutdown path) */
- mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
- rtt_writel(rtc, MR, mr);
-
- rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev,
- &at91_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc->rtcdev)) {
- ret = PTR_ERR(rtc->rtcdev);
- goto fail;
- }
-
- /* register irq handler after we know what name we'll use */
- ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
- IRQF_DISABLED | IRQF_SHARED,
- rtc->rtcdev->dev.bus_id, rtc);
- if (ret) {
- dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
- rtc_device_unregister(rtc->rtcdev);
- goto fail;
- }
-
- /* NOTE: sam9260 rev A silicon has a ROM bug which resets the
- * RTT on at least some reboots. If you have that chip, you must
- * initialize the time from some external source like a GPS, wall
- * clock, discrete RTC, etc
- */
-
- if (gpbr_readl(rtc) == 0)
- dev_warn(&pdev->dev, "%s: SET TIME!\n",
- rtc->rtcdev->dev.bus_id);
-
- return 0;
-
-fail:
- platform_set_drvdata(pdev, NULL);
- kfree(rtc);
- return ret;
-}
-
-/*
- * Disable and remove the RTC driver
- */
-static int __exit at91_rtc_remove(struct platform_device *pdev)
-{
- struct sam9_rtc *rtc = platform_get_drvdata(pdev);
- u32 mr = rtt_readl(rtc, MR);
-
- /* disable all interrupts */
- rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN));
- free_irq(AT91_ID_SYS, rtc);
-
- rtc_device_unregister(rtc->rtcdev);
-
- platform_set_drvdata(pdev, NULL);
- kfree(rtc);
- return 0;
-}
-
-static void at91_rtc_shutdown(struct platform_device *pdev)
-{
- struct sam9_rtc *rtc = platform_get_drvdata(pdev);
- u32 mr = rtt_readl(rtc, MR);
-
- rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
- rtt_writel(rtc, MR, mr & ~rtc->imr);
-}
-
-#ifdef CONFIG_PM
-
-/* AT91SAM9 RTC Power management control */
-
-static int at91_rtc_suspend(struct platform_device *pdev,
- pm_message_t state)
-{
- struct sam9_rtc *rtc = platform_get_drvdata(pdev);
- u32 mr = rtt_readl(rtc, MR);
-
- /*
- * This IRQ is shared with DBGU and other hardware which isn't
- * necessarily a wakeup event source.
- */
- rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
- if (rtc->imr) {
- if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) {
- enable_irq_wake(AT91_ID_SYS);
- /* don't let RTTINC cause wakeups */
- if (mr & AT91_RTT_RTTINCIEN)
- rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN);
- } else
- rtt_writel(rtc, MR, mr & ~rtc->imr);
- }
-
- return 0;
-}
-
-static int at91_rtc_resume(struct platform_device *pdev)
-{
- struct sam9_rtc *rtc = platform_get_drvdata(pdev);
- u32 mr;
-
- if (rtc->imr) {
- if (device_may_wakeup(&pdev->dev))
- disable_irq_wake(AT91_ID_SYS);
- mr = rtt_readl(rtc, MR);
- rtt_writel(rtc, MR, mr | rtc->imr);
- }
-
- return 0;
-}
-#else
-#define at91_rtc_suspend NULL
-#define at91_rtc_resume NULL
-#endif
-
-static struct platform_driver at91_rtc_driver = {
- .driver.name = "rtc-at91sam9",
- .driver.owner = THIS_MODULE,
- .remove = __exit_p(at91_rtc_remove),
- .shutdown = at91_rtc_shutdown,
- .suspend = at91_rtc_suspend,
- .resume = at91_rtc_resume,
-};
-
-/* Chips can have more than one RTT module, and they can be used for more
- * than just RTCs. So we can't just register as "the" RTT driver.
- *
- * A normal approach in such cases is to create a library to allocate and
- * free the modules. Here we just use bus_find_device() as like such a
- * library, binding directly ... no runtime "library" footprint is needed.
- */
-static int __init at91_rtc_match(struct device *dev, void *v)
-{
- struct platform_device *pdev = to_platform_device(dev);
- int ret;
-
- /* continue searching if this isn't the RTT we need */
- if (strcmp("at91_rtt", pdev->name) != 0
- || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT)
- goto fail;
-
- /* else we found it ... but fail unless we can bind to the RTC driver */
- if (dev->driver) {
- dev_dbg(dev, "busy, can't use as RTC!\n");
- goto fail;
- }
- dev->driver = &at91_rtc_driver.driver;
- if (device_attach(dev) == 0) {
- dev_dbg(dev, "can't attach RTC!\n");
- goto fail;
- }
- ret = at91_rtc_probe(pdev);
- if (ret == 0)
- return true;
-
- dev_dbg(dev, "RTC probe err %d!\n", ret);
-fail:
- return false;
-}
-
-static int __init at91_rtc_init(void)
-{
- int status;
- struct device *rtc;
-
- status = platform_driver_register(&at91_rtc_driver);
- if (status)
- return status;
- rtc = bus_find_device(&platform_bus_type, NULL,
- NULL, at91_rtc_match);
- if (!rtc)
- platform_driver_unregister(&at91_rtc_driver);
- return rtc ? 0 : -ENODEV;
-}
-module_init(at91_rtc_init);
-
-static void __exit at91_rtc_exit(void)
-{
- platform_driver_unregister(&at91_rtc_driver);
-}
-module_exit(at91_rtc_exit);
-
-
-MODULE_AUTHOR("Michel Benoit");
-MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x");
-MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/rtc/rtc-bfin.c b/trunk/drivers/rtc/rtc-bfin.c
index d90ba860d216..1aa709dda0d6 100644
--- a/trunk/drivers/rtc/rtc-bfin.c
+++ b/trunk/drivers/rtc/rtc-bfin.c
@@ -1,6 +1,6 @@
/*
* Blackfin On-Chip Real Time Clock Driver
- * Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789]
+ * Supports BF53[123]/BF53[467]/BF54[2489]
*
* Copyright 2004-2007 Analog Devices Inc.
*
@@ -32,25 +32,26 @@
* writes to clear status registers complete immediately.
*/
+#include
+#include
#include
-#include
-#include
+#include
#include
-#include
-#include
-#include
#include
-#include
#include