diff -Nru a/CREDITS b/CREDITS --- a/CREDITS Thu Jan 8 23:00:24 2004 +++ b/CREDITS Thu Jan 8 23:00:24 2004 @@ -1567,7 +1567,7 @@ E: mk@isl.rdc.toshiba.co.jp E: mk@karaba.org W: http://www.karaba.org/~mk/ -P: 1024D/2EC7E30D 9A35 D378 F084 9EA4 EFBA 925B 1C93 B376 F0EF BE59 +P: 1024D/2EC7E30D 4DC3 949B 5A6C F0D6 375F 4472 8888 A8E1 2EC7 E30D D: IPsec, IPv6 D: USAGI/WIDE Project, TOSHIBA CORPORATION S: 2-47-8, Takinogawa, @@ -2669,6 +2669,13 @@ S: 70110 Kuopio S: Finland +N: Luca Risolia +E: luca_ing@libero.it +D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chip +S: Via Libertà 41/a +S: Osio Sotto, 24046, Bergamo +S: Italy + N: William E. Roadcap E: roadcapw@cfw.com W: http://www.cfw.com/~roadcapw @@ -3569,4 +3576,4 @@ # alphabetically. Leonard used to be very proud of being the # last entry, and he'll get positively pissed if he can't even # be second-to-last. (and this file really _is_ supposed to be -# in alphabetic order) +# in alphabetic order) diff -Nru a/Documentation/Changes b/Documentation/Changes --- a/Documentation/Changes Thu Jan 8 23:00:24 2004 +++ b/Documentation/Changes Thu Jan 8 23:00:24 2004 @@ -56,7 +56,7 @@ o e2fsprogs 1.29 # tune2fs o jfsutils 1.1.3 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs -o xfsprogs 2.1.0 # xfs_db -V +o xfsprogs 2.6.0 # xfs_db -V o pcmcia-cs 3.1.21 # cardmgr -V o quota-tools 3.09 # quota -V o PPP 2.4.0 # pppd --version @@ -183,9 +183,8 @@ The latest version of xfsprogs contains mkfs.xfs, xfs_db, and the xfs_repair utilities, among others, for the XFS filesystem. It is architecture independent and any version from 2.0.0 onward should -work correctly with this version of the XFS kernel code. For the new -(v2) log format that has better support for stripe-size aligning on -LVM and MD devices at least xfsprogs 2.1.0 is needed. +work correctly with this version of the XFS kernel code (2.6.0 or +later is recommended, due to some significant improvements). Pcmcia-cs @@ -359,7 +358,7 @@ Xfsprogs -------- -o +o Pcmcia-cs --------- diff -Nru a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl --- a/Documentation/DocBook/kernel-locking.tmpl Thu Jan 8 23:00:23 2004 +++ b/Documentation/DocBook/kernel-locking.tmpl Thu Jan 8 23:00:23 2004 @@ -6,8 +6,7 @@ - Paul - Rusty + Rusty Russell
@@ -18,8 +17,8 @@ - 2000 - Paul Russell + 2003 + Rusty Russell @@ -58,16 +57,17 @@ Welcome, to Rusty's Remarkably Unreliable Guide to Kernel Locking issues. This document describes the locking systems in - the Linux Kernel as we approach 2.4. + the Linux Kernel in 2.6. - It looks like SMP - is here to stay; so everyone hacking on the kernel - these days needs to know the fundamentals of concurrency and locking - for SMP. + With the wide availability of HyperThreading, and preemption in the Linux + Kernel, everyone hacking on the kernel needs to know the + fundamentals of concurrency and locking for + SMP. - + The Problem With Concurrency (Skip this if you know what a Race Condition is). @@ -169,15 +169,23 @@ + + Race Conditions and Critical Regions - This overlap, where what actually happens depends on the - relative timing of multiple tasks, is called a race condition. + This overlap, where the result depends on the + relative timing of multiple tasks, is called a race condition. The piece of code containing the concurrency issue is called a - critical region. And especially since Linux starting running + critical region. And especially since Linux starting running on SMP machines, they became one of the major issues in kernel design and implementation. + Preemption can have the same effect, even if there is only one + CPU: by preempting one task during the critical region, we have + exactly the same race condition. In this case the thread which + preempts might run the critical region itself. + + The solution is to recognize when these simultaneous accesses occur, and use locks to make sure that only one instance can enter the critical region at any time. There are many @@ -185,10 +193,28 @@ And then there are the unfriendly primitives, but I'll pretend they don't exist. - + Locking in the Linux Kernel + + + If I could give you one piece of advice: never sleep with anyone + crazier than yourself. But if I had to give you advice on + locking: keep it simple. + + + + Be reluctant to introduce new locks. + + + + Strangely enough, this last one is the exact reverse of my advice when + you have slept with someone crazier than yourself. + And you should think about getting a big dog. + + + Two Main Types of Kernel Locks: Spinlocks and Semaphores @@ -213,23 +239,32 @@ Neither type of lock is recursive: see - . + . + Locks and Uniprocessor Kernels - For kernels compiled without CONFIG_SMP, spinlocks - do not exist at all. This is an excellent design decision: when - no-one else can run at the same time, there is no reason to - have a lock at all. + For kernels compiled without CONFIG_SMP, and + without CONFIG_PREEMPT spinlocks do not exist at + all. This is an excellent design decision: when no-one else can + run at the same time, there is no reason to have a lock. + + + + If the kernel is compiled without CONFIG_SMP, + but CONFIG_PREEMPT is set, then spinlocks + simply disable preemption, which is sufficient to prevent any + races. For most purposes, we can think of preemption as + equivalent to SMP, and not worry about it separately. You should always test your locking code with CONFIG_SMP - enabled, even if you don't have an SMP test box, because it - will still catch some (simple) kinds of deadlock. + and CONFIG_PREEMPT enabled, even if you don't have an SMP test box, because it + will still catch some kinds of locking bugs. @@ -239,25 +274,6 @@ - - Read/Write Lock Variants - - - Both spinlocks and semaphores have read/write variants: - rwlock_t and struct rw_semaphore. - These divide users into two classes: the readers and the writers. If - you are only reading the data, you can get a read lock, but to write to - the data you need the write lock. Many people can hold a read lock, - but a writer must be sole holder. - - - - This means much smoother locking if your code divides up - neatly along reader/writer lines. All the discussions below - also apply to read/write variants. - - - Locking Only In User Context @@ -289,17 +305,26 @@ - Locking Between User Context and BHs + Locking Between User Context and Softirqs - If a bottom half shares + If a softirq shares data with user context, you have two problems. Firstly, the current - user context can be interrupted by a bottom half, and secondly, the + user context can be interrupted by a softirq, and secondly, the critical region could be entered from another CPU. This is where spin_lock_bh() (include/linux/spinlock.h) is - used. It disables bottom halves on that CPU, then grabs the lock. - spin_unlock_bh() does the reverse. + used. It disables softirqs on that CPU, then grabs the lock. + spin_unlock_bh() does the reverse. (The + '_bh' suffix is a historical reference to "Bottom Halves", the + old name for software interrupts. It should really be + called spin_lock_softirq()' in a perfect world). + + + + Note that you can also use spin_lock_irq() + or spin_lock_irqsave() here, which stop + hardware interrupts as well: see . @@ -307,70 +332,41 @@ as well: the spin lock vanishes, and this macro simply becomes local_bh_disable() (include/linux/interrupt.h), which - protects you from the bottom half being run. + protects you from the softirq being run. - Locking Between User Context and Tasklets/Soft IRQs + Locking Between User Context and Tasklets - This is exactly the same as above, because - local_bh_disable() actually disables all - softirqs and tasklets - on that CPU as well. It should really be - called `local_softirq_disable()', but the name has been preserved - for historical reasons. Similarly, - spin_lock_bh() would now be called - spin_lock_softirq() in a perfect world. + This is exactly the same as above, because tasklets are actually run + from a softirq. - - Locking Between Bottom Halves + + Locking Between User Context and Timers - Sometimes a bottom half might want to share data with - another bottom half (especially remember that timers are run - off a bottom half). + This, too, is exactly the same as above, because timers are actually run from + a softirq. From a locking point of view, tasklets and timers + are identical. - - - The Same BH - - - Since a bottom half is never run on two CPUs at once, you - don't need to worry about your bottom half being run twice - at once, even on SMP. - - - - - Different BHs - - - Since only one bottom half ever runs at a time once, you - don't need to worry about race conditions with other bottom - halves. Beware that things might change under you, however, - if someone changes your bottom half to a tasklet. If you - want to make your code future-proof, pretend you're already - running from a tasklet (see below), and doing the extra - locking. Of course, if it's five years before that happens, - you're gonna look like a damn fool. - - - Locking Between Tasklets + Locking Between Tasklets/Timers - Sometimes a tasklet might want to share data with another - tasklet, or a bottom half. + Sometimes a tasklet or timer might want to share data with + another tasklet or timer. - The Same Tasklet + The Same Tasklet/Timer Since a tasklet is never run on two CPUs at once, you don't need to worry about your tasklet being reentrant (running @@ -379,10 +375,10 @@ - Different Tasklets + Different Tasklets/Timers - If another tasklet (or bottom half, such as a timer) wants - to share data with your tasklet, you will both need to use + If another tasklet/timer wants + to share data with your tasklet or timer , you will both need to use spin_lock() and spin_unlock() calls. spin_lock_bh() is @@ -396,8 +392,8 @@ Locking Between Softirqs - Often a softirq might - want to share data with itself, a tasklet, or a bottom half. + Often a softirq might + want to share data with itself or a tasklet/timer. @@ -421,10 +417,10 @@ Different Softirqs - You'll need to use spin_lock() and - spin_unlock() for shared data, whether it - be a timer (which can be running on a different CPU), bottom half, - tasklet or the same or another softirq. + You'll need to use spin_lock() and + spin_unlock() for shared data, whether it + be a timer, tasklet, different softirq or the same or another + softirq: any of them could be running on a different CPU. @@ -434,13 +430,13 @@ Hard IRQ Context - Hardware interrupts usually communicate with a bottom half, + Hardware interrupts usually communicate with a tasklet or softirq. Frequently this involves putting work in a - queue, which the BH/softirq will take out. + queue, which the softirq will take out. - Locking Between Hard IRQ and Softirqs/Tasklets/BHs + Locking Between Hard IRQ and Softirqs/Tasklets If a hardware irq handler shares data with a softirq, you have @@ -453,6 +449,16 @@ + The irq handler does not to use + spin_lock_irq(), because the softirq cannot + run while the irq handler is running: it can use + spin_lock(), which is slightly faster. The + only exception would be if a different hardware irq handler uses + the same lock: spin_lock_irq() will stop + that from interrupting us. + + + This works perfectly for UP as well: the spin lock vanishes, and this macro simply becomes local_irq_disable() (include/asm/smp.h), which @@ -468,60 +474,766 @@ interrupts are already off) and in softirqs (where the irq disabling is required). + + + Note that softirqs (and hence tasklets and timers) are run on + return from hardware interrupts, so + spin_lock_irq() also stops these. In that + sense, spin_lock_irqsave() is the most + general and powerful locking function. + + + + + Locking Between Two Hard IRQ Handlers + + It is rare to have to share data between two IRQ handlers, but + if you do, spin_lock_irqsave() should be + used: it is architecture-specific whether all interrupts are + disabled inside irq handlers themselves. + - - - Common Techniques + + + Cheat Sheet For Locking - This section lists some common dilemmas and the standard - solutions used in the Linux kernel code. If you use these, - people will find your code simpler to understand. + Pete Zaitcev gives the following summary: + + + + If you are in a process context (any syscall) and want to + lock other process out, use a semaphore. You can take a semaphore + and sleep (copy_from_user*( or + kmalloc(x,GFP_KERNEL)). + + + + + Otherwise (== data can be touched in an interrupt), use + spin_lock_irqsave() and + spin_unlock_irqrestore(). + + + + + Avoid holding spinlock for more than 5 lines of code and + across any function call (except accessors like + readb). + + + - - If I could give you one piece of advice: never sleep with anyone - crazier than yourself. But if I had to give you advice on - locking: keep it simple. - + + Table of Minimum Requirements - - Lock data, not code. + The following table lists the minimum + locking requirements between various contexts. In some cases, + the same context can only be running on one CPU at a time, so + no locking is required for that context (eg. a particular + thread can only run on one CPU at a time, but if it needs + shares data with another thread, locking is required). - - Be reluctant to introduce new locks. + Remember the advice above: you can always use + spin_lock_irqsave(), which is a superset + of all other spinlock primitives. + +Table of Locking Requirements + + + + +IRQ Handler A +IRQ Handler B +Softirq A +Softirq B +Tasklet A +Tasklet B +Timer A +Timer B +User Context A +User Context B + + + +IRQ Handler A +None + + + +IRQ Handler B +spin_lock_irqsave +None + + + +Softirq A +spin_lock_irq +spin_lock_irq +spin_lock + + + +Softirq B +spin_lock_irq +spin_lock_irq +spin_lock +spin_lock + + + +Tasklet A +spin_lock_irq +spin_lock_irq +spin_lock +spin_lock +None + + + +Tasklet B +spin_lock_irq +spin_lock_irq +spin_lock +spin_lock +spin_lock +None + + + +Timer A +spin_lock_irq +spin_lock_irq +spin_lock +spin_lock +spin_lock +spin_lock +None + + + +Timer B +spin_lock_irq +spin_lock_irq +spin_lock +spin_lock +spin_lock +spin_lock +spin_lock +None + + + +User Context A +spin_lock_irq +spin_lock_irq +spin_lock_bh +spin_lock_bh +spin_lock_bh +spin_lock_bh +spin_lock_bh +spin_lock_bh +None + + + +User Context B +spin_lock_irq +spin_lock_irq +spin_lock_bh +spin_lock_bh +spin_lock_bh +spin_lock_bh +spin_lock_bh +spin_lock_bh +down_interruptible +None + + + + +
+
+ + + Common Examples + +Let's step through a simple example: a cache of number to name +mappings. The cache keeps a count of how often each of the objects is +used, and when it gets full, throws out the least used one. + + + + + All In User Context + +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 semaphore to protect the cache and all the objects within +it. Here's the code: + - - Strangely enough, this is the exact reverse of my advice when - you have slept with someone crazier than yourself. - + +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <asm/semaphore.h> +#include <asm/errno.h> + +struct object +{ + struct list_head list; + int id; + char name[32]; + int popularity; +}; + +/* Protects the cache, cache_num, and the objects within it */ +static DECLARE_MUTEX(cache_lock); +static LIST_HEAD(cache); +static unsigned int cache_num = 0; +#define MAX_CACHE_SIZE 10 + +/* Must be holding cache_lock */ +static struct object *__cache_find(int id) +{ + struct object *i; + + list_for_each_entry(i, &cache, list) + if (i->id == id) { + i->popularity++; + return i; + } + return NULL; +} - - No Writers in Interrupt Context +/* Must be holding cache_lock */ +static void __cache_delete(struct object *obj) +{ + BUG_ON(!obj); + list_del(&obj->list); + kfree(obj); + cache_num--; +} + +/* Must be holding cache_lock */ +static void __cache_add(struct object *obj) +{ + list_add(&obj->list, &cache); + if (++cache_num > MAX_CACHE_SIZE) { + struct object *i, *outcast = NULL; + list_for_each_entry(i, &cache, list) { + if (!outcast || i->popularity < outcast->popularity) + outcast = i; + } + __cache_delete(outcast); + } +} - - There is a fairly common case where an interrupt handler needs - access to a critical region, but does not need write access. - In this case, you do not need to use - read_lock_irq(), but only - read_lock() everywhere (since if an interrupt - occurs, the irq handler will only try to grab a read lock, which - won't deadlock). You will still need to use - write_lock_irq(). +int cache_add(int id, const char *name) +{ + struct object *obj; + + if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) + return -ENOMEM; + + strlcpy(obj->name, name, sizeof(obj->name)); + obj->id = id; + obj->popularity = 0; + + down(&cache_lock); + __cache_add(obj); + up(&cache_lock); + return 0; +} + +void cache_delete(int id) +{ + down(&cache_lock); + __cache_delete(__cache_find(id)); + up(&cache_lock); +} + +int cache_find(int id, char *name) +{ + struct object *obj; + int ret = -ENOENT; + + down(&cache_lock); + obj = __cache_find(id); + if (obj) { + ret = 0; + strcpy(name, obj->name); + } + up(&cache_lock); + return ret; +} + + + +Note that we always make sure we have the cache_lock when we add, +delete, or look up the cache: both the cache infrastructure itself and +the contents of the objects are protected by the lock. In this case +it's easy, since we copy the data for the user, and never let them +access the objects directly. + + +There is a slight (and common) optimization here: in +cache_add we set up the fields of the object +before grabbing the lock. This is safe, as no-one else can access it +until we put it in cache. + + + + + Accessing From Interrupt Context + +Now consider the case where cache_find can be +called from interrupt context: either a hardware interrupt or a +softirq. An example would be a timer which deletes object from the +cache. + + +The change is shown below, in standard patch format: the +- are lines which are taken away, and the ++ are lines which are added. + + +--- cache.c.usercontext 2003-12-09 13:58:54.000000000 +1100 ++++ cache.c.interrupt 2003-12-09 14:07:49.000000000 +1100 +@@ -12,7 +12,7 @@ + int popularity; + }; + +-static DECLARE_MUTEX(cache_lock); ++static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED; + static LIST_HEAD(cache); + static unsigned int cache_num = 0; + #define MAX_CACHE_SIZE 10 +@@ -55,6 +55,7 @@ + int cache_add(int id, const char *name) + { + struct object *obj; ++ unsigned long flags; + + if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) + return -ENOMEM; +@@ -63,30 +64,33 @@ + obj->id = id; + obj->popularity = 0; + +- down(&cache_lock); ++ spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); +- up(&cache_lock); ++ spin_unlock_irqrestore(&cache_lock, flags); + return 0; + } + + void cache_delete(int id) + { +- down(&cache_lock); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&cache_lock, flags); + __cache_delete(__cache_find(id)); +- up(&cache_lock); ++ spin_unlock_irqrestore(&cache_lock, flags); + } + + int cache_find(int id, char *name) + { + struct object *obj; + int ret = -ENOENT; ++ unsigned long flags; + +- down(&cache_lock); ++ spin_lock_irqsave(&cache_lock, flags); + obj = __cache_find(id); + if (obj) { + ret = 0; + strcpy(name, obj->name); + } +- up(&cache_lock); ++ spin_unlock_irqrestore(&cache_lock, flags); + return ret; + } + + + +Note that the spin_lock_irqsave will turn off +interrupts if they are on, otherwise does nothing (if we are already +in an interrupt handler), hence these functions are safe to call from +any context. + + +Unfortunately, cache_add calls +kmalloc with the GFP_KERNEL +flag, which is only legal in user context. I have assumed that +cache_add is still only called in user context, +otherwise this should become a parameter to +cache_add. + + + + Exposing Objects Outside This File + +If our objects contained more information, it might not be sufficient +to copy the information in and out: other parts of the code might want +to keep pointers to these objects, for example, rather than looking up +the id every time. This produces two problems. + + +The first problem is that we use the cache_lock to +protect objects: we'd need to make this non-static so the rest of the +code can use it. This makes locking trickier, as it is no longer all +in one place. + + +The second problem is the lifetime problem: if another structure keeps +a pointer to an object, it presumably expects that pointer to remain +valid. Unfortunately, this is only guaranteed while you hold the +lock, otherwise someone might call cache_delete +and even worse, add another object, re-using the same address. + + +As there is only one lock, you can't hold it forever: no-one else would +get any work done. + + +The solution to this problem is to use a reference count: everyone who +has a pointer to the object increases it when they first get the +object, and drops the reference count when they're finished with it. +Whoever drops it to zero knows it is unused, and can actually delete it. + + +Here is the code: + + + +--- cache.c.interrupt 2003-12-09 14:25:43.000000000 +1100 ++++ cache.c.refcnt 2003-12-09 14:33:05.000000000 +1100 +@@ -7,6 +7,7 @@ + struct object + { + struct list_head list; ++ unsigned int refcnt; + int id; + char name[32]; + int popularity; +@@ -17,6 +18,35 @@ + static unsigned int cache_num = 0; + #define MAX_CACHE_SIZE 10 + ++static void __object_put(struct object *obj) ++{ ++ if (--obj->refcnt == 0) ++ kfree(obj); ++} ++ ++static void __object_get(struct object *obj) ++{ ++ obj->refcnt++; ++} ++ ++void object_put(struct object *obj) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&cache_lock, flags); ++ __object_put(obj); ++ spin_unlock_irqrestore(&cache_lock, flags); ++} ++ ++void object_get(struct object *obj) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&cache_lock, flags); ++ __object_get(obj); ++ spin_unlock_irqrestore(&cache_lock, flags); ++} ++ + /* Must be holding cache_lock */ + static struct object *__cache_find(int id) + { +@@ -35,6 +65,7 @@ + { + BUG_ON(!obj); + list_del(&obj->list); ++ __object_put(obj); + cache_num--; + } + +@@ -63,6 +94,7 @@ + strlcpy(obj->name, name, sizeof(obj->name)); + obj->id = id; + obj->popularity = 0; ++ obj->refcnt = 1; /* The cache holds a reference */ + + spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); +@@ -79,18 +111,15 @@ + spin_unlock_irqrestore(&cache_lock, flags); + } + +-int cache_find(int id, char *name) ++struct object *cache_find(int id) + { + struct object *obj; +- int ret = -ENOENT; + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + obj = __cache_find(id); +- if (obj) { +- ret = 0; +- strcpy(name, obj->name); +- } ++ if (obj) ++ __object_get(obj); + spin_unlock_irqrestore(&cache_lock, flags); +- return ret; ++ return obj; + } + + + +We encapsulate the reference counting in the standard 'get' and 'put' +functions. Now we can return the object itself from +cache_find which has the advantage that the user +can now sleep holding the object (eg. to +copy_to_user to name to userspace). + + +The other point to note is that I said a reference should be held for +every pointer to the object: thus the reference count is 1 when first +inserted into the cache. In some versions the framework does not hold +a reference count, but they are more complicated. + + + + Using Atomic Operations For The Reference Count + +In practice, atomic_t would usually be used for +refcnt. There are a number of atomic +operations defined in + +include/asm/atomic.h: these are +guaranteed to be seen atomically from all CPUs in the system, so no +lock is required. In this case, it is simpler than using spinlocks, +although for anything non-trivial using spinlocks is clearer. The +atomic_inc and +atomic_dec_and_test are used instead of the +standard increment and decrement operators, and the lock is no longer +used to protect the reference count itself. + + + +--- cache.c.refcnt 2003-12-09 15:00:35.000000000 +1100 ++++ cache.c.refcnt-atomic 2003-12-11 15:49:42.000000000 +1100 +@@ -7,7 +7,7 @@ + struct object + { + struct list_head list; +- unsigned int refcnt; ++ atomic_t refcnt; + int id; + char name[32]; + int popularity; +@@ -18,33 +18,15 @@ + static unsigned int cache_num = 0; + #define MAX_CACHE_SIZE 10 + +-static void __object_put(struct object *obj) +-{ +- if (--obj->refcnt == 0) +- kfree(obj); +-} +- +-static void __object_get(struct object *obj) +-{ +- obj->refcnt++; +-} +- + void object_put(struct object *obj) + { +- unsigned long flags; +- +- spin_lock_irqsave(&cache_lock, flags); +- __object_put(obj); +- spin_unlock_irqrestore(&cache_lock, flags); ++ if (atomic_dec_and_test(&obj->refcnt)) ++ kfree(obj); + } + + void object_get(struct object *obj) + { +- unsigned long flags; +- +- spin_lock_irqsave(&cache_lock, flags); +- __object_get(obj); +- spin_unlock_irqrestore(&cache_lock, flags); ++ atomic_inc(&obj->refcnt); + } + + /* Must be holding cache_lock */ +@@ -65,7 +47,7 @@ + { + BUG_ON(!obj); + list_del(&obj->list); +- __object_put(obj); ++ object_put(obj); + cache_num--; + } + +@@ -94,7 +76,7 @@ + strlcpy(obj->name, name, sizeof(obj->name)); + obj->id = id; + obj->popularity = 0; +- obj->refcnt = 1; /* The cache holds a reference */ ++ atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ + + spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); +@@ -119,7 +101,7 @@ + spin_lock_irqsave(&cache_lock, flags); + obj = __cache_find(id); + if (obj) +- __object_get(obj); ++ object_get(obj); + spin_unlock_irqrestore(&cache_lock, flags); + return obj; + } + + + + + Protecting The Objects Themselves + +In these examples, we assumed that the objects (except the reference +counts) never changed once they are created. If we wanted to allow +the name to change, there are three possibilities: + + + +You can make cache_lock non-static, and tell people +to grab that lock before changing the name in any object. + + + + +You can provide a cache_obj_rename which grabs +this lock and changes the name for the caller, and tell everyone to +use that function. + + + + +You can make the cache_lock protect only the cache +itself, and use another lock to protect the name. + + + - - Similar logic applies to locking between softirqs/tasklets/BHs - which never need a write lock, and user context: - read_lock() and - write_lock_bh(). - - + +Theoretically, you can make the locks as fine-grained as one lock for +every field, for every object. In practice, the most common variants +are: + + + + +One lock which protects the infrastructure (the cache +list in this example) and all the objects. This is what we have done +so far. + + + + +One lock which protects the infrastructure (including the list +pointers inside the objects), and one lock inside the object which +protects the rest of that object. + + + + +Multiple locks to protect the infrastructure (eg. one lock per hash +chain), possibly with a separate per-object lock. + + + - + +Here is the "lock-per-object" implementation: + + +--- cache.c.refcnt-atomic 2003-12-11 15:50:54.000000000 +1100 ++++ cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 +@@ -6,11 +6,17 @@ + + struct object + { ++ /* These two protected by cache_lock. */ + struct list_head list; ++ int popularity; ++ + atomic_t refcnt; ++ ++ /* Doesn't change once created. */ + int id; ++ ++ spinlock_t lock; /* Protects the name */ + char name[32]; +- int popularity; + }; + + static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED; +@@ -77,6 +84,7 @@ + obj->id = id; + obj->popularity = 0; + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ ++ spin_lock_init(&obj->lock); + + spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); + + + +Note that I decide that the popularity +count should be protected by the cache_lock rather +than the per-object lock: this is because it (like the +struct list_head inside the object) is +logically part of the infrastructure. This way, I don't need to grab +the lock of every object in __cache_add when +seeking the least popular. + + + +I also decided that the id member is +unchangeable, so I don't need to grab each object lock in +__cache_find() to examine the +id: the object lock is only used by a +caller who wants to read or write the name +field. + + + +Note also that I added a comment describing what data was protected by +which locks. This is extremely important, as it describes the runtime +behavior of the code, and can be hard to gain from just reading. And +as Alan Cox says, Lock data, not code. + + + + + Common Problems + Deadlock: Simple and Advanced @@ -535,10 +1247,10 @@ For a slightly more complex case, imagine you have a region - shared by a bottom half and user context. If you use a + shared by a softirq and user context. If you use a spin_lock() call to protect it, it is - possible that the user context will be interrupted by the bottom - half while it holds the lock, and the bottom half will then spin + possible that the user context will be interrupted by the softirq + while it holds the lock, and the softirq will then spin forever trying to get the same lock. @@ -558,7 +1270,7 @@ - A more complex problem is the so-called `deadly embrace', + A more complex problem is the so-called 'deadly embrace', involving two or more locks. Say you have a hash table: each entry in the table is a spinlock, and a chain of hashed objects. Inside a softirq handler, you sometimes want to @@ -606,7 +1318,7 @@ their lock. It will look, smell, and feel like a crash. - + Preventing Deadlock @@ -634,7 +1346,6 @@ will do?). Remember, the other programmers are out to get you, so don't do this. - Overzealous Prevention Of Deadlocks @@ -650,266 +1361,481 @@ If you don't see why, please stay the fuck away from my code. - +
- - Per-CPU Data - - - A great technique for avoiding locking which is used fairly - widely is to duplicate information for each CPU. For example, - if you wanted to keep a count of a common condition, you could - use a spin lock and a single counter. Nice and simple. - + + Racing Timers: A Kernel Pastime - If that was too slow [it's probably not], you could instead - use a counter for each CPU [don't], then none of them need an - exclusive lock [you're wasting your time here]. To make sure - the CPUs don't have to synchronize caches all the time, align - the counters to cache boundaries by appending - `__cacheline_aligned' to the declaration - (include/linux/cache.h). - [Can't you think of anything better to do?] + Timers can produce their own special problems with races. + Consider a collection of objects (list, hash, etc) where each + object has a timer which is due to destroy it. - They will need a read lock to access their own counters, - however. That way you can use a write lock to grant exclusive - access to all of them at once, to tally them up. + If you want to destroy the entire collection (say on module + removal), you might do the following: - - - Big Reader Locks + + /* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE + HUNGARIAN NOTATION */ + spin_lock_bh(&list_lock); - - A classic example of per-CPU information is Ingo's `big - reader' locks - (linux/include/brlock.h). These - use the Per-CPU Data techniques described above to create a lock which - is very fast to get a read lock, but agonizingly slow for a write - lock. - + while (list) { + struct foo *next = list->next; + del_timer(&list->timer); + kfree(list); + list = next; + } + + spin_unlock_bh(&list_lock); + - Fortunately, there are a limited number of these locks - available: you have to go through a strict interview process - to get one. + Sooner or later, this will crash on SMP, because a timer can + have just gone off before the spin_lock_bh(), + and it will only get the lock after we + spin_unlock_bh(), and then try to free + the element (which has already been freed!). - - - - Avoiding Locks: Read And Write Ordering - Sometimes it is possible to avoid locking. Consider the - following case from the 2.2 firewall code, which inserted an - element into a single linked list in user context: + This can be avoided by checking the result of + del_timer(): if it returns + 1, the timer has been deleted. + If 0, it means (in this + case) that it is currently running, so we can do: - new->next = i->next; - i->next = new; - + retry: + spin_lock_bh(&list_lock); - - Here the author (Alan Cox, who knows what he's doing) assumes - that the pointer assignments are atomic. This is important, - because networking packets would traverse this list on bottom - halves without a lock. Depending on their exact timing, they - would either see the new element in the list with a valid - next pointer, or it would not be in the - list yet. A lock is still required against other CPUs inserting - or deleting from the list, of course. - + while (list) { + struct foo *next = list->next; + if (!del_timer(&list->timer)) { + /* Give timer a chance to delete this */ + spin_unlock_bh(&list_lock); + goto retry; + } + kfree(list); + list = next; + } - - Of course, the writes must be in this - order, otherwise the new element appears in the list with an - invalid next pointer, and any other - CPU iterating at the wrong time will jump through it into garbage. - Because modern CPUs reorder, Alan's code actually read as follows: - - - - new->next = i->next; - wmb(); - i->next = new; + spin_unlock_bh(&list_lock); - The wmb() is a write memory barrier - (include/asm/system.h): neither - the compiler nor the CPU will allow any writes to memory after the - wmb() to be visible to other hardware - before any of the writes before the wmb(). + Another common problem is deleting timers which restart + themselves (by calling add_timer() at the end + of their timer function). Because this is a fairly common case + which is prone to races, you should use del_timer_sync() + (include/linux/timer.h) + to handle this case. It returns the number of times the timer + had to be deleted before we finally stopped it from adding itself back + in. + - - As i386 does not do write reordering, this bug would never - show up on that platform. On other SMP platforms, however, it - will. - + + The Fucked Up Sparc - There is also rmb() for read ordering: to ensure - any previous variable reads occur before following reads. The simple - mb() macro combines both - rmb() and wmb(). + Alan Cox says the irq disable/enable is in the register + window on a sparc. Andi Kleen says when you do + restore_flags in a different function you mess up all the + register windows. - Some atomic operations are defined to act as a memory barrier - (ie. as per the mb() macro, but if in - doubt, be explicit. - - Also, - spinlock operations act as partial barriers: operations after - gaining a spinlock will never be moved to precede the - spin_lock() call, and operations before - releasing a spinlock will never be moved after the - spin_unlock() call. - + So never pass the flags word set by + spin_lock_irqsave() and brethren to another + function (unless it's declared inline). Usually no-one + does this, but now you've been warned. Dave Miller can never do + anything in a straightforward manner (I can say that, because I have + pictures of him and a certain PowerPC maintainer in a compromising + position). - - Avoiding Locks: Atomic Operations + + + + Locking Speed - There are a number of atomic operations defined in - include/asm/atomic.h: these - are guaranteed to be seen atomically from all CPUs in the system, thus - avoiding races. If your shared data consists of a single counter, say, - these operations might be simpler than using spinlocks (although for - anything non-trivial using spinlocks is clearer). +There are three main things to worry about when considering speed of +some code which does locking. First is concurrency: how many things +are going to be waiting while someone else is holding a lock. Second +is the time taken to actually acquire and release an uncontended lock. +Third is using fewer, or smarter locks. I'm assuming that the lock is +used fairly often: otherwise, you wouldn't be concerned about +efficiency. + + +Concurrency depends on how long the lock is usually held: you should +hold the lock for as long as needed, but no longer. In the cache +example, we always create the object without the lock held, and then +grab the lock only when we are ready to insert it in the list. + + +Acquisition times depend on how much damage the lock operations do to +the pipeline (pipeline stalls) and how likely it is that this CPU was +the last one to grab the lock (ie. is the lock cache-hot for this +CPU): on a machine with more CPUs, this likelihood drops fast. +Consider a 700MHz Intel Pentium III: an instruction takes about 0.7ns, +an atomic increment takes about 58ns, a lock which is cache-hot on +this CPU takes 160ns, and a cacheline transfer from another CPU takes +an additional 170 to 360ns. (These figures from Paul McKenney's + Linux +Journal RCU article). + + +These two aims conflict: holding a lock for a short time might be done +by splitting locks into parts (such as in our final per-object-lock +example), but this increases the number of lock acquisitions, and the +results are often slower than having a single lock. This is another +reason to advocate locking simplicity. + + +The third concern is addressed below: there are some methods to reduce +the amount of locking which needs to be done. + + + + Read/Write Lock Variants + + + Both spinlocks and semaphores have read/write variants: + rwlock_t and struct rw_semaphore. + These divide users into two classes: the readers and the writers. If + you are only reading the data, you can get a read lock, but to write to + the data you need the write lock. Many people can hold a read lock, + but a writer must be sole holder. - - Note that the atomic operations do in general not act as memory - barriers. Instead you can insert a memory barrier before or - after atomic_inc() or - atomic_dec() by inserting - smp_mb__before_atomic_inc(), - smp_mb__after_atomic_inc(), - smp_mb__before_atomic_dec() or - smp_mb__after_atomic_dec() - respectively. The advantage of using those macros instead of - smp_mb() is, that they are cheaper on some - platforms. - + + If your code divides neatly along reader/writer lines (as our + cache code does), and the lock is held by readers for + significant lengths of time, using these locks can help. They + are slightly slower than the normal locks though, so in practice + rwlock_t is not usually worthwhile. - - Protecting A Collection of Objects: Reference Counts + + Avoiding Locks: Read Copy Update - Locking a collection of objects is fairly easy: you get a - single spinlock, and you make sure you grab it before - searching, adding or deleting an object. + There is a special method of read/write locking called Read Copy + Update. Using RCU, the readers can avoid taking a lock + altogether: as we expect our cache to be read more often than + updated (otherwise the cache is a waste of time), it is a + candidate for this optimization. - The purpose of this lock is not to protect the individual - objects: you might have a separate lock inside each one for - that. It is to protect the data structure - containing the objects from race conditions. Often - the same lock is used to protect the contents of all the - objects as well, for simplicity, but they are inherently - orthogonal (and many other big words designed to confuse). + How do we get rid of read locks? Getting rid of read locks + means that writers may be changing the list underneath the + readers. That is actually quite simple: we can read a linked + list while an element is being added if the writer adds the + element very carefully. For example, adding + new to a single linked list called + list: + + new->next = list->next; + wmb(); + list->next = new; + + - Changing this to a read-write lock will often help markedly if - reads are far more common that writes. If not, there is - another approach you can use to reduce the time the lock is - held: reference counts. + The wmb() is a write memory barrier. It + ensures that the first operation (setting the new element's + next pointer) is complete and will be seen by + all CPUs, before the second operation is (putting the new + element into the list). This is important, since modern + compilers and modern CPUs can both reorder instructions unless + told otherwise: we want a reader to either not see the new + element at all, or see the new element with the + next pointer correctly pointing at the rest of + the list. + + + Fortunately, there is a function to do this for standard + struct list_head lists: + list_add_rcu() + (include/linux/list.h). + + + Removing an element from the list is even simpler: we replace + the pointer to the old element with a pointer to its successor, + and readers will either see it, or skip over it. + + list->next = old->next; + + + There is list_del_rcu() + (include/linux/list.h) which does this (the + normal version poisons the old object, which we don't want). + + + The reader must also be careful: some CPUs can look through the + next pointer to start reading the contents of + the next element early, but don't realize that the pre-fetched + contents is wrong when the next pointer changes + underneath them. Once again, there is a + list_for_each_entry_rcu() + (include/linux/list.h) to help you. Of + course, writers can just use + list_for_each_entry(), since there cannot + be two simultaneous writers. + + + Our final dilemma is this: when can we actually destroy the + removed element? Remember, a reader might be stepping through + this element in the list right now: it we free this element and + the next pointer changes, the reader will jump + off into garbage and crash. We need to wait until we know that + all the readers who were traversing the list when we deleted the + element are finished. We use call_rcu() to + register a callback which will actually destroy the object once + the readers are finished. + + + But how does Read Copy Update know when the readers are + finished? The method is this: firstly, the readers always + traverse the list inside + rcu_read_lock()/rcu_read_unlock() + pairs: these simply disable preemption so the reader won't go to + sleep while reading the list. + + + RCU then waits until every other CPU has slept at least once: + since readers cannot sleep, we know that any readers which were + traversing the list during the deletion are finished, and the + callback is triggered. The real Read Copy Update code is a + little more optimized than this, but this is the fundamental + idea. + + + +--- cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 ++++ cache.c.rcupdate 2003-12-11 17:55:14.000000000 +1100 +@@ -1,15 +1,18 @@ + #include <linux/list.h> + #include <linux/slab.h> + #include <linux/string.h> ++#include <linux/rcupdate.h> + #include <asm/semaphore.h> + #include <asm/errno.h> + + struct object + { +- /* These two protected by cache_lock. */ ++ /* This is protected by RCU */ + struct list_head list; + int popularity; + ++ struct rcu_head rcu; ++ + atomic_t refcnt; + + /* Doesn't change once created. */ +@@ -40,7 +43,7 @@ + { + struct object *i; + +- list_for_each_entry(i, &cache, list) { ++ list_for_each_entry_rcu(i, &cache, list) { + if (i->id == id) { + i->popularity++; + return i; +@@ -49,19 +52,25 @@ + return NULL; + } + ++/* Final discard done once we know no readers are looking. */ ++static void cache_delete_rcu(void *arg) ++{ ++ object_put(arg); ++} ++ + /* Must be holding cache_lock */ + static void __cache_delete(struct object *obj) + { + BUG_ON(!obj); +- list_del(&obj->list); +- object_put(obj); ++ list_del_rcu(&obj->list); + cache_num--; ++ call_rcu(&obj->rcu, cache_delete_rcu, obj); + } + + /* Must be holding cache_lock */ + static void __cache_add(struct object *obj) + { +- list_add(&obj->list, &cache); ++ list_add_rcu(&obj->list, &cache); + if (++cache_num > MAX_CACHE_SIZE) { + struct object *i, *outcast = NULL; + list_for_each_entry(i, &cache, list) { +@@ -85,6 +94,7 @@ + obj->popularity = 0; + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ + spin_lock_init(&obj->lock); ++ INIT_RCU_HEAD(&obj->rcu); + + spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); +@@ -104,12 +114,11 @@ + struct object *cache_find(int id) + { + struct object *obj; +- unsigned long flags; + +- spin_lock_irqsave(&cache_lock, flags); ++ rcu_read_lock(); + obj = __cache_find(id); + if (obj) + object_get(obj); +- spin_unlock_irqrestore(&cache_lock, flags); ++ rcu_read_unlock(); + return obj; + } + + + +Note that the reader will alter the +popularity member in +__cache_find(), and now it doesn't hold a lock. +One solution would be to make it an atomic_t, but for +this usage, we don't really care about races: an approximate result is +good enough, so I didn't change it. + + + +The result is that cache_find() requires no +synchronization with any other functions, so is almost as fast on SMP +as it would be on UP. + + + +There is a furthur optimization possible here: remember our original +cache code, where there were no reference counts and the caller simply +held the lock whenever using the object? This is still possible: if +you hold the lock, noone can delete the object, so you don't need to +get and put the reference count. + + + +Now, because the 'read lock' in RCU is simply disabling preemption, a +caller which always has preemption disabled between calling +cache_find() and +object_put() does not need to actually get and +put the reference count: we could expose +__cache_find() by making it non-static, and +such callers could simply call that. + + +The benefit here is that the reference count is not written to: the +object is not altered in any way, which is much faster on SMP +machines due to caching. + + + + + Per-CPU Data - In this approach, an object has an owner, who sets the - reference count to one. Whenever you get a pointer to the - object, you increment the reference count (a `get' operation). - Whenever you relinquish a pointer, you decrement the reference - count (a `put' operation). When the owner wants to destroy - it, they mark it dead, and do a put. + Another technique for avoiding locking which is used fairly + widely is to duplicate information for each CPU. For example, + if you wanted to keep a count of a common condition, you could + use a spin lock and a single counter. Nice and simple. - Whoever drops the reference count to zero (usually implemented - with atomic_dec_and_test()) actually cleans - up and frees the object. + If that was too slow (it's usually not, but if you've got a + really big machine to test on and can show that it is), you + could instead use a counter for each CPU, then none of them need + an exclusive lock. See DEFINE_PER_CPU(), + get_cpu_var() and + put_cpu_var() + (include/linux/percpu.h). - This means that you are guaranteed that the object won't - vanish underneath you, even though you no longer have a lock - for the collection. + Of particular use for simple per-cpu counters is the + local_t type, and the + cpu_local_inc() and related functions, + which are more efficient than simple code on some architectures + (include/asm/local.h). - Here's some skeleton code: + Note that there is no simple, reliable way of getting an exact + value of such a counter, without introducing more locks. This + is not a problem for some uses. + - - void create_foo(struct foo *x) - { - atomic_set(&x->use, 1); - spin_lock_bh(&list_lock); - ... insert in list ... - spin_unlock_bh(&list_lock); - } - - struct foo *get_foo(int desc) - { - struct foo *ret; - - spin_lock_bh(&list_lock); - ... find in list ... - if (ret) atomic_inc(&ret->use); - spin_unlock_bh(&list_lock); - - return ret; - } + + Data Which Mostly Used By An IRQ Handler - void put_foo(struct foo *x) - { - if (atomic_dec_and_test(&x->use)) - kfree(foo); - } + + If data is always accessed from within the same IRQ handler, you + don't need a lock at all: the kernel already guarantees that the + irq handler will not run simultaneously on multiple CPUs. + + + Manfred Spraul points out that you can still do this, even if + the data is very occasionally accessed in user context or + softirqs/tasklets. The irq handler doesn't use a lock, and + all other accesses are done as so: + + + + spin_lock(&lock); + disable_irq(irq); + ... + enable_irq(irq); + spin_unlock(&lock); + + + The disable_irq() prevents the irq handler + from running (and waits for it to finish if it's currently + running on other CPUs). The spinlock prevents any other + accesses happening at the same time. Naturally, this is slower + than just a spin_lock_irq() call, so it + only makes sense if this type of access happens extremely + rarely. + + + - void destroy_foo(struct foo *x) - { - spin_lock_bh(&list_lock); - ... remove from list ... - spin_unlock_bh(&list_lock); + + What Functions Are Safe To Call From Interrupts? - put_foo(x); - } - + + Many functions in the kernel sleep (ie. call schedule()) + directly or indirectly: you can never call them while holding a + spinlock, or with preemption disabled. This also means you need + to be in user context: calling them from an interrupt is illegal. + - - Macros To Help You - - There are a set of debugging macros tucked inside - include/linux/netfilter_ipv4/lockhelp.h - and listhelp.h: these are very - useful for ensuring that locks are held in the right places to protect - infrastructure. - - - - - - Things Which Sleep + + Some Functions Which Sleep - You can never call the following routines while holding a - spinlock, as they may sleep. This also means you need to be in - user context. + The most common ones are listed below, but you usually have to + read the code to find out if other calls are safe. If everyone + else who calls it can sleep, you probably need to be able to + sleep, too. In particular, registration and deregistration + functions usually expect to be called from user context, and can + sleep. @@ -961,106 +1887,31 @@ - - printk() can be called in - any context, interestingly enough. - - - - - The Fucked Up Sparc + + Some Functions Which Don't Sleep - Alan Cox says the irq disable/enable is in the register - window on a sparc. Andi Kleen says when you do - restore_flags in a different function you mess up all the - register windows. - - - - So never pass the flags word set by - spin_lock_irqsave() and brethren to another - function (unless it's declared inline. Usually no-one - does this, but now you've been warned. Dave Miller can never do - anything in a straightforward manner (I can say that, because I have - pictures of him and a certain PowerPC maintainer in a compromising - position). - - - - - Racing Timers: A Kernel Pastime - - - Timers can produce their own special problems with races. - Consider a collection of objects (list, hash, etc) where each - object has a timer which is due to destroy it. + Some functions are safe to call from any context, or holding + almost any lock. - - If you want to destroy the entire collection (say on module - removal), you might do the following: - - - - /* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE - HUNGARIAN NOTATION */ - spin_lock_bh(&list_lock); - - while (list) { - struct foo *next = list->next; - del_timer(&list->timer); - kfree(list); - list = next; - } - - spin_unlock_bh(&list_lock); - - - - Sooner or later, this will crash on SMP, because a timer can - have just gone off before the spin_lock_bh(), - and it will only get the lock after we - spin_unlock_bh(), and then try to free - the element (which has already been freed!). - - - - This can be avoided by checking the result of - del_timer(): if it returns - 1, the timer has been deleted. - If 0, it means (in this - case) that it is currently running, so we can do: - - - - retry: - spin_lock_bh(&list_lock); - - while (list) { - struct foo *next = list->next; - if (!del_timer(&list->timer)) { - /* Give timer a chance to delete this */ - spin_unlock_bh(&list_lock); - goto retry; - } - kfree(list); - list = next; - } - - spin_unlock_bh(&list_lock); - - - - Another common problem is deleting timers which restart - themselves (by calling add_timer() at the end - of their timer function). Because this is a fairly common case - which is prone to races, you should use del_timer_sync() - (include/linux/timer.h) - to handle this case. It returns the number of times the timer - had to be deleted before we finally stopped it from adding itself back - in. - + + + + printk() + + + + + kfree() + + + + + add_timer() and del_timer() + + + @@ -1101,8 +1952,9 @@ Thanks to Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul - Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul and Tim - Waugh for proofreading, correcting, flaming, commenting. + Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim + Waugh, Pete Zaitcev, James Morris, Robert Love, Paul McKenney, + John Ashby for proofreading, correcting, flaming, commenting. @@ -1113,12 +1965,27 @@ Glossary + + preemption + + + Prior to 2.5, or when CONFIG_PREEMPT is + unset, processes in user context inside the kernel would not + preempt each other (ie. you had that CPU until you have it up, + except for interrupts). With the addition of + CONFIG_PREEMPT in 2.5.4, this changed: when + in user context, higher priority tasks can "cut in": spinlocks + were changed to disable preemption, even on UP. + + + + bh Bottom Half: for historical reasons, functions with - `_bh' in them often now refer to any software interrupt, e.g. + '_bh' in them often now refer to any software interrupt, e.g. spin_lock_bh() blocks any software interrupt on the current CPU. Bottom halves are deprecated, and will eventually be replaced by tasklets. Only one bottom half will be @@ -1132,8 +1999,7 @@ Hardware interrupt request. in_irq() returns - true in a hardware interrupt handler (it - also returns true when interrupts are blocked). + true in a hardware interrupt handler. @@ -1144,8 +2010,7 @@ Not user context: processing a hardware irq or software irq. Indicated by the in_interrupt() macro - returning true (although it also - returns true when interrupts or BHs are blocked). + returning true. @@ -1161,35 +2026,40 @@ - softirq + Software Interrupt / softirq - Strictly speaking, one of up to 32 enumerated software + Software interrupt handler. in_irq() returns + false; in_softirq() + returns true. Tasklets and softirqs + both fall into the category of 'software interrupts'. + + + Strictly speaking a softirq is one of up to 32 enumerated software interrupts which can run on multiple CPUs at once. - Sometimes used to refer to tasklets and bottom halves as + Sometimes used to refer to tasklets as well (ie. all software interrupts). - - Software Interrupt / Software IRQ + + tasklet - Software interrupt handler. in_irq() returns - false; in_softirq() - returns true. Tasklets, softirqs and - bottom halves all fall into the category of `software interrupts'. + A dynamically-registrable software interrupt, + which is guaranteed to only run on one CPU at a time. - - tasklet + + timer - A dynamically-registrable software interrupt, - which is guaranteed to only run on one CPU at a time. + A dynamically-registrable software interrupt, which is run at + (or close to) a given time. When running, it is just like a + tasklet (in fact, they are called from the TIMER_SOFTIRQ). @@ -1207,10 +2077,11 @@ User Context - The kernel executing on behalf of a particular - process or kernel thread (given by the current() - macro.) Not to be confused with userspace. Can be interrupted by - software or hardware interrupts. + The kernel executing on behalf of a particular process (ie. a + system call or trap) or kernel thread. You can tell which + process with the current macro.) Not to + be confused with userspace. Can be interrupted by software or + hardware interrupts. diff -Nru a/Documentation/MSI-HOWTO.txt b/Documentation/MSI-HOWTO.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/MSI-HOWTO.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,321 @@ + The MSI Driver Guide HOWTO + Tom L Nguyen tom.l.nguyen@intel.com + 10/03/2003 + +1. About this guide + +This guide describes the basics of Message Signaled Interrupts(MSI), the +advantages of using MSI over traditional interrupt mechanisms, and how +to enable your driver to use MSI or MSI-X. Also included is a Frequently +Asked Questions. + +2. Copyright 2003 Intel Corporation + +3. What is MSI/MSI-X? + +Message Signaled Interrupt (MSI), as described in the PCI Local Bus +Specification Revision 2.3 or latest, is an optional feature, and a +required feature for PCI Express devices. MSI enables a device function +to request service by sending an Inbound Memory Write on its PCI bus to +the FSB as a Message Signal Interrupt transaction. Because MSI is +generated in the form of a Memory Write, all transaction conditions, +such as a Retry, Master-Abort, Target-Abort or normal completion, are +supported. + +A PCI device that supports MSI must also support pin IRQ assertion +interrupt mechanism to provide backward compatibility for systems that +do not support MSI. In Systems, which support MSI, the bus driver is +responsible for initializing the message address and message data of +the device function's MSI/MSI-X capability structure during device +initial configuration. + +An MSI capable device function indicates MSI support by implementing +the MSI/MSI-X capability structure in its PCI capability list. The +device function may implement both the MSI capability structure and +the MSI-X capability structure; however, the bus driver should not +enable both, but instead enable only the MSI-X capability structure. + +The MSI capability structure contains Message Control register, +Message Address register and Message Data register. These registers +provide the bus driver control over MSI. The Message Control register +indicates the MSI capability supported by the device. The Message +Address register specifies the target address and the Message Data +register specifies the characteristics of the message. To request +service, the device function writes the content of the Message Data +register to the target address. The device and its software driver +are prohibited from writing to these registers. + +The MSI-X capability structure is an optional extension to MSI. It +uses an independent and separate capability structure. There are +some key advantages to implementing the MSI-X capability structure +over the MSI capability structure as described below. + + - Support a larger maximum number of vectors per function. + + - Provide the ability for system software to configure + each vector with an independent message address and message + data, specified by a table that resides in Memory Space. + + - MSI and MSI-X both support per-vector masking. Per-vector + masking is an optional extension of MSI but a required + feature for MSI-X. Per-vector masking provides the kernel + the ability to mask/unmask MSI when servicing its software + interrupt service routing handler. If per-vector masking is + not supported, then the device driver should provide the + hardware/software synchronization to ensure that the device + generates MSI when the driver wants it to do so. + +4. Why use MSI? + +As a benefit the simplification of board design, MSI allows board +designers to remove out of band interrupt routing. MSI is another +step towards a legacy-free environment. + +Due to increasing pressure on chipset and processor packages to +reduce pin count, the need for interrupt pins is expected to +diminish over time. Devices, due to pin constraints, may implement +messages to increase performance. + +PCI Express endpoints uses INTx emulation (in-band messages) instead +of IRQ pin assertion. Using INTx emulation requires interrupt +sharing among devices connected to the same node (PCI bridge) while +MSI is unique (non-shared) and does not require BIOS configuration +support. As a result, the PCI Express technology requires MSI +support for better interrupt performance. + +Using MSI enables the device functions to support two or more +vectors, which can be configure to target different CPU's to +increase scalability. + +5. Configuring a driver to use MSI/MSI-X + +By default, the kernel will not enable MSI/MSI-X on all devices that +support this capability once the patch is installed. A kernel +configuration option must be selected to enable MSI/MSI-X support. + +5.1 Including MSI support into the kernel + +To include MSI support into the kernel requires users to patch the +VECTOR-base patch first and then the MSI patch because the MSI +support needs VECTOR based scheme. Once these patches are installed, +setting CONFIG_PCI_USE_VECTOR enables the VECTOR based scheme and +the option for MSI-capable device drivers to selectively enable MSI +(using pci_enable_msi as desribed below). + +Since the target of the inbound message is the local APIC, providing +CONFIG_PCI_USE_VECTOR is dependent on whether CONFIG_X86_LOCAL_APIC +is enabled or not. + +int pci_enable_msi(struct pci_dev *) + +With this new API, any existing device driver, which like to have +MSI enabled on its device function, must call this explicitly. A +successful call will initialize the MSI/MSI-X capability structure +with ONE vector, regardless of whether the device function is +capable of supporting multiple messages. This vector replaces the +pre-assigned dev->irq with a new MSI vector. To avoid the conflict +of new assigned vector with existing pre-assigned vector requires +the device driver to call this API before calling request_irq(...). + +The below diagram shows the events, which switches the interrupt +mode on the MSI-capable device function between MSI mode and +PIN-IRQ assertion mode. + + ------------ pci_enable_msi ------------------------ + | | <=============== | | + | MSI MODE | | PIN-IRQ ASSERTION MODE | + | | ===============> | | + ------------ free_irq ------------------------ + +5.2 Configuring for MSI support + +Due to the non-contiguous fashion in vector assignment of the +existing Linux kernel, this patch does not support multiple +messages regardless of the device function is capable of supporting +more than one vector. The bus driver initializes only entry 0 of +this capability if pci_enable_msi(...) is called successfully by +the device driver. + +5.3 Configuring for MSI-X support + +Both the MSI capability structure and the MSI-X capability structure +share the same above semantics; however, due to the ability of the +system software to configure each vector of the MSI-X capability +structure with an independent message address and message data, the +non-contiguous fashion in vector assignment of the existing Linux +kernel has no impact on supporting multiple messages on an MSI-X +capable device functions. By default, as mentioned above, ONE vector +should be always allocated to the MSI-X capability structure at +entry 0. The bus driver does not initialize other entries of the +MSI-X table. + +Note that the PCI subsystem should have full control of a MSI-X +table that resides in Memory Space. The software device driver +should not access this table. + +To request for additional vectors, the device software driver should +call function msi_alloc_vectors(). It is recommended that the +software driver should call this function once during the +initialization phase of the device driver. + +The function msi_alloc_vectors(), once invoked, enables either +all or nothing, depending on the current availability of vector +resources. If no vector resources are available, the device function +still works with ONE vector. If the vector resources are available +for the number of vectors requested by the driver, this function +will reconfigure the MSI-X capability structure of the device with +additional messages, starting from entry 1. To emphasize this +reason, for example, the device may be capable for supporting the +maximum of 32 vectors while its software driver usually may request +4 vectors. + +For each vector, after this successful call, the device driver is +responsible to call other functions like request_irq(), enable_irq(), +etc. to enable this vector with its corresponding interrupt service +handler. It is the device driver's choice to have all vectors shared +the same interrupt service handler or each vector with a unique +interrupt service handler. + +In addition to the function msi_alloc_vectors(), another function +msi_free_vectors() is provided to allow the software driver to +release a number of vectors back to the vector resources. Once +invoked, the PCI subsystem disables (masks) each vector released. +These vectors are no longer valid for the hardware device and its +software driver to use. Like free_irq, it recommends that the +device driver should also call msi_free_vectors to release all +additional vectors previously requested. + +int msi_alloc_vectors(struct pci_dev *dev, int *vector, int nvec) + +This API enables the software driver to request the PCI subsystem +for additional messages. Depending on the number of vectors +available, the PCI subsystem enables either all or nothing. + +Argument dev points to the device (pci_dev) structure. +Argument vector is a pointer of integer type. The number of +elements is indicated in argument nvec. +Argument nvec is an integer indicating the number of messages +requested. +A return of zero indicates that the number of allocated vector is +successfully allocated. Otherwise, indicate resources not +available. + +int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec) + +This API enables the software driver to inform the PCI subsystem +that it is willing to release a number of vectors back to the +MSI resource pool. Once invoked, the PCI subsystem disables each +MSI-X entry associated with each vector stored in the argument 2. +These vectors are no longer valid for the hardware device and +its software driver to use. + +Argument dev points to the device (pci_dev) structure. +Argument vector is a pointer of integer type. The number of +elements is indicated in argument nvec. +Argument nvec is an integer indicating the number of messages +released. +A return of zero indicates that the number of allocated vectors +is successfully released. Otherwise, indicates a failure. + +5.4 Hardware requirements for MSI support +MSI support requires support from both system hardware and +individual hardware device functions. + +5.4.1 System hardware support +Since the target of MSI address is the local APIC CPU, enabling +MSI support in Linux kernel is dependent on whether existing +system hardware supports local APIC. Users should verify their +system whether it runs when CONFIG_X86_LOCAL_APIC=y. + +In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set; +however, in UP environment, users must manually set +CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting +CONFIG_PCI_USE_VECTOR enables the VECTOR based scheme and +the option for MSI-capable device drivers to selectively enable +MSI (using pci_enable_msi as desribed below). + +Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI +vector is allocated new during runtime and MSI support does not +depend on BIOS support. This key independency enables MSI support +on future IOxAPIC free platform. + +5.4.2 Device hardware support +The hardware device function supports MSI by indicating the +MSI/MSI-X capability structure on its PCI capability list. By +default, this capability structure will not be initialized by +the kernel to enable MSI during the system boot. In other words, +the device function is running on its default pin assertion mode. +Note that in many cases the hardware supporting MSI have bugs, +which may result in system hang. The software driver of specific +MSI-capable hardware is responsible for whether calling +pci_enable_msi or not. A return of zero indicates the kernel +successfully initializes the MSI/MSI-X capability structure of the +device funtion. The device function is now running on MSI mode. + +5.5 How to tell whether MSI is enabled on device function + +At the driver level, a return of zero from pci_enable_msi(...) +indicates to the device driver that its device function is +initialized successfully and ready to run in MSI mode. + +At the user level, users can use command 'cat /proc/interrupts' +to display the vector allocated for the device and its interrupt +mode, as shown below. + + CPU0 CPU1 + 0: 324639 0 IO-APIC-edge timer + 1: 1186 0 IO-APIC-edge i8042 + 2: 0 0 XT-PIC cascade + 12: 2797 0 IO-APIC-edge i8042 + 14: 6543 0 IO-APIC-edge ide0 + 15: 1 0 IO-APIC-edge ide1 +169: 0 0 IO-APIC-level uhci-hcd +185: 0 0 IO-APIC-level uhci-hcd +193: 138 10 PCI MSI aic79xx +201: 30 0 PCI MSI aic79xx +225: 30 0 IO-APIC-level aic7xxx +233: 30 0 IO-APIC-level aic7xxx +NMI: 0 0 +LOC: 324553 325068 +ERR: 0 +MIS: 0 + +6. FAQ + +Q1. Are there any limitations on using the MSI? + +A1. If the PCI device supports MSI and conforms to the +specification and the platform supports the APIC local bus, +then using MSI should work. + +Q2. Will it work on all the Pentium processors (P3, P4, Xeon, +AMD processors)? In P3 IPI's are transmitted on the APIC local +bus and in P4 and Xeon they are transmitted on the system +bus. Are there any implications with this? + +A2. MSI support enables a PCI device sending an inbound +memory write (0xfeexxxxx as target address) on its PCI bus +directly to the FSB. Since the message address has a +redirection hint bit cleared, it should work. + +Q3. The target address 0xfeexxxxx will be translated by the +Host Bridge into an interrupt message. Are there any +limitations on the chipsets such as Intel 8xx, Intel e7xxx, +or VIA? + +A3. If these chipsets support an inbound memory write with +target address set as 0xfeexxxxx, as conformed to PCI +specification 2.3 or latest, then it should work. + +Q4. From the driver point of view, if the MSI is lost because +of the errors occur during inbound memory write, then it may +wait for ever. Is there a mechanism for it to recover? + +A4. Since the target of the transaction is an inbound memory +write, all transaction termination conditions (Retry, +Master-Abort, Target-Abort, or normal completion) are +supported. A device sending an MSI must abide by all the PCI +rules and conditions regarding that inbound memory write. So, +if a retry is signaled it must retry, etc... We believe that +the recommendation for Abort is also a retry (refer to PCI +specification 2.3 or latest). diff -Nru a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers --- a/Documentation/SubmittingDrivers Thu Jan 8 23:00:24 2004 +++ b/Documentation/SubmittingDrivers Thu Jan 8 23:00:24 2004 @@ -34,14 +34,13 @@ maintainer then please contact Alan Cox Linux 2.4: - The same rules apply as 2.2 but this kernel tree is under active - development. The final contact point for Linux 2.4 submissions is - Marcelo Tosatti . + The same rules apply as 2.2. The final contact point for Linux 2.4 + submissions is Marcelo Tosatti . -Linux 2.5: +Linux 2.6: The same rules apply as 2.4 except that you should follow linux-kernel - to track changes in API's. The final contact point for Linux 2.5 - submissions is Linus Torvalds . + to track changes in API's. The final contact point for Linux 2.6 + submissions is Andrew Morton . What Criteria Determine Acceptance ---------------------------------- diff -Nru a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt --- a/Documentation/block/biodoc.txt Thu Jan 8 23:00:24 2004 +++ b/Documentation/block/biodoc.txt Thu Jan 8 23:00:24 2004 @@ -323,7 +323,7 @@ request->buffer, request->sector and request->nr_sectors or request->current_nr_sectors fields itself rather than using the block layer end_request or end_that_request_first completion interfaces. -(See 2.3 or Documentation/bio/request.txt for a brief explanation of +(See 2.3 or Documentation/block/request.txt for a brief explanation of the request structure fields) [TBD: end_that_request_last should be usable even in this case; @@ -517,7 +517,7 @@ Only some relevant fields (mainly those which changed or may be referred to in some of the discussion here) are listed below, not necessarily in the order in which they occur in the structure (see include/linux/blkdev.h) -Refer to Documentation/bio/request.txt for details about all the request +Refer to Documentation/block/request.txt for details about all the request structure fields and a quick reference about the layers which are supposed to use or modify those fields. diff -Nru a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/dvb/bt8xx.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,90 @@ +How to get the Nebula, PCTV and Twinhan DST cards working +========================================================= + +This class of cards has a bt878a as the PCI interface, and +require the bttv driver. + +Please pay close attention to the warning about the bttv module +options below for the DST card. + +1) General informations +======================= + +These drivers require the bttv driver to provide the means to access +the i2c bus and the gpio pins of the bt8xx chipset. + +Because of this, you need to enable +"Device drivers" => "Multimedia devices" + => "Video For Linux" => "BT848 Video For Linux" + +2) Loading Modules +================== + +In general you need to load the bttv driver, which will handle the gpio and +i2c communication for us. Next you need the common dvb-bt8xx device driver +and one frontend driver. + +The bttv driver will HANG YOUR SYSTEM IF YOU DO NOT SPECIFY THE CORRECT +CARD ID! + +(If you don't get your card running and you suspect that the card id you're +using is wrong, have a look at "bttv-cards.c" for a list of possible card +ids.) + +Pay attention to failures when you load the frontend drivers +(e.g. dmesg, /var/log/messages). + +3a) Nebula / Pinnacle PCTV +-------------------------- + + $ modprobe bttv i2c_hw=1 card=0x68 + $ modprobe dvb-bt8xx + +For Nebula cards use the "nxt6000" frontend driver: + $ modprobe nxt6000 + +For Pinnacle PCTV cards use the "cx24110" frontend driver: + $ modprobe cx24110 + +3b) TwinHan +----------- + + $ modprobe bttv i2c_hw=1 card=0x71 + $ modprobe dvb-bt8xx + $ modprobe dst + +The value 0x71 will override the PCI type detection for dvb-bt8xx, which +is necessary for TwinHan cards.# + +If you're having an older card (blue color circuit) and card=0x71 locks your +machine, try using 0x68, too. If that does not work, ask on the DVB mailing list. + +The DST module takes a couple of useful parameters, in case the +dst drivers fails to detect your type of card correctly. + +dst_type takes values 0 (satellite), 1 (terrestial TV), 2 (cable). + +dst_type_flags takes bit combined values: +1 = new tuner type packets. You can use this if your card is detected + and you have debug and you continually see the tuner packets not + working (make sure not a basic problem like dish alignment etc.) + +2 = TS 204. If your card tunes OK, but the picture is terrible, seemingly + breaking up in one half continually, and crc fails a lot, then + this is worth a try (or trying to turn off) + +4 = has symdiv. Some cards, mostly without new tuner packets, require + a symbol division algorithm. Doesn't apply to terrestial TV. + +You can also specify a value to have the autodetected values turned off +(e.g. 0). The autodected values are determined bythe cards 'response +string' which you can see in your logs e.g. + +dst_check_ci: recognize DST-MOT + +or + +dst_check_ci: unable to recognize DSTXCI or STXCI + +-- +Authors: Richard Walker, Jamie Honan, Michael Hunold diff -Nru a/Documentation/dvb/cards.txt b/Documentation/dvb/cards.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/dvb/cards.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,63 @@ +Hardware supported by the linuxtv.org DVB drivers +================================================= + + Generally, the DVB hardware manufacturers frequently change the + frontends (i.e. tuner / demodulator units) used, usually without + changing the product name, revision number or specs. Some cards + are also available in versions with different frontends for + DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed seperately. + + Note 1: There is no guarantee that every frontend driver works + out-of-the box with every card, because of different wiring. + + Note 2: The demodulator chips can be used with a variety of + tuner/PLL chips, and not all combinations are supported. Often + the demodulator and tuner/PLL chip are inside a metal box for + shielding, and the whole metal box has its own part number. + + +o Frontends drivers: + - dvb_dummy_fe: for testing... + DVB-S: + - alps_bsrv2 : Alps BSRV2 (ves1893 demodulator) + - cx24110 : Conexant HM1221/HM1811 (cx24110 or cx24106 demod, cx24108 PLL) + - grundig_29504-491 : Grundig 29504-491 (Philips TDA8083 demodulator), tsa5522 PLL + - mt312 : Zarlink mt312 or Mitel vp310 demodulator, sl1935 or tsa5059 PLL + - stv0299 : Alps BSRU6 (tsa5059 PLL), LG TDQB-S00x (tsa5059 PLL), + LG TDQF-S001F (sl1935 PLL), Philips SU1278 (tua6100 PLL), + Philips SU1278SH (tsa5059 PLL) + DVB-C: + - ves1820 : various (ves1820 demodulator, sp5659c or spXXXX PLL) + - at76c651 : Atmel AT76c651(B) with DAT7021 PLL + DVB-T: + - alps_tdlb7 : Alps TDLB7 (sp8870 demodulator, sp5659 PLL) + - alps_tdmb7 : Alps TDMB7 (cx22700 demodulator) + - grundig_29504-401 : Grundig 29504-401 (LSI L64781 demodulator), tsa5060 PLL + - tda1004x : Philips tda10045h (td1344 or tdm1316l PLL) + - nxt6000 : Alps TDME7 (MITEL SP5659 PLL), Alps TDED4 (TI ALP510 PLL), + Comtech DVBT-6k07 (SP5730 PLL) + (NxtWave Communications NXT6000 demodulator) + + +o Cards based on the Phillips saa7146 multimedia PCI bridge chip: + - TI AV7110 based cards (i.e. with hardware MPEG decoder): + - Siemens/Technotrend/Hauppauge PCI DVB card revision 1.1, 1.3, 1.5, 1.6, 2.1 + (aka Hauppauge Nexus) + - "budget" cards (i.e. without hardware MPEG decoder): + - Technotrend Budget / Hauppauge WinTV-Nova PCI Cards + - SATELCO Multimedia PCI + - KNC1 DVB-S + +o Cards based on the B2C2 Inc. FlexCopII: + - Technisat SkyStar2 PCI DVB + +o Cards based on the Conexant Bt8xx PCI bridge: + - Pinnacle PCTV Sat DVB + - Nebula Electronics DigiTV + +o Technotrend / Hauppauge DVB USB devices: + - Nova USB + - DEC 2000-T + +o Preliminary support for the analog module of the Siemens DVB-C PCI card + diff -Nru a/Documentation/dvb/contributors.txt b/Documentation/dvb/contributors.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/dvb/contributors.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,62 @@ +Thanks go to the following people for patches and contributions: + +Michael Hunold + for the initial saa7146 driver and it's recent overhaul + +Christian Theiss + for his work on the initial Linux DVB driver + +Marcus Metzler +Ralph Metzler + for their contining work on the DVB driver + +Michael Holzt + for his contributions to the dvb-net driver + +Diego Picciani + for CyberLogin for Linux which allows logging onto EON + (in case you are wondering where CyberLogin is, EON changed its login + procedure and CyberLogin is no longer used.) + +Martin Schaller + for patching the cable card decoder driver + +Klaus Schmidinger + for various fixes regarding tuning, OSD and CI stuff and his work on VDR + +Steve Brown + for his AFC kernel thread + +Christoph Martin + for his LIRC infrared handler + +Andreas Oberritter +Dennis Noermann +Felix Domke +Florian Schirmer +Ronny Strutz <3des@elitedvb.de> +Wolfram Joost +...and all the other dbox2 people + for many bugfixes in the generic DVB Core, frontend drivers and + their work on the dbox2 port of the DVB driver + +Oliver Endriss + for many bugfixes + +Andrew de Quincey + for the tda1004x frontend driver, and various bugfixes + +Peter Schildmann + for the driver for the Technisat SkyStar2 PCI DVB card + +Vadim Catana +Roberto Ragusa +Augusto Cardoso + for all the work for the FlexCopII chipset by B2C2,Inc. + +Davor Emard + for his work on the budget drivers, the demux code, + the module unloading problems, ... + +(If you think you should be in this list, but you are not, drop a + line to the DVB mailing list) diff -Nru a/Documentation/dvb/faq.txt b/Documentation/dvb/faq.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/dvb/faq.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,109 @@ +Some very frequently asked questions about linuxtv-dvb + +1. The signal seems to die a few seconds after tuning. + + It's not a bug, it's a feature. Because the frontends have + significant power requirements (and hence get very hot), they + are powered down if they are unused (i.e. if the frontend device + is closed). The dvb-core.o module paramter "dvb_shutdown_timeout" + allow you to change the timeout (default 5 seconds). Setting the + timeout to 0 disables the timeout feature. + +2. How can I watch TV? + + The driver distribution includes some simple utilities which + are mainly intended for testing and to demonstrate how the + DVB API works. + + Depending on whether you have a DVB-S, DVB-C or DVB-T card, use + apps/szap/szap, czap or tzap. You must supply a channel list + in ~/.[sct]zap/channels.conf. If you are lucky you can just copy + one of the supplied channel lists, or you can create a new one + by running apps/scan/scan. If you run scan on an unknown network + you might have to supply some start data in apps/scan/initial.h. + + If you have a card with a built-in hardware MPEG-decoder the + drivers create a video4linux device (/dev/v4l/video0) which + you can use to watch TV with any v4l application. xawtv is known + to work. Note that you cannot change channels with xawtv, you + have to zap using [sct]zap. If you want a nice application for + TV watching and record/playback, have a look at VDR. + + If your card does not have a hardware MPEG decoder you need + a software MPEG decoder. Mplayer or xine are known to work. + Newsflash: MythTV also has DVB support now. + Note: Only very recent versions of Mplayer and xine can decode. + MPEG2 transport streams (TS) directly. Then, run + '[sct]zap channelname -r' in one xterm, and keep it running, + and start 'mplayer - < /dev/dvb/adapter0/dvr0' or + 'xine stdin://mpeg2 < /dev/dvb/adapter0/dvr0' in a second xterm. + That's all far from perfect, but it seems no one has written + a nice DVB application which includes a builtin software MPEG + decoder yet. + + Newsflash: Newest xine directly supports DVB. Just copy your + channels.conf to ~/.xine and start 'xine dvb://', or select + the DVB button in the xine GUI. Channel switching works using the + numpad pgup/pgdown (NP9 / NP3) keys to scroll through the channel osd + menu and pressing numpad-enter to switch to the selected channel. + + Note: Older versions of xine and mplayer understand MPEG program + streams (PS) only, and can be used in conjunction with the + ts2ps tool from the Metzler Brother's dvb-mpegtools package. + +3. Which other DVB applications exist? + + http://www.cadsoft.de/people/kls/vdr/ + Klaus Schmidinger's Video Disk Recorder + + http://www.metzlerbros.org/dvb/ + Metzler Bros. DVB development; alternate drivers and + DVB utilities, include dvb-mpegtools and tuxzap. + + http://www.linuxstb.org/ + http://sourceforge.net/projects/dvbtools/ + Dave Chapman's dvbtools package, including + dvbstream and dvbtune + + http://www.linuxdvb.tv/ + Henning Holtschneider's site with many interesting + links and docs + + http://www.dbox2.info/ + LinuxDVB on the dBox2 + + http://www.tuxbox.org/ + http://cvs.tuxbox.org/ + the TuxBox CVS many interesting DVB applications and the dBox2 + DVB source + + http://sourceforge.net/projects/dvbsak/ + DVB Swiss Army Knife library and utilities + + http://www.nenie.org/misc/mpsys/ + MPSYS: a MPEG2 system library and tools + + http://mplayerhq.hu/ + mplayer + + http://xine.sourceforge.net/ + http://xinehq.de/ + xine + + http://www.mythtv.org/ + MythTV - analog TV PVR, but now with DVB support, too + (with software MPEG decode) + +4. Can't get a signal tuned correctly + + If you are using a Technotrend/Hauppauge DVB-C card *without* analog + module, you might have to use module parameter adac=-1 (dvb-ttpci.o). + +5. The dvb_net device doesn't give me any multicast packets + + Check your routes if they include the multicast address range. + Additionally make sure that "source validation by reversed path + lookup" is disabled: + $ "echo 0 > /proc/sys/net/ipv4/conf/dvb0/rp_filter" + +eof diff -Nru a/Documentation/dvb/firmware.txt b/Documentation/dvb/firmware.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/dvb/firmware.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,116 @@ +Some DVB cards and many newer frontends require proprietary, +binary-only firmware. + +The DVB drivers will be converted to use the request_firmware() +hotplug interface (see linux/Documentation/firmware_class/). +(CONFIG_FW_LOADER) + +The firmware can be loaded automatically via the hotplug manager +or manually with the steps described below. + +Currently the drivers still use various different methods +to load their firmwares, so here's just a short list of the +current state: + +- dvb-ttpci: driver uses firmware hotplug interface +- ttusb-budget: firmware is compiled in (dvb-ttusb-dspbootcode.h) +- sp887x: firmware is compiled in (sp887x_firm.h) +- alps_tdlb7: firmware is loaded from path specified by + "mcfile" module parameter; the binary must be + extracted from the Windows driver (Sc_main.mc). +- tda1004x: firmware is loaded from path specified in + DVB_TDA1004X_FIRMWARE_FILE kernel config + variable (default /etc/dvb/tda1004x.bin); the + firmware binary must be extracted from the windows + driver +- ttusb-dec: see "ttusb-dec.txt" for details + +1) Automatic firmware loading + +You need to install recent hotplug scripts if your distribution did not do it +for you already, especially the /etc/hotplug/firmware.agent. +http://linux-hotplug.sourceforge.net/ (Call /sbin/hotplug without arguments +to find out if the firmware agent is installed.) + +The firmware.agent script expects firmware binaries in +/usr/lib/hotplug/firmware/. To avoid naming and versioning +conflicts we propose the following naming scheme: + + /usr/lib/hotplug/firmware/dvb-{driver}-{ver}.fw for MPEG decoders etc. + /usr/lib/hotplug/firmware/dvb-fe-{driver}-{ver}.fw for frontends + + {driver} name is the basename of the driver kernel module (e.g. dvb-ttpci) + {ver} is a version number/name that should change only when the + driver/firmware internal API changes (so users are free to install the + latest firmware compatible with the driver). + +2) Manually loading the firmware into a driver + (currently only the dvb-ttpci / av7110 driver supports this) + +Step a) Mount sysfs-filesystem. + +Sysfs provides a means to export kernel data structures, their attributes, +and the linkages between them to userspace. + +For detailed informations have a look at Documentation/filesystems/sysfs.txt +All you need to know at the moment is that firmware loading only works through +sysfs. + +> mkdir /sys +> mount -t sysfs sysfs /sys + +Step b) Exploring the firmware loading facilities + +Firmware_class support is located in +/sys/class/firmware + +> dir /sys/class/firmware + +The "timeout" values specifies the amount of time that is waited before the +firmware upload process is cancelled. The default values is 10 seconds. If +you use a hotplug script for the firmware upload, this is sufficient. If +you want to upload the firmware by hand, however, this might be too fast. + +> echo "180" > /sys/class/firmware/timeout + +Step c) Getting a usable firmware file for the dvb-ttpci driver/av7110 card. + +You can download the firmware files from +http://www.linuxtv.org/download/dvb/ + +Please note that in case of the dvb-ttpci driver this is *not* the "Root" +file you probably know from the 2.4 DVB releases driver. + +> wget http://www.linuxtv.org/download/dvb/dvb-ttpci-01.fw +gets you the version 01 of the firmware fot the ttpci driver. + +Step d) Loading the dvb-ttpci driver and loading the firmware + +"modprobe" will take care that every needed module will be loaded +automatically (except the frontend driver) + +> modprobe dvb-ttpci + +The "modprobe" process will hang until +a) you upload the firmware or +b) the timeout occurs. + +Change to another terminal and have a look at + +> dir /sys/class/firmware/ + +total 0 +drwxr-xr-x 2 root root 0 Jul 29 11:00 0000:03:05.0 +-rw-r--r-- 1 root root 0 Jul 29 10:41 timeout + +"0000:03:05.0" is the id for my dvb-c card. It depends on the pci slot, +so it changes if you plug the card to different slots. + +You can upload the firmware like that: + +> export DEVDIR=/sys/class/firmware/0000\:03\:05.0 +> echo 1 > $DEVDIR/loading +> cat dvb-ttpci-01.fw > $DEVDIR/data +> echo 0 > $DEVDIR/loading + +That's it. The driver should be up and running now. diff -Nru a/Documentation/dvb/readme.txt b/Documentation/dvb/readme.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/dvb/readme.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,44 @@ +Linux Digital Video Broadcast (DVB) subsystem +============================================= + +The main development site and CVS repository for these +drivers is http://linuxtv.org/. + +The developer mailing list linux-dvb is also hosted there, +see http://linuxtv.org/mailinglists.xml. Please check +the archive http://linuxtv.org/mailinglists/linux-dvb/ +before asking newbie questions on the list. + +API documentation, utilities and test/example programs +are available as part of the old driver package for Linux 2.4 +(linuxtv-dvb-1.0.x.tar.gz), or from CVS (module DVB). +We plan to split this into separate packages, but it's not +been done yet. + +http://linuxtv.org/download/dvb/ + +What's inside this directory: + +"cards.txt" +contains a list of supported hardware. + +"contributors.txt" +is the who-is-who of DVB development + +"faq.txt" +contains frequently asked questions and their answers. + +"firmware.txt" +contains informations for required external firmware +files and where to get them. + +"ttusb-dec.txt" +contains detailed informations about the +TT DEC2000/DEC3000 USB DVB hardware. + +"bt8xx.txt" +contains detailed installation instructions for the +various bt8xx based "budget" DVB cards +(Nebula, Pinnacle PCTV, Twinhan DST) + +Good luck and have fun! diff -Nru a/Documentation/dvb/ttusb-dec.txt b/Documentation/dvb/ttusb-dec.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/dvb/ttusb-dec.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,49 @@ +TechnoTrend/Hauppauge DEC USB Driver +==================================== + +Driver Status +------------- + +Supported: + DEC2000-t + Linux Kernels 2.4 and 2.6 + Video Streaming + Audio Streaming + Section Filters + Channel Zapping + Hotplug firmware loader under 2.6 kernels + +In Progress: + DEC3000-s + +To Do: + Tuner status information + DVB network interface + Streaming video PC->DEC + +Getting the Firmware +-------------------- +Currently, the driver only works with v2.15a of the firmware. The firmwares +can be obtained in this way: + +wget http://hauppauge.lightpath.net/de/dec215a.exe +unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_T.bin +unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_S.bin + + +Compilation Notes for 2.4 kernels +--------------------------------- +For 2.4 kernels the firmware for the DECs is compiled into the driver itself. +The firmwares are expected to be in /etc/dvb at compilation time. + +mv STB_PC_T.bin /etc/dvb/dec2000t.bin +mv STB_PC_S.bin /etc/dvb/dec3000s.bin + + +Hotplug Firmware Loading for 2.6 kernels +---------------------------------------- +For 2.6 kernels the firmware is loaded at the point that the driver module is +loaded. See linux/Documentation/dvb/firmware.txt for more information. + +mv STB_PC_T.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-2000t-2.15a.fw +mv STB_PC_S.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-3000s-2.15a.fw diff -Nru a/Documentation/fb/aty128fb.txt b/Documentation/fb/aty128fb.txt --- a/Documentation/fb/aty128fb.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/fb/aty128fb.txt Thu Jan 8 23:00:23 2004 @@ -32,7 +32,7 @@ You should compile in both vgacon (to boot if you remove your Rage128 from box) and aty128fb (for graphics mode). You should not compile-in vesafb unless you have primary display on non-Rage128 VBE2.0 device (see -Documentation/vesafb.txt for details). +Documentation/fb/vesafb.txt for details). X11 diff -Nru a/Documentation/fb/matroxfb.txt b/Documentation/fb/matroxfb.txt --- a/Documentation/fb/matroxfb.txt Thu Jan 8 23:00:24 2004 +++ b/Documentation/fb/matroxfb.txt Thu Jan 8 23:00:24 2004 @@ -31,7 +31,7 @@ You should compile in both vgacon (to boot if you remove you Matrox from box) and matroxfb (for graphics mode). You should not compile-in vesafb unless you have primary display on non-Matrox VBE2.0 device (see -Documentation/vesafb.txt for details). +Documentation/fb/vesafb.txt for details). Currently supported video modes are (through vesa:... interface, PowerMac has [as addon] compatibility code): diff -Nru a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking --- a/Documentation/filesystems/Locking Thu Jan 8 23:00:24 2004 +++ b/Documentation/filesystems/Locking Thu Jan 8 23:00:24 2004 @@ -420,7 +420,7 @@ prototypes: void (*open)(struct vm_area_struct*); void (*close)(struct vm_area_struct*); - struct page *(*nopage)(struct vm_area_struct*, unsigned long, int); + struct page *(*nopage)(struct vm_area_struct*, unsigned long, int *); locking rules: BKL mmap_sem diff -Nru a/Documentation/filesystems/xfs.txt b/Documentation/filesystems/xfs.txt --- a/Documentation/filesystems/xfs.txt Thu Jan 8 23:00:24 2004 +++ b/Documentation/filesystems/xfs.txt Thu Jan 8 23:00:24 2004 @@ -29,10 +29,11 @@ The preferred buffered I/O size can also be altered on an individual file basis using the ioctl(2) system call. - ikeep + ikeep/noikeep When inode clusters are emptied of inodes, keep them around - on the disk, this is the old XFS behavior. Default is now to - return the inode cluster to the free space pool. + on the disk (ikeep) - this is the traditional XFS behaviour + and is still the default for now. Using the noikeep option, + inode clusters are returned to the free space pool. logbufs=value Set the number of in-memory log buffers. Valid numbers range @@ -75,6 +76,10 @@ Filesystems mounted "norecovery" must be mounted read-only or the mount will fail. + nouuid + Don't check for double mounted file systems using the file system uuid. + This is useful to mount LVM snapshot volumes. + osyncisosync Make O_SYNC writes implement true O_SYNC. WITHOUT this option, Linux XFS behaves as if an "osyncisdsync" option is used, @@ -108,10 +113,6 @@ The "swidth" option is required if the "sunit" option has been specified, and must be a multiple of the "sunit" value. - nouuid - Don't check for double mounted file systems using the file system uuid. - This is useful to mount LVM snapshot volumes. - sysctls ======= @@ -139,14 +140,14 @@ Causes certain error conditions to call BUG(). Value is a bitmask; AND together the tags which represent errors which should cause panics: - XFS_NO_PTAG 0LL - XFS_PTAG_IFLUSH 0x0000000000000001LL - XFS_PTAG_LOGRES 0x0000000000000002LL - XFS_PTAG_AILDELETE 0x0000000000000004LL - XFS_PTAG_ERROR_REPORT 0x0000000000000008LL - XFS_PTAG_SHUTDOWN_CORRUPT 0x0000000000000010LL - XFS_PTAG_SHUTDOWN_IOERROR 0x0000000000000020LL - XFS_PTAG_SHUTDOWN_LOGERROR 0x0000000000000040LL + XFS_NO_PTAG 0 + XFS_PTAG_IFLUSH 0x00000001 + XFS_PTAG_LOGRES 0x00000002 + XFS_PTAG_AILDELETE 0x00000004 + XFS_PTAG_ERROR_REPORT 0x00000008 + XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 + XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 + XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 This option is intended for debugging only. @@ -164,6 +165,21 @@ fs.xfs.restrict_chown (Min: 0 Default: 1 Max: 1) Controls whether unprivileged users can use chown to "give away" a file to another user. + + fs.xfs.inherit_sync (Min: 0 Default: 1 Max 1) + Setting this to "1" will cause the "sync" flag set + by the chattr(1) command on a directory to be + inherited by files in that directory. + + fs.xfs.inherit_nodump (Min: 0 Default: 1 Max 1) + Setting this to "1" will cause the "nodump" flag set + by the chattr(1) command on a directory to be + inherited by files in that directory. + + fs.xfs.inherit_noatime (Min: 0 Default: 1 Max 1) + Setting this to "1" will cause the "noatime" flag set + by the chattr(1) command on a directory to be + inherited by files in that directory. vm.pagebuf.stats_clear (Min: 0 Default: 0 Max: 1) Setting this to "1" clears accumulated pagebuf statistics diff -Nru a/Documentation/i2c/i2c-velleman b/Documentation/i2c/i2c-velleman --- a/Documentation/i2c/i2c-velleman Thu Jan 8 23:00:24 2004 +++ b/Documentation/i2c/i2c-velleman Thu Jan 8 23:00:24 2004 @@ -1,6 +1,6 @@ i2c-velleman driver ------------------- -This is a driver for i2c-hw access for Velleman K9000 and other adapters. +This is a driver for i2c-hw access for Velleman K8000 and other adapters. Useful links ------------ @@ -10,18 +10,14 @@ Velleman K8000 Howto: http://howto.htlw16.ac.at/k8000-howto.html - K8000 and K8005 libraries ------------------------- -The project has lead to new libs for the Velleman K8000 and K8005.. +The project has lead to new libs for the Velleman K8000 and K8005: LIBK8000 v1.99.1 and LIBK8005 v0.21 -With these libs you can control the K8000 and K8005 with the original -simple commands which are in the original Velleman software. -Like SetIOchannel, ReadADchannel, SendStepCCWFull and many more. -Via i2c kernel device /dev/velleman +With these libs, you can control the K8000 interface card and the K8005 +stepper motor card with the simple commands which are in the original +Velleman software, like SetIOchannel, ReadADchannel, SendStepCCWFull and +many more, using /dev/velleman. The libs can be found on http://groups.yahoo.com/group/k8000/files/linux/ - -The Velleman K8000 interface card on http://www.velleman.be/kits/k8000.htm -The Velleman K8005 steppermotorcard on http://www.velleman.be/kits/k8005.htm diff -Nru a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/i2c/porting-clients Thu Jan 8 23:00:24 2004 @@ -0,0 +1,121 @@ +Revision 3, 2003-10-04 +Jean Delvare +Greg KH + +This is a guide on how to convert I2C chip drivers from Linux 2.4 to +Linux 2.6. I have been using existing drivers (lm75, lm78) as examples. +Then I converted a driver myself (lm83) and updated this document. + +There are two sets of points below. The first set concerns technical +changes. The second set concerns coding policy. Both are mandatory. + +Although reading this guide will help you porting drivers, I suggest +you keep an eye on an already ported driver while porting your own +driver. This will help you a lot understanding what this guide +exactly means. Choose the chip driver that is the more similar to +yours for best results. + +Technical changes: + +* [Includes] Get rid of "version.h". Replace with + . Includes typically look like that: + #include + #include + #include + #include + #include + #include /* if you need VRM support */ + #include /* if you have I/O operations */ + Some extra headers may be required for a given driver. + +* [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, SENSORS_ISA_END + becomes I2C_CLIENT_ISA_END. + +* [Client data] Get rid of sysctl_id. Try using standard names for + register values (for example, temp_os becomes temp_max). You're + still relatively free here, but you *have* to follow the standard + names for sysfs files (see the Sysctl section below). + +* [Function prototypes] The detect functions loses its flags + parameter. Sysctl (e.g. lm75_temp) and miscellaneous (e.g. + swap_bytes) functions are off the list of prototypes. This + usually leaves five prototypes: + static int lm75_attach_adapter(struct i2c_adapter *adapter); + static int lm75_detect(struct i2c_adapter *adapter, int address, + int kind); + static void lm75_init_client(struct i2c_client *client); + static int lm75_detach_client(struct i2c_client *client); + static void lm75_update_client(struct i2c_client *client); + +* [Sysctl] All sysctl stuff is of course gone (defines, ctl_table + and functions). Instead, right after the static id definition + line, you have to define show and set functions for each sysfs + file. Only define set for writable values. Take a look at an + existing 2.6 driver for details (lm78 for example). Don't forget + to define the attributes for each file (this is that step that + links callback functions). Use the file names specified in + Documentation/i2c/sysfs-interface for the individual files. Also + convert the units these files read and write to the specified ones. + If you need to add a new type of file, please discuss it on the + sensors mailing list by providing a + patch to the Documentation/i2c/sysfs-interface file. + +* [Attach] For I2C drivers, the attach function should make sure + that the adapter's class has I2C_ADAP_CLASS_SMBUS, using the + following construct: + if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + return 0; + ISA-only drivers of course don't need this. + +* [Detect] As mentioned earlier, the flags parameter is gone. + The type_name and client_name strings are replaced by a single + name string, which will be filled with a lowercase, short string + (typically the driver name, e.g. "lm75"). The errorN labels are + reduced to the number needed. If that number is 2 (i2c-only + drivers), it is advised that the labels are named exit and + exit_free. For i2c+isa drivers, labels should be named ERROR0, + ERROR1 and ERROR2. Don't forget to properly set err before + jumping to error labels. By the way, labels should be + left-aligned. + Use memset to fill the client and data area with 0x00. + Use i2c_set_clientdata to set the client data (as opposed to + a direct access to client->data). + Use strlcpy instead of strcpy to copy the client name. + Replace the sysctl directory registration by calls to + device_create_file. Move the driver initialization before any + sysfs file creation. + +* [Detach] Get rid of data, remove the call to + i2c_deregister_entry. + +* [Update] Don't access client->data directly, use + i2c_get_clientdata(client) instead. + +* [Interface] Init function should not print anything. Make sure + there is a MODULE_LICENSE() line. + +Coding policy: + +* [Copyright] Use (C), not (c), for copyright. + +* [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you + can. Calls to printk/pr_debug for debugging purposes are replaced + by calls to dev_dbg. Here is an example on how to call it (taken + from lm75_detect): + dev_dbg(&adapter->dev, + "lm75_detect called for an ISA bus adapter?!?\n"); + Replace other printk calls with the dev_info, dev_err or dev_warn + function, as appropriate. + +* [Constants] Constants defines (registers, conversions, initial + values) should be aligned. This greatly improves readability. + Same goes for variables declarations. Alignments are achieved by the + means of tabs, not spaces. Remember that tabs are set to 8 in the + Linux kernel code. + +* [Structure definition] The name field should be standardized. All + lowercase and as simple as the driver name itself (e.g. "lm75"). + +* [Layout] Avoid extra empty lines between comments and what they + comment. Respect the coding style (see Documentation/CodingStyle), + in particular when it comes to placing curly braces. diff -Nru a/Documentation/i2c/summary b/Documentation/i2c/summary --- a/Documentation/i2c/summary Thu Jan 8 23:00:24 2004 +++ b/Documentation/i2c/summary Thu Jan 8 23:00:24 2004 @@ -71,5 +71,5 @@ i2c-adap-ibm_ocp: IBM 4xx processor I2C device (uses i2c-algo-ibm_ocp) (NOT BUILT BY DEFAULT) i2c-pport: Primitive parallel port adapter (uses i2c-algo-bit) i2c-rpx: RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT) -i2c-velleman: Velleman K9000 parallel port adapter (uses i2c-algo-bit) +i2c-velleman: Velleman K8000 parallel port adapter (uses i2c-algo-bit) diff -Nru a/Documentation/i2c/sysfs-interface b/Documentation/i2c/sysfs-interface --- a/Documentation/i2c/sysfs-interface Thu Jan 8 23:00:23 2004 +++ b/Documentation/i2c/sysfs-interface Thu Jan 8 23:00:23 2004 @@ -68,9 +68,7 @@ Fixed point XXXXX, divide by 1000 to get Amps. Read/Write. -curr_min[1-n] Current min or hysteresis value. - Preferably a hysteresis value, reported as a absolute - current, NOT a delta from the max value. +curr_min[1-n] Current min value. Fixed point XXXXX, divide by 1000 to get Amps. Read/Write. @@ -144,25 +142,38 @@ Integers 1,2,3, or thermistor Beta value (3435) Read/Write. -temp_max[1-3] Temperature max value. +temp_max[1-4] Temperature max value. Fixed point value in form XXXXX and should be divided by 1000 to get degrees Celsius. Read/Write value. -temp_min[1-3] Temperature min or hysteresis value. +temp_min[1-3] Temperature min value. Fixed point value in form XXXXX and should be divided by - 1000 to get degrees Celsius. This is preferably a - hysteresis value, reported as a absolute temperature, - NOT a delta from the max value. + 1000 to get degrees Celsius. Read/Write value. -temp_input[1-3] Temperature input value. +temp_hyst[1-3] Temperature hysteresis value. + Fixed point value in form XXXXX and should be divided by + 1000 to get degrees Celsius. Must be reported as an + absolute temperature, NOT a delta from the max value. + Read/Write value. + +temp_input[1-4] Temperature input value. + Fixed point value in form XXXXX and should be divided by + 1000 to get degrees Celsius. Read only value. +temp_crit Temperature critical value, typically greater than all + temp_max values. + Fixed point value in form XXXXX and should be divided by + 1000 to get degrees Celsius. + Common to all temperature channels. + Read/Write value. + If there are multiple temperature sensors, temp_*1 is generally the sensor inside the chip itself, generally - reported as "motherboard temperature". temp_*2 and - temp_*3 are generally sensors external to the chip + reported as "motherboard temperature". temp_*2 to + temp_*4 are generally sensors external to the chip itself, for example the thermal diode inside the CPU or a thermistor nearby. diff -Nru a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients --- a/Documentation/i2c/writing-clients Thu Jan 8 23:00:23 2004 +++ b/Documentation/i2c/writing-clients Thu Jan 8 23:00:23 2004 @@ -24,16 +24,14 @@ routines, a client structure specific information like the actual I2C address. - struct i2c_driver foo_driver - { - /* name */ "Foo version 2.3 and later driver", - /* id */ I2C_DRIVERID_FOO, - /* flags */ I2C_DF_NOTIFY, - /* attach_adapter */ &foo_attach_adapter, - /* detach_client */ &foo_detach_client, - /* command */ &foo_command, /* May be NULL */ - /* inc_use */ &foo_inc_use, /* May be NULL */ - /* dec_use */ &foo_dec_use /* May be NULL */ + static struct i2c_driver foo_driver = { + .owner = THIS_MODULE, + .name = "Foo version 2.3 driver", + .id = I2C_DRIVERID_FOO, /* usually from i2c-id.h */ + .flags = I2C_DF_NOTIFY, + .attach_adapter = &foo_attach_adapter, + .detach_client = &foo_detach_client, + .command = &foo_command /* may be NULL */ } The name can be chosen freely, and may be upto 40 characters long. Please @@ -50,43 +48,8 @@ All other fields are for call-back functions which will be explained below. - -Module usage count -================== - -If your driver can also be compiled as a module, there are moments at -which the module can not be removed from memory. For example, when you -are doing a lengthy transaction, or when you create a /proc directory, -and some process has entered that directory (this last case is the -main reason why these call-backs were introduced). - -To increase or decrease the module usage count, you can use the -MOD_{INC,DEC}_USE_COUNT macros. They must be called from the module -which needs to get its usage count changed; that is why each driver -module has to implement its own callback. - - void foo_inc_use (struct i2c_client *client) - { - #ifdef MODULE - MOD_INC_USE_COUNT; - #endif - } - - void foo_dec_use (struct i2c_client *client) - { - #ifdef MODULE - MOD_DEC_USE_COUNT; - #endif - } - -Do not call these call-back functions directly; instead, use one of the -following functions defined in i2c.h: - void i2c_inc_use_client(struct i2c_client *); - void i2c_dec_use_client(struct i2c_client *); - -You should *not* increase the module count just because a device is -detected and a client created. This would make it impossible to remove -an adapter driver! +There use to be two additional fields in this structure, inc_use et dec_use, +for module usage count, but these fields were obsoleted and removed. Extra client data diff -Nru a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt --- a/Documentation/i386/zero-page.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/i386/zero-page.txt Thu Jan 8 23:00:23 2004 @@ -22,6 +22,7 @@ 0x90000 + contents of CL_OFFSET (only taken, when CL_MAGIC = 0xA33F) 0x40 20 bytes struct apm_bios_info, APM_BIOS_INFO + 0x60 16 bytes Intel SpeedStep (IST) BIOS support information 0x80 16 bytes hd0-disk-parameter from intvector 0x41 0x90 16 bytes hd1-disk-parameter from intvector 0x46 diff -Nru a/Documentation/input/input.txt b/Documentation/input/input.txt --- a/Documentation/input/input.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/input/input.txt Thu Jan 8 23:00:23 2004 @@ -255,7 +255,7 @@ is also emulated, characters should appear if you move it. You can test the joystick emulation with the 'jstest' utility, -available in the joystick package (see Documentation/joystick.txt). +available in the joystick package (see Documentation/input/joystick.txt). You can test the event devices with the 'evtest' utility available in the LinuxConsole project CVS archive (see the URL below). diff -Nru a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt --- a/Documentation/kbuild/kconfig-language.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/kbuild/kconfig-language.txt Thu Jan 8 23:00:23 2004 @@ -141,8 +141,8 @@ otherwise 'y'. (4) Returns the value of the expression. Used to override precedence. (5) Returns the result of (2-/expr/). -(6) Returns the result of max(/expr/, /expr/). -(7) Returns the result of min(/expr/, /expr/). +(6) Returns the result of min(/expr/, /expr/). +(7) Returns the result of max(/expr/, /expr/). An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 respectively for calculations). A menu entry becomes visible when it's diff -Nru a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt --- a/Documentation/kbuild/modules.txt Thu Jan 8 23:00:24 2004 +++ b/Documentation/kbuild/modules.txt Thu Jan 8 23:00:24 2004 @@ -1,4 +1,4 @@ -For now this is a raw copy from the old Documentation/modules.txt, +For now this is a raw copy from the old Documentation/kbuild/modules.txt, which was removed in 2.6.0-test5. The information herein is correct but not complete. diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt Thu Jan 8 23:00:24 2004 +++ b/Documentation/kernel-parameters.txt Thu Jan 8 23:00:24 2004 @@ -24,6 +24,7 @@ HW Appropriate hardware is enabled. IA-32 IA-32 aka i386 architecture is enabled. IA-64 IA-64 architecture is enabled. + IOSCHED More than one I/O scheduler is enabled. IP_PNP IP DCHP, BOOTP, or RARP is enabled. ISAPNP ISA PnP code is enabled. ISDN Appropriate ISDN support is enabled. @@ -303,6 +304,10 @@ See comment before function elanfreq_setup() in arch/i386/kernel/cpu/cpufreq/elanfreq.c. + elevator= [IOSCHED] + Format: {"as"|"cfq"|"deadline"|"noop"} + See Documentation/as-iosched.txt for details + es1370= [HW,OSS] Format: [,] See also header of sound/oss/es1370.c. @@ -790,7 +795,8 @@ before loading. See Documentation/ramdisk.txt. - psmouse_noext [HW,MOUSE] Disable probing for PS2 mouse protocol extensions + psmouse_proto= [HW,MOUSE] Highest PS2 mouse protocol extension to + probe for (bare|imps|exps). psmouse_resetafter= [HW,MOUSE] Try to reset Synaptics Touchpad after so many @@ -1144,7 +1150,7 @@ See header of drivers/scsi/wd7000.c. wdt= [WDT] Watchdog - See Documentation/watchdog.txt. + See Documentation/watchdog/watchdog.txt. xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks. xd_geo= See header of drivers/block/xd.c. diff -Nru a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt --- a/Documentation/networking/ip-sysctl.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/networking/ip-sysctl.txt Thu Jan 8 23:00:23 2004 @@ -678,4 +678,23 @@ Pekka Savola YOSHIFUJI Hideaki / USAGI Project + +/proc/sys/net/bridge/* Variables: + +bridge-nf-call-arptables - BOOLEAN + 1 : pass bridged ARP traffic to arptables' FORWARD chain. + 0 : disable this. + Default: 1 + +bridge-nf-call-iptables - BOOLEAN + 1 : pass bridged IPv4 traffic to iptables' chains. + 0 : disable this. + Default: 1 + +bridge-nf-filter-vlan-tagged - BOOLEAN + 1 : pass bridged vlan-tagged ARP/IP traffic to arptables/iptables. + 0 : disable this. + Default: 1 + + $Id: ip-sysctl.txt,v 1.20 2001/12/13 09:00:18 davem Exp $ diff -Nru a/Documentation/scsi/BusLogic.txt b/Documentation/scsi/BusLogic.txt --- a/Documentation/scsi/BusLogic.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/scsi/BusLogic.txt Thu Jan 8 23:00:23 2004 @@ -577,7 +577,7 @@ INSMOD Loadable Kernel Module Installation Facility: insmod BusLogic.o \ - 'BusLogic_Options="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"' + 'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"' NOTE: Module Utilities 2.1.71 or later is required for correct parsing of driver options containing commas. diff -Nru a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt --- a/Documentation/scsi/aic79xx.txt Thu Jan 8 23:00:24 2004 +++ b/Documentation/scsi/aic79xx.txt Thu Jan 8 23:00:24 2004 @@ -1,5 +1,5 @@ ==================================================================== -= Adaptec Ultra320 Family Manager Set v1.3.0 = += Adaptec Ultra320 Family Manager Set v1.3.11 = = = = README for = = The Linux Operating System = @@ -19,57 +19,169 @@ The following Adaptec SCSI Host Adapters are supported by this driver set. - Ultra320 Adapters Description + Ultra320 ASIC Description ---------------------------------------------------------------- - Adaptec SCSI Card 39320 Dual Channel 64-bit PCI-X 133MHz to - Ultra320 SCSI Card (one external - 68-pin, two internal 68-pin) - Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to - Ultra320 SCSI Card (two external VHDC - and one internal 68-pin) - Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to - Ultra320 SCSI Card (two external VHDC - and one internal 68-pin) based on the - AIC-7902B ASIC - Adaptec SCSI Card 29320 Single Channel 64-bit PCI-X 133MHz to - Ultra320 SCSI Card (one external - 68-pin, two internal 68-pin, one - internal 50-pin) - Adaptec SCSI Card 29320LP Single Channel 64-bit Low Profile - PCI-X 133MHz to Ultra320 SCSI Card - (One external VHDC, one internal - 68-pin) - AIC-7901A Single Channel 64-bit PCI-X 133MHz to - Ultra320 SCSI ASIC - AIC-7902A4 Dual Channel 64-bit PCI-X 133MHz to - Ultra320 SCSI ASIC - AIC-7902B Dual Channel 64-bit PCI-X 133MHz to - Ultra320 SCSI ASIC - + AIC-7901A Single Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI ASIC + AIC-7901B Single Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI ASIC with Retained Training + AIC-7902A4 Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI ASIC + AIC-7902B Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI ASIC with Retained Training + + Ultra320 Adapters Description ASIC + -------------------------------------------------------------------------- + Adaptec SCSI Card 39320 Dual Channel 64-bit PCI-X 133MHz to 7902A4/7902B + Ultra320 SCSI Card (one external + 68-pin, two internal 68-pin) + Adaptec SCSI Card 39320A Dual Channel 64-bit PCI-X 133MHz to 7902B + Ultra320 SCSI Card (one external + 68-pin, two internal 68-pin) + Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to 7902A4 + Ultra320 SCSI Card (two external VHDC + and one internal 68-pin) + Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to 7902A4 + Ultra320 SCSI Card (two external VHDC + and one internal 68-pin) based on the + AIC-7902B ASIC + Adaptec SCSI Card 29320 Single Channel 64-bit PCI-X 133MHz to 7901A + Ultra320 SCSI Card (one external + 68-pin, two internal 68-pin, one + internal 50-pin) + Adaptec SCSI Card 29320A Single Channel 64-bit PCI-X 133MHz to 7901B + Ultra320 SCSI Card (one external + 68-pin, two internal 68-pin, one + internal 50-pin) + Adaptec SCSI Card 29320LP Single Channel 64-bit Low Profile 7901A + PCI-X 133MHz to Ultra320 SCSI Card + (One external VHDC, one internal + 68-pin) + Adaptec SCSI Card 29320ALP Single Channel 64-bit Low Profile 7901B + PCI-X 133MHz to Ultra320 SCSI Card + (One external VHDC, one internal + 68-pin) 2. Version History - (V1.3.0, January 2003) Full regression testing for all U320 products - completed. - - (V1.3.0 ALPHA, November 2002) Initial Alpha release. - Added abort and target/lun reset error recovery handler and - interrupt coalessing. - - (V1.2.0, November 2002) Added support for Domain Validation and - Hewlett-Packard version of the 39320D and AIC-7902 adapters. - Support for previous adapters has not been fully tested and should - only be used at the customer's own risk. - - (V1.1.1, September 2002) Added support for the Linux 2.5.X kernel series - - (V1.1.0, August 2002) Added support for four additional SCSI - products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901. - - (V1.1, August 2002) Added support for four additional SCSI - products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901. + 1.3.11 (July 11, 2003) + - Fix several deadlock issues. + - Add 29320ALP and 39320B Id's. + + 1.3.10 (June 3rd, 2003) + - Align the SCB_TAG field on a 16byte boundary. This avoids + SCB corruption on some PCI-33 busses. + - Correct non-zero luns on Rev B. hardware. + - Update for change in 2.5.X SCSI proc FS interface. + - When negotiation async via an 8bit WDTR message, send + an SDTR with an offset of 0 to be sure the target + knows we are async. This works around a firmware defect + in the Quantum Atlas 10K. + - Implement controller susupend and resume. + - Clear PCI error state during driver attach so that we + don't disable memory mapped I/O due to a stray write + by some other driver probe that occurred before we + claimed the controller. + + 1.3.9 (May 22nd, 2003) + - Fix compiler errors. + - Remove S/G splitting for segments that cross a 4GB boundary. + This is guaranteed not to happen in Linux. + - Add support for scsi_report_device_reset() found in + 2.5.X kernels. + - Add 7901B support. + - Simplify handling of the packtized lun Rev A workaround. + - Correct and simplify handling of the ignore wide residue + message. The previous code would fail to report a residual + if the transaction data length was even and we received + an IWR message. + + 1.3.8 (April 29th, 2003) + - Fix types accessed via the command line interface code. + - Perform a few firmware optimizations. + - Fix "Unexpected PKT busfree" errors. + - Use a sequencer interrupt to notify the host of + commands with bad status. We defer the notification + until there are no outstanding selections to ensure + that the host is interrupted for as short a time as + possible. + - Remove pre-2.2.X support. + - Add support for new 2.5.X interrupt API. + - Correct big-endian architecture support. + + 1.3.7 (April 16th, 2003) + - Use del_timer_sync() to ensure that no timeouts + are pending during controller shutdown. + - For pre-2.5.X kernels, carefully adjust our segment + list size to avoid SCSI malloc pool fragmentation. + - Cleanup channel display in our /proc output. + - Workaround duplicate device entries in the mid-layer + devlice list during add-single-device. + + 1.3.6 (March 28th, 2003) + - Correct a double free in the Domain Validation code. + - Correct a reference to free'ed memory during controller + shutdown. + - Reset the bus on an SE->LVD change. This is required + to reset our transcievers. + + 1.3.5 (March 24th, 2003) + - Fix a few register window mode bugs. + - Include read streaming in the PPR flags we display in + diagnostics as well as /proc. + - Add PCI hot plug support for 2.5.X kernels. + - Correct default precompensation value for RevA hardware. + - Fix Domain Validation thread shutdown. + - Add a firmware workaround to make the LED blink + brighter during packetized operations on the H2A4. + - Correct /proc display of user read streaming settings. + - Simplify driver locking by releasing the io_request_lock + upon driver entry from the mid-layer. + - Cleanup command line parsing and move much of this code + to aiclib. + + 1.3.4 (February 28th, 2003) + - Correct a race condition in our error recovery handler. + - Allow Test Unit Ready commands to take a full 5 seconds + during Domain Validation. + + 1.3.2 (February 19th, 2003) + - Correct a Rev B. regression due to the GEM318 + compatibility fix included in 1.3.1. + + 1.3.1 (February 11th, 2003) + - Add support for the 39320A. + - Improve recovery for certain PCI-X errors. + - Fix handling of LQ/DATA/LQ/DATA for the + same write transaction that can occur without + interveining training. + - Correct compatibility issues with the GEM318 + enclosure services device. + - Correct data corruption issue that occurred under + high tag depth write loads. + - Adapt to a change in the 2.5.X daemonize() API. + - Correct a "Missing case in ahd_handle_scsiint" panic. + + 1.3.0 (January 21st, 2003) + - Full regression testing for all U320 products completed. + - Added abort and target/lun reset error recovery handler and + interrupt coalessing. + + 1.2.0 (November 14th, 2002) + - Added support for Domain Validation + - Add support for the Hewlett-Packard version of the 39320D + and AIC-7902 adapters. + Support for previous adapters has not been fully tested and should + only be used at the customer's own risk. + + 1.1.1 (September 24th, 2002) + - Added support for the Linux 2.5.X kernel series + + 1.1.0 (September 17th, 2002) + - Added support for four additional SCSI products: + ASC-39320, ASC-29320, ASC-29320LP, AIC-7901. - (V1.0, May 2002) This is the initial release of the - Ultra320 FMS. The following is a list of supported features: + 1.0.0 (May 30th, 2002) + - Initial driver release. 2.1. Software/Hardware Features - Support for the SPI-4 "Ultra320" standard: @@ -82,6 +194,7 @@ supported) - Support for the PCI-X standard up to 133MHz - Support for the PCI v2.2 standard + - Domain Validation 2.2. Operating System Support: - Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1 diff -Nru a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt --- a/Documentation/scsi/aic7xxx.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/scsi/aic7xxx.txt Thu Jan 8 23:00:23 2004 @@ -131,27 +131,54 @@ SCSI "stub" effects. 2. Version History + 6.2.36 (June 3rd, 2003) + - Correct code that disables PCI parity error checking. + - Correct and simplify handling of the ignore wide residue + message. The previous code would fail to report a residual + if the transaction data length was even and we received + an IWR message. + - Add support for the 2.5.X EISA framework. + - Update for change in 2.5.X SCSI proc FS interface. + - Correct Domain Validation command-line option parsing. + - When negotiation async via an 8bit WDTR message, send + an SDTR with an offset of 0 to be sure the target + knows we are async. This works around a firmware defect + in the Quantum Atlas 10K. + - Clear PCI error state during driver attach so that we + don't disable memory mapped I/O due to a stray write + by some other driver probe that occurred before we + claimed the controller. - 6.2.34 - Fix locking regression instroduced in 6.2.29 that - could cuase a lock order reversal between the io_request_lock - and our per-softc lock. This was only possible on RH9, - SuSE, and kernel.org 2.4.X kernels. - - 6.2.33 - Dynamically disable PCI parity error reporting after - 10 errors are reported to the user. These errors are - the result of some other device issuing PCI transactions - with bad parity. Once the user has been informed of the - problem, continuing to report the errors just degrades - our performance. - - 6.2.32 - Dynamically sized S/G lists to avoid SCSI malloc - pool fragmentation and SCSI mid-layer deadlock. - - 6.2.28 - Domain Validation Fixes - PCI parity error disable - Enhanced Memory Mapped I/O probe + 6.2.35 (May 14th, 2003) + - Fix a few GCC 3.3 compiler warnings. + - Correct operation on EISA Twin Channel controller. + - Add support for 2.5.X's scsi_report_device_reset(). - 6.2.20 - Added Domain Validation + 6.2.34 (May 5th, 2003) + - Fix locking regression instroduced in 6.2.29 that + could cuase a lock order reversal between the io_request_lock + and our per-softc lock. This was only possible on RH9, + SuSE, and kernel.org 2.4.X kernels. + + 6.2.33 (April 30th, 2003) + - Dynamically disable PCI parity error reporting after + 10 errors are reported to the user. These errors are + the result of some other device issuing PCI transactions + with bad parity. Once the user has been informed of the + problem, continuing to report the errors just degrades + our performance. + + 6.2.32 (March 28th, 2003) + - Dynamically sized S/G lists to avoid SCSI malloc + pool fragmentation and SCSI mid-layer deadlock. + + 6.2.28 (January 20th, 2003) + - Domain Validation Fixes + - Add ability to disable PCI parity error checking. + - Enhanced Memory Mapped I/O probe + + 6.2.20 (November 7th, 2002) + - Added Domain Validation. 3. Command Line Options diff -Nru a/Documentation/scsi/st.txt b/Documentation/scsi/st.txt --- a/Documentation/scsi/st.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/scsi/st.txt Thu Jan 8 23:00:23 2004 @@ -2,7 +2,7 @@ The driver is currently maintained by Kai Mäkisara (email Kai.Makisara@kolumbus.fi) -Last modified: Sat Apr 12 20:26:37 2003 by makisara +Last modified: Sun Nov 9 22:36:02 2003 by makisara BASICS @@ -93,6 +93,24 @@ device can be opened for writing even if there is a write protected tape in the drive (commands trying to write something return error if attempted). + + +MINOR NUMBERS + +The tape driver currently supports 128 drives by default. This number +can be increased by editing st.h and recompiling the driver if +necessary. The upper limit is 2^17 drives if 4 modes for each drive +are used. + +The minor numbers consist of the following bit fields: + +dev_upper non-rew mode dev-lower + 20 - 8 7 6 5 4 0 +The non-rewind bit is always bit 7 (the uppermost bit in the lowermost +byte). The bits defining the mode are next to the non-rewind bits. The +remaining bits define the tape device number. This numbering is +backward compatible with the numbering used when the minor number was +only 8 bits wide. BSD AND SYS V SEMANTICS diff -Nru a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl Thu Jan 8 23:00:23 2004 +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl Thu Jan 8 23:00:23 2004 @@ -3623,7 +3623,7 @@ More precise information can be found in - alsa-kernel/Documentation/ControlNames.txt. + alsa-kernel/Documentation/sound/alsa/ControlNames.txt. diff -Nru a/Documentation/sound/oss/CMI8330 b/Documentation/sound/oss/CMI8330 --- a/Documentation/sound/oss/CMI8330 Thu Jan 8 23:00:23 2004 +++ b/Documentation/sound/oss/CMI8330 Thu Jan 8 23:00:23 2004 @@ -2,7 +2,7 @@ ------------------------------------- Alessandro Zummo -( Be sure to read Documentation/sound/SoundPro too ) +( Be sure to read Documentation/sound/oss/SoundPro too ) This adapter is now directly supported by the sb driver. diff -Nru a/Documentation/sound/oss/INSTALL.awe b/Documentation/sound/oss/INSTALL.awe --- a/Documentation/sound/oss/INSTALL.awe Thu Jan 8 23:00:24 2004 +++ b/Documentation/sound/oss/INSTALL.awe Thu Jan 8 23:00:24 2004 @@ -114,7 +114,7 @@ # insmod awe_wave (Be sure to load awe_wave after sb!) - See /usr/src/linux/Documentation/sound/AWE32 for + See /usr/src/linux/Documentation/sound/oss/AWE32 for more details. 9. (only for obsolete systems) If you don't have /dev/sequencer diff -Nru a/Documentation/sound/oss/Introduction b/Documentation/sound/oss/Introduction --- a/Documentation/sound/oss/Introduction Thu Jan 8 23:00:24 2004 +++ b/Documentation/sound/oss/Introduction Thu Jan 8 23:00:24 2004 @@ -24,7 +24,7 @@ ======== 0.1.0 11/20/1998 First version, draft 1.0.0 11/1998 Alan Cox changes, incorporation in 2.2.0 - as /usr/src/linux/Documentation/sound/Introduction + as /usr/src/linux/Documentation/sound/oss/Introduction 1.1.0 6/30/1999 Second version, added notes on making the drivers, added info on multiple sound cards of similar types,] added more diagnostics info, added info about esd. diff -Nru a/Documentation/sound/oss/PAS16 b/Documentation/sound/oss/PAS16 --- a/Documentation/sound/oss/PAS16 Thu Jan 8 23:00:24 2004 +++ b/Documentation/sound/oss/PAS16 Thu Jan 8 23:00:24 2004 @@ -9,7 +9,7 @@ This documentation is relevant for the PAS16 driver (pas2_card.c and friends) under kernel version 2.3.99 and later. If you are unfamiliar with configuring sound under Linux, please read the -Sound-HOWTO, linux/Documentation/sound/Introduction and other +Sound-HOWTO, linux/Documentation/sound/oss/Introduction and other relevant docs first. The following information is relevant information from README.OSS @@ -73,8 +73,8 @@ You want to read the Sound-HOWTO, available from http://www.tldp.org/docs.html#howto . General information about the modular sound system is contained in the files - Documentation/sound/Introduction. The file - Documentation/sound/README.OSS contains some slightly outdated but + Documentation/sound/oss/Introduction. The file + Documentation/sound/oss/README.OSS contains some slightly outdated but still useful information as well. OSS sound modules @@ -119,7 +119,7 @@ cards may have software (TSR) FM emulation. Enabling FM support with these cards may cause trouble (I don't currently know of any such cards, however). - Please read the file Documentation/sound/OPL3 if your card has an + Please read the file Documentation/sound/oss/OPL3 if your card has an OPL3 chip. If you compile the driver into the kernel, you have to add "opl3=" to the kernel command line. diff -Nru a/Documentation/sound/oss/SoundPro b/Documentation/sound/oss/SoundPro --- a/Documentation/sound/oss/SoundPro Thu Jan 8 23:00:24 2004 +++ b/Documentation/sound/oss/SoundPro Thu Jan 8 23:00:24 2004 @@ -1,7 +1,7 @@ Documentation for the SoundPro CMI8330 extensions in the WSS driver (ad1848.o) ------------------------------------------------------------------------------ -( Be sure to read Documentation/sound/CMI8330 too ) +( Be sure to read Documentation/sound/oss/CMI8330 too ) Ion Badulescu, ionut@cs.columbia.edu February 24, 1999 diff -Nru a/Documentation/sound/oss/Wavefront b/Documentation/sound/oss/Wavefront --- a/Documentation/sound/oss/Wavefront Thu Jan 8 23:00:23 2004 +++ b/Documentation/sound/oss/Wavefront Thu Jan 8 23:00:23 2004 @@ -105,7 +105,7 @@ drivers/sound/wf_midi.c -- the "uart401" driver to support virtual MIDI mode. include/wavefront.h -- the header file - Documentation/sound/Tropez+ -- short docs on configuration + Documentation/sound/oss/Tropez+ -- short docs on configuration ********************************************************************** 4) How do I compile/install/use it ? diff -Nru a/Documentation/usb/w9968cf.txt b/Documentation/usb/w9968cf.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/usb/w9968cf.txt Thu Jan 8 23:00:24 2004 @@ -0,0 +1,463 @@ + + W996[87]CF JPEG USB Dual Mode Camera Chip driver for Linux 2.6 + ============================================================== + + - Documentation - + + +Index +===== +1. Copyright +2. License +3. Overview +4. Supported devices +5. Kernel configuration and third-part module compilation +6. Module loading +7. Module paramaters +8. Credits + + +1. Copyright +============ +Copyright (C) 2002 2003 by Luca Risolia + + +2. License +========== +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +3. Overview +=========== +This driver supports the video streaming capabilities of the devices mounting +Winbond W9967CF and Winbond W9968CF JPEG USB Dual Mode Camera Chips, when they +are being commanded by USB. + +The driver relies on the Video4Linux, USB and I2C core modules of the Linux +kernel, version 2.6.0 or greater, and is not compatible in any way with +previous versions. It has been designed to run properly on SMP systems +as well. At the moment, an additional module, "ovcamchip", is mandatory; it +provides support for some OmniVision CMOS sensors connected to the W996[87]CF +chips. + +The driver is split into two modules: the basic one, "w9968cf", is needed for +the supported devices to work; the second one, "w9968cf-vpp", is an optional +module, which provides some useful video post-processing functions like video +decoding, up-scaling and colour conversions. These routines can't be included +into official kernels for performance purposes. Once the driver is installed, +every time an application tries to open a recognized device, "w9968cf" checks +the presence of the "w9968cf-vpp" module and loads it automatically by default. + +Up to 32 cameras can be handled at the same time. They can be connected and +disconnected from the host many times without turning off the computer, if +your system supports the hotplug facility. + +To change the default settings for each camera, many paramaters can be passed +through command line when the module is loaded into memory. + +The latest and full featured version of the W996[87]CF driver can be found at: +http://go.lamarinapunto.com/ + +The "ovcamchip" module is part of the OV511 driver, version 2.25, which can be +downloaded from internet: +http://alpha.dyndns.org/ov511/ +To know how to patch, compile and load it, read the paragraphs below. + + +4. Supported devices +==================== +At the moment, known W996[87]CF based devices are: +- Aroma Digi Pen ADG-5000 Refurbished +- AVerTV USB +- Creative Labs Video Blaster WebCam Go +- Creative Labs Video Blaster WebCam Go Plus +- Die Lebon LDC-D35A Digital Kamera +- Ezonics EZ-802 EZMega Cam +- OPCOM Digi Pen VGA Dual Mode Pen Camera + +If you know any other W996[87]CF based cameras, please contact me. + +The list above does NOT imply that all those devices work with this driver: up +until now only webcams that have a CMOS sensor supported by the "ovcamchip" +module work. +For a list of supported CMOS sensors, please visit the module author homepage: +http://alpha.dyndns.org/ov511/ + +Possible external microcontrollers of those webcams are not supported: this +means that still images can't be downloaded from the device memory. + +Furthermore, it's worth to note that I was only able to run tests on my +"Creative Labs Video Blaster WebCam Go". Donations of other models, for +additional testing and full support, would be much appreciated. + + +5. Kernel configuration and third-part module compilation +========================================================= +As noted above, kernel 2.6.0 is the minimum for this driver; for it to work +properly, the driver needs kernel support for Video4Linux, USB and I2C, and a +third-part module for the CMOS sensor. + +The following options of the kernel configuration file must be enabled and +corresponding modules must be compiled: + + # Multimedia devices + # + CONFIG_VIDEO_DEV=m + + # I2C support + # + CONFIG_I2C=m + +The I2C core module can be compiled statically in the kernel as well. + + # USB support + # + CONFIG_USB=m + +In addition, depending on the hardware being used, just one of the modules +below is necessary: + + # USB Host Controller Drivers + # + CONFIG_USB_EHCI_HCD=m + CONFIG_USB_UHCI_HCD=m + CONFIG_USB_OHCI_HCD=m + +Also, make sure "Enforce bandwidth allocation" is NOT enabled. + + # USB Multimedia devices + # + CONFIG_USB_W9968CF=m + +The last module we need is "ovcamchip.o". To obtain it, you have to download +the OV511 driver, version 2.25 - don't use other versions - which is available +at http://alpha.dyndns.org/ov511/ . Then you have to download the latest +version of the full featured W996[87]CF driver, which contains a patch for the +"ovcamchip" module; it is available at http://go.lamarinapunto.com . +Once you have obtained the packages, decompress, patch and compile the +"ovcamchip" module. In other words: + + [user@localhost home]$ tar xvzf w9968cf-x.x.tar.gz + [user@localhost home]$ tar xvjf ov511-2.25.tar.bz2 + [user@localhost home]$ cd ov511-2.25 + [user@localhost ov511-2.25]$ patch -p1 < \ + /path/to/w9968cf-x.x/ov511-2.25.patch + [user@localhost ov511-2.25]$ make + +It's worth to note that the full featured version of the W996[87]CF driver +can also be installed overwriting the one in the kernel; in this case, read the +documentation included in the package. + +If everything went well, the W996[87]CF driver can be immediatly used (see next +paragraph). + + +6. Module loading +================= +To use the driver, it is necessary to load the "w9968cf" module into memory +after every other module required. + +For example, loading can be done this way, as root: + + [root@localhost home]# modprobe usbcore + [root@localhost home]# modprobe i2c-core + [root@localhost ov511-x.xx]# insmod ./ovcamchip.ko + [root@localhost home]# modprobe w9968cf + +At this point the devices should be recognized: "dmesg" can be used to analyze +kernel messages: + + [user@localhost home]$ dmesg + +There are a lot of parameters the module can use to change the default +settings for each device. To list every possible parameter with a brief +explanation about them and which syntax to use, it is recommended to run the +"modinfo" command: + + [root@locahost home]# modinfo w9968cf + + +7. Module paramaters +==================== + +Module paramaters are listed below: +------------------------------------------------------------------------------- +Name: vppmod_load +Type: int +Syntax: <0|1> +Description: Automatic 'w9968cf-vpp' module loading: 0 disabled, 1 enabled. + If enabled, every time an application attempts to open a + camera, 'insmod' searches for the video post-processing module + in the system and loads it automatically (if present). + The 'w9968cf-vpp' module adds extra image manipulation + capabilities to the 'w9968cf' module,like software up-scaling, + colour conversions and video decoding. +Default: 1 +------------------------------------------------------------------------------- +Name: simcams +Type: int +Syntax: +Description: Number of cameras allowed to stream simultaneously. + n may vary from 0 to 32. +Default: 32 +------------------------------------------------------------------------------- +Name: video_nr +Type: int array (min = 0, max = 32) +Syntax: <-1|n[,...]> +Description: Specify V4L minor mode number. + -1 = use next available + n = use minor number n + You can specify 32 cameras this way. + For example: + video_nr=-1,2,-1 would assign minor number 2 to the second + recognized camera and use auto for the first one and for every + other camera. +Default: -1 +------------------------------------------------------------------------------- +Name: packet_size +Type: int array (min = 0, max = 32) +Syntax: +Description: Specify the maximum data payload size in bytes for alternate + settings, for each device. n is scaled between 63 and 1023. +Default: 1023 +------------------------------------------------------------------------------- +Name: max_buffers +Type: int array (min = 0, max = 32) +Syntax: +Description: Only for advanced users. + Specify the maximum number of video frame buffers to allocate + for each device, from 2 to 32. +Default: 2 +------------------------------------------------------------------------------- +Name: double_buffer +Type: int array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: Hardware double buffering: 0 disabled, 1 enabled. + It should be enabled if you want smooth video output: if you + obtain out of sync. video, disable it at all, or try to + decrease the 'clockdiv' module paramater value. +Default: 1 for every device. +------------------------------------------------------------------------------- +Name: clamping +Type: int array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: Video data clamping: 0 disabled, 1 enabled. +Default: 0 for every device. +------------------------------------------------------------------------------- +Name: filter_type +Type: int array (min = 0, max = 32) +Syntax: <0|1|2[,...]> +Description: Video filter type. + 0 none, 1 (1-2-1) 3-tap filter, 2 (2-3-6-3-2) 5-tap filter. + The filter is used to reduce noise and aliasing artifacts + produced by the CCD or CMOS sensor. +Default: 0 for every device. +------------------------------------------------------------------------------- +Name: largeview +Type: int array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: Large view: 0 disabled, 1 enabled. +Default: 1 for every device. +------------------------------------------------------------------------------- +Name: upscaling +Type: int array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: Software scaling (for non-compressed video only): + 0 disabled, 1 enabled. + Disable it if you have a slow CPU or you don't have enough + memory. +Default: 0 for every device. +Note: If 'w9968cf-vpp' is not loaded, this paramater is set to 0. +------------------------------------------------------------------------------- +Name: decompression +Type: int array (min = 0, max = 32) +Syntax: <0|1|2[,...]> +Description: Software video decompression: + 0 = disables decompression + (doesn't allow formats needing decompression). + 1 = forces decompression + (allows formats needing decompression only). + 2 = allows any permitted formats. + Formats supporting (de)compressed video are YUV422P and + YUV420P/YUV420 in any resolutions where width and height are + multiples of 16. +Default: 2 for every device. +Note: If 'w9968cf-vpp' is not loaded, forcing decompression is not + allowed; in this case this paramater is set to 2. +------------------------------------------------------------------------------- +Name: force_palette +Type: int array (min = 0, max = 32) +Syntax: <0|9|10|13|15|8|7|1|6|3|4|5[,...]> +Description: Force picture palette. + In order: + 0 = Off - allows any of the following formats: + 9 = UYVY 16 bpp - Original video, compression disabled + 10 = YUV420 12 bpp - Original video, compression enabled + 13 = YUV422P 16 bpp - Original video, compression enabled + 15 = YUV420P 12 bpp - Original video, compression enabled + 8 = YUVY 16 bpp - Software conversion from UYVY + 7 = YUV422 16 bpp - Software conversion from UYVY + 1 = GREY 8 bpp - Software conversion from UYVY + 6 = RGB555 16 bpp - Software conversion from UYVY + 3 = RGB565 16 bpp - Software conversion from UYVY + 4 = RGB24 24 bpp - Software conversion from UYVY + 5 = RGB32 32 bpp - Software conversion from UYVY + When not 0, this paramater will override 'decompression'. +Default: 0 for every device. Initial palette is 9 (UYVY). +Note: If 'w9968cf-vpp' is not loaded, this paramater is set to 9. +------------------------------------------------------------------------------- +Name: force_rgb +Type: int array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: Read RGB video data instead of BGR: + 1 = use RGB component ordering. + 0 = use BGR component ordering. + This parameter has effect when using RGBX palettes only. +Default: 0 for every device. +------------------------------------------------------------------------------- +Name: autobright +Type: long array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: CMOS sensor automatically changes brightness: + 0 = no, 1 = yes +Default: 0 for every device. +------------------------------------------------------------------------------- +Name: autoexp +Type: long array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: CMOS sensor automatically changes exposure: + 0 = no, 1 = yes +Default: 1 for every device. +------------------------------------------------------------------------------- +Name: lightfreq +Type: long array (min = 0, max = 32) +Syntax: <50|60[,...]> +Description: Light frequency in Hz: + 50 for European and Asian lighting, 60 for American lighting. +Default: 50 for every device. +------------------------------------------------------------------------------- +Name: bandingfilter +Type: long array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: Banding filter to reduce effects of fluorescent + lighting: + 0 disabled, 1 enabled. + This filter tries to reduce the pattern of horizontal + light/dark bands caused by some (usually fluorescent) lighting. +Default: 0 for every device. +------------------------------------------------------------------------------- +Name: clockdiv +Type: long array (min = 0, max = 32) +Syntax: <-1|n[,...]> +Description: Force pixel clock divisor to a specific value (for experts): + n may vary from 0 to 127. + -1 for automatic value. + See also the 'double_buffer' module paramater. +Default: -1 for every device. +------------------------------------------------------------------------------- +Name: backlight +Type: long array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: Objects are lit from behind: + 0 = no, 1 = yes +Default: 0 for every device. +------------------------------------------------------------------------------- +Name: mirror +Type: long array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: Reverse image horizontally: + 0 = no, 1 = yes +Default: 0 for every device. +------------------------------------------------------------------------------- +Name: sensor_mono +Type: long array (min = 0, max = 32) +Syntax: <0|1[,...]> +Description: The CMOS sensor is monochrome: + 0 = no, 1 = yes +Default: 0 for every device. +------------------------------------------------------------------------------- +Name: brightness +Type: long array (min = 0, max = 32) +Syntax: +Description: Set picture brightness (0-65535). + This parameter has no effect if 'autobright' is enabled. +Default: 31000 for every device. +------------------------------------------------------------------------------- +Name: hue +Type: long array (min = 0, max = 32) +Syntax: +Description: Set picture hue (0-65535). +Default: 32768 for every device. +------------------------------------------------------------------------------- +Name: colour +Type: long array (min = 0, max = 32) +Syntax: +Description: Set picture saturation (0-65535). +Default: 32768 for every device. +------------------------------------------------------------------------------- +Name: contrast +Type: long array (min = 0, max = 32) +Syntax: +Description: Set picture contrast (0-65535). +Default: 50000 for every device. +------------------------------------------------------------------------------- +Name: whiteness +Type: long array (min = 0, max = 32) +Syntax: +Description: Set picture whiteness (0-65535). +Default: 32768 for every device. +------------------------------------------------------------------------------- +Name: debug +Type: int +Syntax: +Description: Debugging information level, from 0 to 6: + 0 = none (be cautious) + 1 = critical errors + 2 = significant informations + 3 = configuration or general messages + 4 = warnings + 5 = called functions + 6 = function internals + Level 5 and 6 are useful for testing only, when just one + device is used. +Default: 2 +------------------------------------------------------------------------------- +Name: specific_debug +Type: int +Syntax: <0|1> +Description: Enable or disable specific debugging messages: + 0 = print messages concerning every level <= 'debug' level. + 1 = print messages concerning the level indicated by 'debug'. +Default: 0 +------------------------------------------------------------------------------- + + +8. Credits +========== +The development would not have proceed much further without having looked at +the source code of other drivers and without the help of several persons; in +particular: + +- the I2C interface to kernel and high-level CMOS sensor control routines have + been taken from the OV511 driver by Mark McClelland; + +- memory management code has been copied from the bttv driver by Ralph Metzler, + Marcus Metzler and Gerd Knorr; + +- the low-level I2C read function has been written by Frédéric Jouault, who + also gave me commented logs about sniffed USB traffic taken from another + driver for another system; + +- the low-level I2C fast write function has been written by Piotr Czerczak; diff -Nru a/Documentation/watchdog/watchdog-api.txt b/Documentation/watchdog/watchdog-api.txt --- a/Documentation/watchdog/watchdog-api.txt Thu Jan 8 23:00:23 2004 +++ b/Documentation/watchdog/watchdog-api.txt Thu Jan 8 23:00:23 2004 @@ -358,6 +358,15 @@ No bits set in GETSUPPORT +w83627hf_wdt.c -- w83627hf watchdog + + Timeout that defaults to 60 seconds, supports SETTIMEOUT. + + Supports CONFIG_WATCHDOG_NOWAYOUT + + GETSUPPORT returns WDIOF_KEEPALIVEPING and WDIOF_SETTIMEOUT. + The GETSTATUS call returns if the device is open or not. + wdt.c -- ICS WDT500/501 ISA and wdt_pci.c -- ICS WDT500/501 PCI diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Thu Jan 8 23:00:24 2004 +++ b/MAINTAINERS Thu Jan 8 23:00:24 2004 @@ -73,7 +73,7 @@ 3C359 NETWORK DRIVER P: Mike Phillips M: mikep@linuxtr.net -L: linux-net@vger.rutgers.edu +L: linux-net@vger.kernel.org L: linux-tr@linuxtr.net W: http://www.linuxtr.net S: Maintained @@ -929,8 +929,9 @@ S: Maintained SN-IA64 (Itanium) SUB-PLATFORM -P: John Hesterberg -M: jh@sgi.com +P: Jesse Barnes +M: jbarnes@sgi.com +L: linux-altix@sgi.com L: linux-ia64@linuxia64.org W: http://www.sgi.com/altix S: Maintained @@ -979,25 +980,28 @@ P: Ben Collins M: bcollins@debian.org L: linux1394-devel@lists.sourceforge.net -W: http://linux1394.sourceforge.net/ +W: http://www.linux1394.org/ S: Maintained IEEE 1394 OHCI DRIVER P: Ben Collins M: bcollins@debian.org L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ S: Maintained IEEE 1394 PCILYNX DRIVER P: Andreas Bombe M: andreas.bombe@munich.netsurf.de L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ S: Maintained IEEE 1394 RAW I/O DRIVER -P: Andreas Bombe -M: andreas.bombe@munich.netsurf.de +P: Ben Collins +M: bcollins@debian.org L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ S: Maintained IMS TWINTURBO FRAMEBUFFER DRIVER @@ -1234,8 +1238,8 @@ S: Maintained LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers -P: Gerard Roudier -M: groudier@free.fr +P: Matthew Wilcox +M: matthew@wil.cx L: linux-scsi@vger.kernel.org S: Maintained @@ -1468,7 +1472,7 @@ P: Willem Riede M: osst@riede.org L: osst@linux1.onstream.nl -L: linux-scsi@vger.rutgers.edu +L: linux-scsi@vger.kernel.org S: Maintained OPL3-SA2, SA3, and SAx DRIVER @@ -1556,11 +1560,8 @@ S: Maintained PCMCIA SUBSYSTEM -P: David Hinds -M: dahinds@users.sourceforge.net -L: linux-kernel@vger.kernel.org -W: http://pcmcia-cs.sourceforge.net -S: Maintained +L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia +S: Unmaintained PCNET32 NETWORK DRIVER P: Thomas Bogendörfer @@ -1852,8 +1853,10 @@ S: Maintained SPARC (sparc32): +P: Keith M. Wesolowski +M: wesolows@foobazco.org L: sparclinux@vger.kernel.org -S: Unmaintained - please send patches to mailing list +S: Maintained SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER P: Roger Wolff @@ -2216,6 +2219,13 @@ P: David Brownell M: dbrownell@users.sourceforge.net L: linux-usb-devel@lists.sourceforge.net +S: Maintained + +USB W996[87]CF DRIVER +P: Luca Risolia +M: luca_ing@libero.it +L: linux-usb-devel@lists.sourceforge.net +W: http://go.lamarinapunto.com S: Maintained USER-MODE LINUX diff -Nru a/Makefile b/Makefile --- a/Makefile Thu Jan 8 23:00:24 2004 +++ b/Makefile Thu Jan 8 23:00:24 2004 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 0 +SUBLEVEL = 1 EXTRAVERSION = # *DOCUMENTATION* @@ -275,7 +275,7 @@ CPPFLAGS := -D__KERNEL__ -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ +CFLAGS := -Wall -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common AFLAGS := -D__ASSEMBLY__ @@ -431,6 +431,12 @@ # --------------------------------------------------------------------------- +ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE +CFLAGS += -Os +else +CFLAGS += -O2 +endif + ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif @@ -872,7 +878,7 @@ $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version;\ mv -f $(objtree)/.tmp_version $(objtree)/.version; - $(RPM) -ta ../$(KERNELPATH).tar.gz + $(RPM) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz rm ../$(KERNELPATH).tar.gz # Brief documentation of the typical targets used diff -Nru a/README b/README --- a/README Thu Jan 8 23:00:24 2004 +++ b/README Thu Jan 8 23:00:24 2004 @@ -119,7 +119,7 @@ cd /usr/src/linux-2.6.N make O=/home/name/build/kernel menuconfig make O=/home/name/build/kernel - sudo make O=/home/name/build/kernel install_modules install + sudo make O=/home/name/build/kernel modules_install install Please note: If the 'O=output/dir' option is used then it must be used for all invocations of make. diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c --- a/arch/alpha/kernel/irq.c Thu Jan 8 23:00:24 2004 +++ b/arch/alpha/kernel/irq.c Thu Jan 8 23:00:24 2004 @@ -252,9 +252,11 @@ irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { - if (count < HEX_DIGITS+1) + int len = cpumask_snprintf(page, count, irq_affinity[(long)data]); + if (count - len < 2) return -EINVAL; - return sprintf (page, "%016lx\n", irq_affinity[(long)data]); + len += sprintf(page + len, "\n"); + return len; } static unsigned int @@ -331,10 +333,11 @@ prof_cpu_mask_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long *mask = (unsigned long *) data; - if (count < HEX_DIGITS+1) + int len = cpumask_snprintf(page, count, *(cpumask_t *)data); + if (count - len < 2) return -EINVAL; - return sprintf (page, "%016lx\n", *mask); + len += sprintf(page + len, "\n"); + return len; } static int @@ -529,19 +532,21 @@ #ifdef CONFIG_SMP int j; #endif - int i; + int i = *(loff_t *) v; struct irqaction * action; unsigned long flags; #ifdef CONFIG_SMP - seq_puts(p, " "); - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i)) - seq_printf(p, "CPU%d ", i); - seq_putc(p, '\n'); + if (i == 0) { + seq_puts(p, " "); + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(i)) + seq_printf(p, "CPU%d ", i); + seq_putc(p, '\n'); + } #endif - for (i = 0; i < ACTUAL_NR_IRQS; i++) { + if (i < ACTUAL_NR_IRQS) { spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) @@ -568,15 +573,16 @@ seq_putc(p, '\n'); unlock: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } + } else if (i == ACTUAL_NR_IRQS) { #ifdef CONFIG_SMP - seq_puts(p, "IPI: "); - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i)) - seq_printf(p, "%10lu ", cpu_data[i].ipi_count); - seq_putc(p, '\n'); + seq_puts(p, "IPI: "); + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(i)) + seq_printf(p, "%10lu ", cpu_data[i].ipi_count); + seq_putc(p, '\n'); #endif - seq_printf(p, "ERR: %10lu\n", irq_err_count); + seq_printf(p, "ERR: %10lu\n", irq_err_count); + } return 0; } diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile --- a/arch/arm/Makefile Thu Jan 8 23:00:23 2004 +++ b/arch/arm/Makefile Thu Jan 8 23:00:23 2004 @@ -14,8 +14,6 @@ GZFLAGS :=-9 #CFLAGS +=-pipe -CFLAGS :=$(CFLAGS:-O2=-Os) - ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif diff -Nru a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile --- a/arch/arm/boot/compressed/Makefile Thu Jan 8 23:00:23 2004 +++ b/arch/arm/boot/compressed/Makefile Thu Jan 8 23:00:23 2004 @@ -23,10 +23,6 @@ OBJS += head-shark.o ofw-shark.o endif -ifeq ($(CONFIG_ARCH_INTEGRATOR),y) -OBJS += head-integrator.o -endif - ifeq ($(CONFIG_ARCH_CAMELOT),y) OBJS += head-epxa10db.o endif diff -Nru a/arch/arm/boot/compressed/head-integrator.S b/arch/arm/boot/compressed/head-integrator.S --- a/arch/arm/boot/compressed/head-integrator.S Thu Jan 8 23:00:24 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -#include - - .section ".start", "ax" - mov r7, #MACH_TYPE_INTEGRATOR diff -Nru a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S --- a/arch/arm/boot/compressed/head.S Thu Jan 8 23:00:24 2004 +++ b/arch/arm/boot/compressed/head.S Thu Jan 8 23:00:24 2004 @@ -503,12 +503,6 @@ @ Everything from here on will be the new ID system. - .word 0x41129200 @ ARM920T - .word 0xff00fff0 - b __armv4_cache_on - b __armv4_cache_off - b __armv4_cache_flush - .word 0x4401a100 @ sa110 / sa1100 .word 0xffffffe0 b __armv4_cache_on @@ -522,6 +516,12 @@ b __armv4_cache_flush @ These match on the architecture ID + + .word 0x00020000 @ ARMv4T + .word 0x000f0000 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush .word 0x00050000 @ ARMv5TE .word 0x000f0000 diff -Nru a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c --- a/arch/arm/common/sa1111.c Thu Jan 8 23:00:24 2004 +++ b/arch/arm/common/sa1111.c Thu Jan 8 23:00:24 2004 @@ -34,6 +34,8 @@ #include +extern void __init sa1110_mb_enable(void); + /* * We keep the following data for the overall SA1111. Note that the * struct device and struct resource are "fake"; they should be supplied @@ -561,6 +563,8 @@ dev->res.name = dev->dev.bus_id; dev->res.flags = IORESOURCE_MEM; dev->mapbase = sachip->base + info->offset; + dev->skpcr_mask = info->skpcr_mask; + memmove(dev->irq, info->irq, sizeof(dev->irq)); ret = request_resource(parent, &dev->res); if (ret) { diff -Nru a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/configs/netwinder_defconfig Thu Jan 8 23:00:24 2004 @@ -0,0 +1,968 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_ADIFCC is not set +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +CONFIG_ARCH_FOOTBRIDGE=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set + +# +# CLPS711X/EP721X Implementations +# + +# +# Epxa10db +# + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +CONFIG_ARCH_NETWINDER=y + +# +# IOP3xx Implementation Options +# +# CONFIG_ARCH_IOP310 is not set +# CONFIG_ARCH_IOP321 is not set + +# +# IOP3xx Chipset Features +# + +# +# Intel PXA250/210 Implementations +# + +# +# SA11x0 Implementations +# +CONFIG_FOOTBRIDGE=y +CONFIG_FOOTBRIDGE_HOST=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA110=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WB=y + +# +# Processor Features +# + +# +# General setup +# +CONFIG_PCI=y +CONFIG_ISA=y +CONFIG_ISA_DMA=y +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="root=0x301" +CONFIG_LEDS=y +# CONFIG_LEDS_TIMER is not set +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_CML1=y +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +CONFIG_PARPORT_PC_SUPERIO=y +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +CONFIG_IP_NF_FTP=y +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +CONFIG_IP_NF_QUEUE=y +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_LIMIT is not set +# CONFIG_IP_NF_MATCH_IPRANGE is not set +# CONFIG_IP_NF_MATCH_MAC is not set +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +# CONFIG_IP_NF_MATCH_MARK is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_TCPMSS is not set +# CONFIG_IP_NF_MATCH_HELPER is not set +# CONFIG_IP_NF_MATCH_STATE is not set +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +# CONFIG_IP_NF_FILTER is not set +# CONFIG_IP_NF_NAT is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_TARGET_TCPMSS is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_SMC91X is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +# CONFIG_DE2104X is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_DE4X5 is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_DM9102 is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +CONFIG_NE2K_PCI=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set +# CONFIG_HOSTAP is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_SL82C105=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_IDEDMA_PCI_WIP is not set +CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_TSLIBDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2_SYNAPTICS is not set +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_PCSPKR is not set +CONFIG_INPUT_UINPUT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_DZ is not set +# CONFIG_SERIAL_21285 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Algorithms +# + +# +# I2C Hardware Bus support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_21285_WATCHDOG is not set +CONFIG_977_WATCHDOG=y +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set +CONFIG_DS1620=y +CONFIG_NWBUTTON=y +CONFIG_NWBUTTON_REBOOT=y +CONFIG_NWFLASH=y +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SMB_FS=y +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CYBER2000=y +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_OSS=y +CONFIG_SOUND_TRACEINIT=y +CONFIG_SOUND_DMAP=y +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_AD1889 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_MAUI is not set +CONFIG_SOUND_YM3812=y +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +CONFIG_SOUND_WAVEARTIST=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_AD1980 is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set + +# +# Console Switches +# +# CONFIG_SWITCHES is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y diff -Nru a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig --- a/arch/arm/configs/shark_defconfig Thu Jan 8 23:00:24 2004 +++ b/arch/arm/configs/shark_defconfig Thu Jan 8 23:00:24 2004 @@ -10,6 +10,10 @@ # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +# CONFIG_STANDALONE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y # # General setup @@ -19,6 +23,14 @@ # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y # # Loadable module support @@ -35,7 +47,6 @@ # # CONFIG_ARCH_ADIFCC is not set # CONFIG_ARCH_ANAKIN is not set -# CONFIG_ARCH_ARCA5K is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set @@ -44,21 +55,13 @@ # CONFIG_ARCH_CAMELOT is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP310 is not set +# CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set CONFIG_ARCH_SHARK=y # -# Archimedes/A5000 Implementations -# - -# -# Archimedes/A5000 Implementations (select only ONE) -# - -# # CLPS711X/EP721X Implementations # @@ -71,11 +74,13 @@ # # -# IOP310 Implementation Options +# IOP3xx Implementation Options # +# CONFIG_ARCH_IOP310 is not set +# CONFIG_ARCH_IOP321 is not set # -# IOP310 Chipset Features +# IOP3xx Chipset Features # # @@ -92,6 +97,10 @@ CONFIG_CPU_32=y CONFIG_CPU_SA110=y CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WB=y # # Processor Features @@ -116,11 +125,13 @@ # # CONFIG_FPE_NWFPE is not set CONFIG_FPE_FASTFPE=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set # CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# # CONFIG_PM is not set # CONFIG_PREEMPT is not set # CONFIG_ARTHUR is not set @@ -164,6 +175,7 @@ # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 @@ -185,7 +197,6 @@ CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -199,8 +210,11 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_XFRM_USER is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_NETFILTER is not set # # SCTP Configuration (EXPERIMENTAL) @@ -209,9 +223,9 @@ # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set -# CONFIG_LLC is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_NET_DIVERT is not set @@ -239,13 +253,13 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_SMC91X is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set @@ -294,8 +308,14 @@ # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -306,10 +326,12 @@ # Wireless LAN (non-hamradio) # # CONFIG_NET_RADIO is not set +# CONFIG_HOSTAP is not set # -# Token Ring devices (depends on LLC=y) +# Token Ring devices # +# CONFIG_TR is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -320,47 +342,54 @@ # CONFIG_WAN is not set # +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# # IrDA (infrared) support # # CONFIG_IRDA is not set # -# Amateur Radio support +# Bluetooth support # -# CONFIG_HAMRADIO is not set +# CONFIG_BT is not set # # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide.txt for help/info on IDE drives # -# CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set CONFIG_BLK_DEV_IDEFLOPPY=y # CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set # # IDE chipset support/bugfixes # # CONFIG_BLK_DEV_IDEPCI is not set # CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set # -# SCSI support +# SCSI device support # CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) @@ -395,7 +424,6 @@ # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set @@ -407,15 +435,13 @@ # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_PPA is not set # CONFIG_SCSI_IMM is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set @@ -425,6 +451,7 @@ # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -486,6 +513,7 @@ # CONFIG_KEYBOARD_NEWTON is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2_SYNAPTICS is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_INPORT is not set # CONFIG_MOUSE_LOGIBM is not set @@ -497,7 +525,9 @@ # # Character devices # -# CONFIG_VT is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -505,6 +535,7 @@ # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -526,12 +557,17 @@ # CONFIG_I2C is not set # -# I2C Hardware Sensors Mainboard support +# I2C Algorithms +# + +# +# I2C Hardware Bus support # # # I2C Hardware Sensors Chip support # +# CONFIG_I2C_SENSOR is not set # # L3 serial bus support @@ -566,7 +602,6 @@ # CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set -# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -574,6 +609,16 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# # File systems # CONFIG_EXT2_FS=y @@ -581,6 +626,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -618,6 +664,8 @@ # CONFIG_DEVFS_DEBUG is not set # CONFIG_DEVPTS_FS is not set # CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # @@ -642,6 +690,7 @@ CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set # CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_LOCKD=y # CONFIG_EXPORTFS is not set @@ -740,9 +789,24 @@ # CONFIG_FB_VIRTUAL is not set # +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# # Logo configuration # -# CONFIG_LOGO is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y # # Sound @@ -769,7 +833,6 @@ # CONFIG_SOUND_MAESTRO is not set # CONFIG_SOUND_MAESTRO3 is not set # CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -779,6 +842,7 @@ # CONFIG_SOUND_TRACEINIT is not set # CONFIG_SOUND_DMAP is not set # CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_AD1889 is not set # CONFIG_SOUND_SGALAXY is not set CONFIG_SOUND_ADLIB=m # CONFIG_SOUND_ACI_MIXER is not set @@ -803,6 +867,11 @@ # CONFIG_SOUND_YMFPCI is not set # CONFIG_SOUND_UART6850 is not set # CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_KAHLUA is not set +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_AD1980 is not set # # Misc devices @@ -822,11 +891,7 @@ # USB support # # CONFIG_USB is not set - -# -# Bluetooth support -# -# CONFIG_BT is not set +# CONFIG_USB_GADGET is not set # # Kernel hacking diff -Nru a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c --- a/arch/arm/kernel/armksyms.c Thu Jan 8 23:00:23 2004 +++ b/arch/arm/kernel/armksyms.c Thu Jan 8 23:00:23 2004 @@ -68,8 +68,8 @@ extern void __udivmoddi4(void); extern void __udivsi3(void); extern void __umodsi3(void); +extern void __do_div64(void); extern void abort(void); -extern void do_div64(void); extern void ret_from_exception(void); extern void fpundefinstr(void); @@ -223,7 +223,7 @@ EXPORT_SYMBOL_NOVERS(__udivmoddi4); EXPORT_SYMBOL_NOVERS(__udivsi3); EXPORT_SYMBOL_NOVERS(__umodsi3); -EXPORT_SYMBOL_NOVERS(do_div64); +EXPORT_SYMBOL_NOVERS(__do_div64); /* bitops */ EXPORT_SYMBOL(_set_bit_le); diff -Nru a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S --- a/arch/arm/kernel/calls.S Thu Jan 8 23:00:24 2004 +++ b/arch/arm/kernel/calls.S Thu Jan 8 23:00:24 2004 @@ -271,6 +271,20 @@ .long sys_ni_syscall /* sys_set_thread_area */ /* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ .long sys_ni_syscall /* sys_set_tid_address */ + .long sys_timer_create + .long sys_timer_settime + .long sys_timer_gettime +/* 260 */ .long sys_timer_getoverrun + .long sys_timer_delete + .long sys_clock_settime + .long sys_clock_gettime + .long sys_clock_getres +/* 265 */ .long sys_clock_nanosleep + .long sys_statfs64 + .long sys_fstatfs64 + .long sys_tgkill + .long sys_utimes +/* 270 */ .long sys_fadvise64_64 __syscall_end: .rept NR_syscalls - (__syscall_end - __syscall_start) / 4 diff -Nru a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c --- a/arch/arm/kernel/dma-isa.c Thu Jan 8 23:00:24 2004 +++ b/arch/arm/kernel/dma-isa.c Thu Jan 8 23:00:24 2004 @@ -85,6 +85,7 @@ break; default: + direction = PCI_DMA_NONE; break; } diff -Nru a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c --- a/arch/arm/kernel/fiq.c Thu Jan 8 23:00:24 2004 +++ b/arch/arm/kernel/fiq.c Thu Jan 8 23:00:24 2004 @@ -112,12 +112,12 @@ { register unsigned long tmp, tmp2; __asm__ volatile ( - "mrs %0, cpsr - mov %1, %3 - msr cpsr_c, %1 @ select FIQ mode - mov r0, r0 - ldmia %2, {r8 - r14} - msr cpsr_c, %0 @ return to SVC mode + "mrs %0, cpsr\n\ + mov %1, %3\n\ + msr cpsr_c, %1 @ select FIQ mode\n\ + mov r0, r0\n\ + ldmia %2, {r8 - r14}\n\ + msr cpsr_c, %0 @ return to SVC mode\n\ mov r0, r0" : "=&r" (tmp), "=&r" (tmp2) : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE) @@ -132,12 +132,12 @@ { register unsigned long tmp, tmp2; __asm__ volatile ( - "mrs %0, cpsr - mov %1, %3 - msr cpsr_c, %1 @ select FIQ mode - mov r0, r0 - stmia %2, {r8 - r14} - msr cpsr_c, %0 @ return to SVC mode + "mrs %0, cpsr\n\ + mov %1, %3\n\ + msr cpsr_c, %1 @ select FIQ mode\n\ + mov r0, r0\n\ + stmia %2, {r8 - r14}\n\ + msr cpsr_c, %0 @ return to SVC mode\n\ mov r0, r0" : "=&r" (tmp), "=&r" (tmp2) : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE) diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c --- a/arch/arm/kernel/irq.c Thu Jan 8 23:00:23 2004 +++ b/arch/arm/kernel/irq.c Thu Jan 8 23:00:23 2004 @@ -169,11 +169,11 @@ int show_interrupts(struct seq_file *p, void *v) { - int i; + int i = *(loff_t *) v; struct irqaction * action; unsigned long flags; - for (i = 0 ; i < NR_IRQS ; i++) { + if (i < NR_IRQS) { spin_lock_irqsave(&irq_controller_lock, flags); action = irq_desc[i].action; if (!action) @@ -187,12 +187,12 @@ seq_putc(p, '\n'); unlock: spin_unlock_irqrestore(&irq_controller_lock, flags); - } - + } else if (i == NR_IRQS) { #ifdef CONFIG_ARCH_ACORN - show_fiq_list(p, v); + show_fiq_list(p, v); #endif - seq_printf(p, "Err: %10lu\n", irq_err_count); + seq_printf(p, "Err: %10lu\n", irq_err_count); + } return 0; } diff -Nru a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c --- a/arch/arm/kernel/module.c Thu Jan 8 23:00:23 2004 +++ b/arch/arm/kernel/module.c Thu Jan 8 23:00:23 2004 @@ -123,9 +123,10 @@ if (offset & 3 || offset <= (s32)0xfc000000 || offset >= (s32)0x04000000) { - printk(KERN_ERR "%s: unable to fixup " - "relocation: out of range\n", - module->name); + printk(KERN_ERR + "%s: relocation out of range, section " + "%d reloc %d sym '%s'\n", module->name, + relindex, i, strtab + sym->st_name); return -ENOEXEC; } diff -Nru a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S --- a/arch/arm/lib/div64.S Thu Jan 8 23:00:24 2004 +++ b/arch/arm/lib/div64.S Thu Jan 8 23:00:24 2004 @@ -1,59 +1,200 @@ +/* + * linux/arch/arm/lib/div64.S + * + * Optimized computation of 64-bit dividend / 32-bit divisor + * + * Author: Nicolas Pitre + * Created: Oct 5, 2003 + * Copyright: Monta Vista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + #include -#ifndef __ARMEB__ -ql .req r0 @ quotient low -qh .req r1 @ quotient high -onl .req r0 @ original dividend low -onh .req r1 @ original dividend high -nl .req r4 @ dividend low -nh .req r5 @ dividend high -res .req r4 @ result +#ifdef __ARMEB__ +#define xh r0 +#define xl r1 +#define yh r2 +#define yl r3 +#else +#define xl r0 +#define xh r1 +#define yl r2 +#define yh r3 +#endif + +/* + * __do_div64: perform a division with 64-bit dividend and 32-bit divisor. + * + * Note: Calling convention is totally non standard for optimal code. + * This is meant to be used by do_div() from include/asm/div64.h only. + * + * Input parameters: + * xh-xl = dividend (clobbered) + * r4 = divisor (preserved) + * + * Output values: + * yh-yl = result + * xh = remainder + * + * Clobbered regs: xl, ip + */ + +ENTRY(__do_div64) + + @ Test for easy paths first. + subs ip, r4, #1 + bls 9f @ divisor is 0 or 1 + tst ip, r4 + beq 8f @ divisor is power of 2 + + @ See if we need to handle upper 32-bit result. + cmp xh, r4 + mov yh, #0 + blo 3f + + @ Align divisor with upper part of dividend. + @ The aligned divisor is stored in yl preserving the original. + @ The bit position is stored in ip. + +#if __LINUX_ARM_ARCH__ >= 5 + + clz yl, r4 + clz ip, xh + sub yl, yl, ip + mov ip, #1 + mov ip, ip, lsl yl + mov yl, r4, lsl yl + +#else + + mov yl, r4 + mov ip, #1 +1: cmp yl, #0x80000000 + cmpcc yl, xh + movcc yl, yl, lsl #1 + movcc ip, ip, lsl #1 + bcc 1b + +#endif + + @ The division loop for needed upper bit positions. + @ Break out early if dividend reaches 0. +2: cmp xh, yl + orrcs yh, yh, ip + subcss xh, xh, yl + movnes ip, ip, lsr #1 + mov yl, yl, lsr #1 + bne 2b + + @ See if we need to handle lower 32-bit result. +3: cmp xh, #0 + mov yl, #0 + cmpeq xl, r4 + movlo xh, xl + movlo pc, lr + + @ The division loop for lower bit positions. + @ Here we shift remainer bits leftwards rather than moving the + @ divisor for comparisons, considering the carry-out bit as well. + mov ip, #0x80000000 +4: movs xl, xl, lsl #1 + adcs xh, xh, xh + beq 6f + cmpcc xh, r4 +5: orrcs yl, yl, ip + subcs xh, xh, r4 + movs ip, ip, lsr #1 + bne 4b + mov pc, lr + + @ The top part of remainder became zero. If carry is set + @ (the 33th bit) this is a false positive so resume the loop. + @ Otherwise, if lower part is also null then we are done. +6: bcs 5b + cmp xl, #0 + moveq pc, lr + + @ We still have remainer bits in the low part. Bring them up. + +#if __LINUX_ARM_ARCH__ >= 5 + + clz xh, xl @ we know xh is zero here so... + add xh, xh, #1 + mov xl, xl, lsl xh + mov ip, ip, lsr xh + #else -ql .req r1 -qh .req r0 -onl .req r1 -onh .req r0 -nl .req r5 -nh .req r4 -res .req r5 + +7: movs xl, xl, lsl #1 + mov ip, ip, lsr #1 + bcc 7b + #endif -dl .req r3 @ divisor low -dh .req r2 @ divsor high + @ Current remainder is now 1. It is worthless to compare with + @ divisor at this point since divisor can not be smaller than 3 here. + @ If possible, branch for another shift in the division loop. + @ If no bit position left then we are done. + movs ip, ip, lsr #1 + mov xh, #1 + bne 4b + mov pc, lr + +8: @ Division by a power of 2: determine what that divisor order is + @ then simply shift values around + +#if __LINUX_ARM_ARCH__ >= 5 + clz ip, r4 + rsb ip, ip, #31 + +#else + + mov yl, r4 + cmp r4, #(1 << 16) + mov ip, #0 + movhs yl, yl, lsr #16 + movhs ip, #16 + + cmp yl, #(1 << 8) + movhs yl, yl, lsr #8 + addhs ip, ip, #8 + + cmp yl, #(1 << 4) + movhs yl, yl, lsr #4 + addhs ip, ip, #4 + + cmp yl, #(1 << 2) + addhi ip, ip, #3 + addls ip, ip, yl, lsr #1 + +#endif -ENTRY(do_div64) - stmfd sp!, {r4, r5, lr} - mov nl, onl - movs nh, onh @ if high bits are zero - movne lr, #33 - moveq lr, #1 @ only divide low bits - moveq nh, onl - - tst dh, #0x80000000 - bne 2f -1: cmp nh, dh - bls 2f - add lr, lr, #1 - movs dh, dh, lsl #1 @ left justify disor - bpl 1b - -2: movs nh, onh - moveq dl, dh - moveq dh, #0 - movne dl, #0 - mov ql, #0 - mov qh, #0 -3: subs ip, nl, dl @ trial subtraction - sbcs ip, nh, dh - movcs nh, ip @ only update if successful - subcs nl, nl, dl @ (repeat the subtraction) - adcs ql, ql, ql @ C=1 if successful, shift into - adc qh, qh, qh @ quotient - movs dh, dh, lsr #1 @ shift base high part right - mov dl, dl, rrx @ shift base low part right - subs lr, lr, #1 - bne 3b + mov yh, xh, lsr ip + mov yl, xl, lsr ip + rsb ip, ip, #32 + orr yl, yl, xh, lsl ip + mov xh, xl, lsl ip + mov xh, xh, lsr ip + mov pc, lr + + @ eq -> division by 1: obvious enough... +9: moveq yl, xl + moveq yh, xh + moveq xh, #0 + moveq pc, lr + + @ Division by 0: + str lr, [sp, #-4]! + bl __div0 + + @ as wrong as it could be... + mov yl, #0 + mov yh, #0 + mov xh, #0 + ldr pc, [sp], #4 - mov r2, res - ldmfd sp!, {r4, r5, pc} diff -Nru a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c --- a/arch/arm/mach-clps711x/time.c Thu Jan 8 23:00:23 2004 +++ b/arch/arm/mach-clps711x/time.c Thu Jan 8 23:00:23 2004 @@ -40,6 +40,7 @@ void __init clps711x_setup_timer(void) { + struct timespec tv; unsigned int syscon; gettimeoffset = clps711x_gettimeoffset; @@ -50,5 +51,7 @@ clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */ - xtime.tv_sec = clps_readl(RTCDR); + tv.tv_nsec = 0; + tv.tv_sec = clps_readl(RTCDR); + do_settimeofday(&tv); } diff -Nru a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c --- a/arch/arm/mach-integrator/cpu.c Thu Jan 8 23:00:24 2004 +++ b/arch/arm/mach-integrator/cpu.c Thu Jan 8 23:00:24 2004 @@ -172,7 +172,7 @@ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.max_freq = 160000; policy->cpuinfo.min_freq = 12000; - policy->cpuinfo.transition_latency = 1000; /* 1 ms, assumed */ + policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */ policy->cur = policy->min = policy->max = icst525_khz(&cclk_params, vco); /* current freq */ diff -Nru a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c --- a/arch/arm/mach-integrator/integrator_ap.c Thu Jan 8 23:00:24 2004 +++ b/arch/arm/mach-integrator/integrator_ap.c Thu Jan 8 23:00:24 2004 @@ -126,7 +126,7 @@ writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); for (i = 0; i < NR_IRQS; i++) { - if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) { + if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) { set_irq_chip(i, &sc_chip); set_irq_handler(i, do_level_IRQ); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); diff -Nru a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig --- a/arch/arm/mach-sa1100/Kconfig Thu Jan 8 23:00:24 2004 +++ b/arch/arm/mach-sa1100/Kconfig Thu Jan 8 23:00:24 2004 @@ -304,7 +304,7 @@ depends on ARCH_SA1100 help Say Y here to support the Yopy PDA. Product information at - . See Documentation/arm/SA110/Yopy + . See Documentation/arm/SA1100/Yopy for more. config SA1100_STORK diff -Nru a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S --- a/arch/arm/mm/cache-v3.S Thu Jan 8 23:00:24 2004 +++ b/arch/arm/mm/cache-v3.S Thu Jan 8 23:00:24 2004 @@ -32,14 +32,14 @@ /* FALLTHROUGH */ /* - * flush_user_cache_range(start, end, vm_flags) + * flush_user_cache_range(start, end, flags) * * Invalidate a range of cache entries in the specified * address space. * * - start - start address (may not be aligned) * - end - end address (exclusive, may not be aligned) - * - vma - vma_area_struct describing address space + * - flags - vma_area_struct flags describing address space */ ENTRY(v3_flush_user_cache_range) mov ip, #0 diff -Nru a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S --- a/arch/arm/mm/cache-v4.S Thu Jan 8 23:00:23 2004 +++ b/arch/arm/mm/cache-v4.S Thu Jan 8 23:00:23 2004 @@ -34,14 +34,14 @@ mov pc, lr /* - * flush_user_cache_range(start, end, vma) + * flush_user_cache_range(start, end, flags) * * Invalidate a range of cache entries in the specified * address space. * * - start - start address (may not be aligned) * - end - end address (exclusive, may not be aligned) - * - vma - vma_area_struct describing address space + * - flags - vma_area_struct flags describing address space */ ENTRY(v4_flush_user_cache_range) mov ip, #0 diff -Nru a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S --- a/arch/arm/mm/cache-v4wb.S Thu Jan 8 23:00:24 2004 +++ b/arch/arm/mm/cache-v4wb.S Thu Jan 8 23:00:24 2004 @@ -72,14 +72,14 @@ mov pc, lr /* - * flush_user_cache_range(start, end, vm_flags) + * flush_user_cache_range(start, end, flags) * * Invalidate a range of cache entries in the specified * address space. * * - start - start address (inclusive, page aligned) * - end - end address (exclusive, page aligned) - * - vma - vma_area_struct describing address space + * - flags - vma_area_struct flags describing address space */ ENTRY(v4wb_flush_user_cache_range) sub r3, r1, r0 @ calculate total size diff -Nru a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S --- a/arch/arm/mm/cache-v4wt.S Thu Jan 8 23:00:23 2004 +++ b/arch/arm/mm/cache-v4wt.S Thu Jan 8 23:00:23 2004 @@ -64,14 +64,14 @@ mov pc, lr /* - * flush_user_cache_range(start, end, vm_flags) + * flush_user_cache_range(start, end, flags) * * Clean and invalidate a range of cache entries in the specified * address space. * * - start - start address (inclusive, page aligned) * - end - end address (exclusive, page aligned) - * - vma - vma_area_struct describing address space + * - flags - vma_area_struct flags describing address space */ ENTRY(v4wt_flush_user_cache_range) sub r3, r1, r0 @ calculate total size diff -Nru a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c --- a/arch/arm/mm/mm-armv.c Thu Jan 8 23:00:24 2004 +++ b/arch/arm/mm/mm-armv.c Thu Jan 8 23:00:24 2004 @@ -10,6 +10,7 @@ * Page table sludge for ARM v3 and v4 processor architectures. */ #include +#include #include #include #include @@ -25,23 +26,52 @@ #include -static unsigned int cachepolicy __initdata = PMD_SECT_WB; +#define CPOLICY_UNCACHED 0 +#define CPOLICY_BUFFERED 1 +#define CPOLICY_WRITETHROUGH 2 +#define CPOLICY_WRITEBACK 3 +#define CPOLICY_WRITEALLOC 4 + +static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; static unsigned int ecc_mask __initdata = 0; +pgprot_t pgprot_kernel; + +EXPORT_SYMBOL(pgprot_kernel); struct cachepolicy { - char *policy; + const char policy[16]; unsigned int cr_mask; unsigned int pmd; + unsigned int pte; }; static struct cachepolicy cache_policies[] __initdata = { - { "uncached", CR_W|CR_C, PMD_SECT_UNCACHED }, - { "buffered", CR_C, PMD_SECT_BUFFERED }, - { "writethrough", 0, PMD_SECT_WT }, -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - { "writeback", 0, PMD_SECT_WB }, - { "writealloc", 0, PMD_SECT_WBWA } -#endif + { + .policy = "uncached", + .cr_mask = CR_W|CR_C, + .pmd = PMD_SECT_UNCACHED, + .pte = 0, + }, { + .policy = "buffered", + .cr_mask = CR_C, + .pmd = PMD_SECT_BUFFERED, + .pte = PTE_BUFFERABLE, + }, { + .policy = "writethrough", + .cr_mask = 0, + .pmd = PMD_SECT_WT, + .pte = PTE_CACHEABLE, + }, { + .policy = "writeback", + .cr_mask = 0, + .pmd = PMD_SECT_WB, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + }, { + .policy = "writealloc", + .cr_mask = 0, + .pmd = PMD_SECT_WBWA, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + } }; /* @@ -58,7 +88,7 @@ int len = strlen(cache_policies[i].policy); if (memcmp(*p, cache_policies[i].policy, len) == 0) { - cachepolicy = cache_policies[i].pmd; + cachepolicy = i; cr_alignment &= ~cache_policies[i].cr_mask; cr_no_alignment &= ~cache_policies[i].cr_mask; *p += len; @@ -306,9 +336,23 @@ */ static void __init build_mem_type_table(void) { + struct cachepolicy *cp; unsigned int cr = get_cr(); int cpu_arch = cpu_architecture(); - const char *policy; + int i; + +#if defined(CONFIG_CPU_DCACHE_DISABLE) + if (cachepolicy > CPOLICY_BUFFERED) + cachepolicy = CPOLICY_BUFFERED; +#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) + if (cachepolicy > CPOLICY_WRITETHROUGH) + cachepolicy = CPOLICY_WRITETHROUGH; +#endif + if (cpu_arch < CPU_ARCH_ARMv5) { + if (cachepolicy >= CPOLICY_WRITEALLOC) + cachepolicy = CPOLICY_WRITEBACK; + ecc_mask = 0; + } /* * ARMv6 and above have extended page tables. @@ -327,56 +371,39 @@ mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; } - /* - * ARMv6 can map the vectors as write-through. - */ - if (cpu_arch >= CPU_ARCH_ARMv6) - mem_types[MT_VECTORS].prot_pte |= PTE_CACHEABLE; - else - mem_types[MT_VECTORS].prot_pte |= PTE_BUFFERABLE|PTE_CACHEABLE; + cp = &cache_policies[cachepolicy]; - /* - * ARMv5 and higher can use ECC memory. - */ if (cpu_arch >= CPU_ARCH_ARMv5) { - mem_types[MT_VECTORS].prot_l1 |= ecc_mask; - mem_types[MT_MEMORY].prot_sect |= ecc_mask; + mem_types[MT_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; } else { + mem_types[MT_VECTORS].prot_pte |= cp->pte; mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); - if (cachepolicy == PMD_SECT_WBWA) - cachepolicy = PMD_SECT_WB; - ecc_mask = 0; } - mem_types[MT_MEMORY].prot_sect |= cachepolicy; + mem_types[MT_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; - switch (cachepolicy) { - default: - case PMD_SECT_UNCACHED: - policy = "uncached"; - break; - case PMD_SECT_BUFFERED: - mem_types[MT_VECTORS].prot_pte |= PTE_BUFFERABLE; - policy = "buffered"; - break; + for (i = 0; i < 16; i++) { + unsigned long v = pgprot_val(protection_map[i]); + v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte; + protection_map[i] = __pgprot(v); + } + + pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | + L_PTE_DIRTY | L_PTE_WRITE | + L_PTE_EXEC | cp->pte); + + switch (cp->pmd) { case PMD_SECT_WT: - mem_types[MT_VECTORS].prot_pte |= PTE_BUFFERABLE|PTE_CACHEABLE; mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; - policy = "write through"; break; case PMD_SECT_WB: - mem_types[MT_VECTORS].prot_pte |= PTE_BUFFERABLE|PTE_CACHEABLE; - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; - policy = "write back"; - break; case PMD_SECT_WBWA: - mem_types[MT_VECTORS].prot_pte |= PTE_BUFFERABLE|PTE_CACHEABLE; mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; - policy = "write back, write allocate"; break; } printk("Memory policy: ECC %sabled, Data cache %s\n", - ecc_mask ? "en" : "dis", policy); + ecc_mask ? "en" : "dis", cp->policy); } /* diff -Nru a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c --- a/arch/arm26/kernel/irq.c Thu Jan 8 23:00:24 2004 +++ b/arch/arm26/kernel/irq.c Thu Jan 8 23:00:24 2004 @@ -135,10 +135,10 @@ int show_interrupts(struct seq_file *p, void *v) { - int i; + int i = *(loff_t *) v; struct irqaction * action; - for (i = 0 ; i < NR_IRQS ; i++) { + if (i < NR_IRQS) { action = irq_desc[i].action; if (!action) continue; @@ -148,10 +148,10 @@ seq_printf(p, ", %s", action->name); } seq_putc(p, '\n'); + } else if (i == NR_IRQS) { + show_fiq_list(p, v); + seq_printf(p, "Err: %10lu\n", irq_err_count); } - - show_fiq_list(p, v); - seq_printf(p, "Err: %10lu\n", irq_err_count); return 0; } diff -Nru a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c --- a/arch/cris/kernel/irq.c Thu Jan 8 23:00:24 2004 +++ b/arch/cris/kernel/irq.c Thu Jan 8 23:00:24 2004 @@ -89,11 +89,11 @@ int show_interrupts(struct seq_file *p, void *v) { - int i; + int i = *(loff_t *) v; struct irqaction * action; unsigned long flags; - for (i = 0; i < NR_IRQS; i++) { + if (i < NR_IRQS) { local_irq_save(flags); action = irq_action[i]; if (!action) diff -Nru a/arch/h8300/Kconfig b/arch/h8300/Kconfig --- a/arch/h8300/Kconfig Thu Jan 8 23:00:24 2004 +++ b/arch/h8300/Kconfig Thu Jan 8 23:00:24 2004 @@ -5,6 +5,10 @@ mainmenu "uClinux/h8300 (w/o MMU) Kernel Configuration" +config H8300 + bool + default y + config MMU bool default n diff -Nru a/arch/h8300/Makefile b/arch/h8300/Makefile --- a/arch/h8300/Makefile Thu Jan 8 23:00:23 2004 +++ b/arch/h8300/Makefile Thu Jan 8 23:00:23 2004 @@ -34,7 +34,7 @@ ldflags-$(CONFIG_CPU_H8S) := -mh8300self CFLAGS += $(cflags-y) -CFLAGS += -mint32 -fno-builtin -Os +CFLAGS += -mint32 -fno-builtin CFLAGS += -g CFLAGS += -D__linux__ CFLAGS += -DUTS_SYSNAME=\"uClinux\" diff -Nru a/arch/h8300/platform/h8300h/ints.c b/arch/h8300/platform/h8300h/ints.c --- a/arch/h8300/platform/h8300h/ints.c Thu Jan 8 23:00:23 2004 +++ b/arch/h8300/platform/h8300h/ints.c Thu Jan 8 23:00:23 2004 @@ -228,9 +228,9 @@ int show_interrupts(struct seq_file *p, void *v) { - int i; + int i = *(loff_t *) v; - for (i = 0; i < NR_IRQS; i++) { + if (i < NR_IRQS) { if (irq_list[i]) { seq_printf(p, "%3d: %10u ",i,irq_list[i]->count); seq_printf(p, "%s\n", irq_list[i]->devname); diff -Nru a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c --- a/arch/h8300/platform/h8s/ints.c Thu Jan 8 23:00:23 2004 +++ b/arch/h8300/platform/h8s/ints.c Thu Jan 8 23:00:23 2004 @@ -280,9 +280,9 @@ int show_interrupts(struct seq_file *p, void *v) { - int i; + int i = *(loff_t *) v; - for (i = 0; i < NR_IRQS; i++) { + if (i < NR_IRQS) { if (irq_list[i]) { seq_printf(p, "%3d: %10u ",i,irq_list[i]->count); seq_printf(p, "%s\n", irq_list[i]->devname); diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Thu Jan 8 23:00:23 2004 +++ b/arch/i386/Kconfig Thu Jan 8 23:00:23 2004 @@ -115,10 +115,15 @@ default y depends on NUMA && (X86_SUMMIT || X86_GENERICARCH) +config X86_SUMMIT_NUMA + bool + default y + depends on NUMA && (X86_SUMMIT || X86_GENERICARCH) + config X86_CYCLONE_TIMER - bool - default y - depends on X86_SUMMIT || X86_GENERICARCH + bool + default y + depends on X86_SUMMIT || X86_GENERICARCH config ES7000_CLUSTERED_APIC bool @@ -784,6 +789,25 @@ See for more information. +config EFI + bool "Boot from EFI support (EXPERIMENTAL)" + depends on ACPI + default n + ---help--- + + This enables the the kernel to boot on EFI platforms using + system configuration information passed to it from the firmware. + This also enables the kernel to use any EFI runtime services that are + available (such as the EFI variable services). + + This option is only useful on systems that have EFI firmware + and will result in a kernel image that is ~8k larger. In addition, + you must use the latest ELILO loader available at + ftp.hpl.hp.com/pub/linux-ia64/ in order to take advantage of kernel + initialization using EFI information (neither GRUB nor LILO know + anything about EFI). However, even with this option, the resultant + kernel should continue to boot on existing non-EFI platforms. + config HAVE_DEC_LOCK bool depends on (SMP || PREEMPT) && X86_CMPXCHG @@ -793,7 +817,7 @@ # Summit needs it only when NUMA is on config BOOT_IOREMAP bool - depends on ((X86_SUMMIT || X86_GENERICARCH) && NUMA) + depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI)) default y endmenu @@ -1029,6 +1053,25 @@ bool depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS) default y + +config PCI_USE_VECTOR + bool "Vector-based interrupt indexing" + depends on X86_LOCAL_APIC && X86_IO_APIC + default n + help + This replaces the current existing IRQ-based index interrupt scheme + with the vector-base index scheme. The advantages of vector base + over IRQ base are listed below: + 1) Support MSI implementation. + 2) Support future IOxAPIC hotplug + + Note that this enables MSI, Message Signaled Interrupt, on all + MSI capable device functions detected if users also install the + MSI patch. Message Signal Interrupt enables an MSI-capable + hardware device to send an inbound Memory Write on its PCI bus + instead of asserting IRQ signal on device IRQ pin. + + If you don't know what to do here, say N. source "drivers/pci/Kconfig" diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/Makefile Thu Jan 8 23:00:23 2004 @@ -24,12 +24,13 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_X86_NUMAQ) += numaq.o -obj-$(CONFIG_X86_SUMMIT) += summit.o +obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o obj-$(CONFIG_EDD) += edd.o obj-$(CONFIG_MODULES) += module.o obj-y += sysenter.o vsyscall.o obj-$(CONFIG_ACPI_SRAT) += srat.o obj-$(CONFIG_HPET_TIMER) += time_hpet.o +obj-$(CONFIG_EFI) += efi.o efi_stub.o EXTRA_AFLAGS := -traditional diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c Thu Jan 8 23:00:24 2004 +++ b/arch/i386/kernel/acpi/boot.c Thu Jan 8 23:00:24 2004 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -331,6 +332,12 @@ { unsigned long rsdp_phys = 0; + if (efi_enabled) { + if (efi.acpi20) + return __pa(efi.acpi20); + else if (efi.acpi) + return __pa(efi.acpi); + } /* * Scan memory looking for the RSDP signature. First search EBDA (low * memory) paragraphs and then search upper memory (E0000-FFFFF). diff -Nru a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c --- a/arch/i386/kernel/cpu/common.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/cpu/common.c Thu Jan 8 23:00:23 2004 @@ -510,7 +510,7 @@ BUG(); enter_lazy_tlb(&init_mm, current); - load_esp0(t, thread->esp0); + load_esp0(t, thread); set_tss_desc(cpu,t); cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff; load_TR_desc(); diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c --- a/arch/i386/kernel/cpu/cpufreq/acpi.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/cpu/cpufreq/acpi.c Thu Jan 8 23:00:23 2004 @@ -578,8 +578,8 @@ /* detect transition latency */ policy->cpuinfo.transition_latency = 0; for (i=0;istate_count;i++) { - if (perf->states[i].transition_latency > policy->cpuinfo.transition_latency) - policy->cpuinfo.transition_latency = perf->states[i].transition_latency; + if ((perf->states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency) + policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000; } policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cur = perf->states[pr->limit.state.px].core_frequency * 1000; diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c Thu Jan 8 23:00:23 2004 @@ -170,6 +170,9 @@ * between that value multiplied by possible FSBs and cpu_mhz which * was calculated at boot time. Really ugly, but no other way to do this. */ + +#define ROUNDING 0xf + static int _guess (int guess, int maxmult) { int target; @@ -177,15 +180,19 @@ target = ((maxmult/10)*guess); if (maxmult%10 != 0) target += (guess/2); - target &= ~0xf; + target += ROUNDING/2; + target &= ~ROUNDING; return target; } static int guess_fsb(int maxmult) { - int speed = (cpu_khz/1000) & ~0xf; + int speed = (cpu_khz/1000); int i; int speeds[3] = { 66, 100, 133 }; + + speed += ROUNDING/2; + speed &= ~ROUNDING; for (i=0; i<3; i++) { if (_guess(speeds[i],maxmult) == speed) diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c Thu Jan 8 23:00:24 2004 +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c Thu Jan 8 23:00:24 2004 @@ -48,8 +48,7 @@ static int has_N44_O17_errata[NR_CPUS]; -static int stock_freq; - +static unsigned int stock_freq; static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) { @@ -175,6 +174,54 @@ return cpufreq_frequency_table_verify(policy, &p4clockmod_table[0]); } +/* copied from speedstep_lib, made SMP-compatible */ +static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) +{ + u32 msr_lo, msr_hi, mult; + unsigned int fsb = 0; + + if (c->x86 != 0xF) { + printk(KERN_DEBUG PFX "Unknown P4. Please send an e-mail to \n"); + return 0; + } + + rdmsr(0x2c, msr_lo, msr_hi); + + /* printk(KERN_DEBUG PFX "P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); */ + /* decode the FSB: see IA-32 Intel (C) Architecture Software + * Developer's Manual, Volume 3: System Prgramming Guide, + * revision #12 in Table B-1: MSRs in the Pentium 4 and + * Intel Xeon Processors, on page B-4 and B-5. + */ + if (c->x86_model < 2) + fsb = 100 * 1000; + else { + u8 fsb_code = (msr_lo >> 16) & 0x7; + switch (fsb_code) { + case 0: + fsb = 100 * 1000; + break; + case 1: + fsb = 13333 * 10; + break; + case 2: + fsb = 200 * 1000; + break; + } + } + + if (!fsb) { + printk(KERN_DEBUG PFX "couldn't detect FSB speed. Please send an e-mail to \n"); + printk(KERN_DEBUG PFX "P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); + } + + /* Multiplier. */ + mult = msr_lo >> 24; + + return (fsb * mult); +} + + static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) { @@ -192,15 +239,10 @@ has_N44_O17_errata[policy->cpu] = 1; } - /* get frequency */ - if (!stock_freq) { - if (cpu_khz) - stock_freq = cpu_khz; - else { - printk(KERN_INFO PFX "unknown core frequency - please use module parameter 'stock_freq'\n"); - return -EINVAL; - } - } + /* get max frequency */ + stock_freq = cpufreq_p4_get_frequency(c); + if (!stock_freq) + return -EINVAL; /* table init */ for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { @@ -213,7 +255,7 @@ /* cpuinfo and default policy values */ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = 1000; + policy->cpuinfo.transition_latency = 1000000; /* assumed */ policy->cur = stock_freq; return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]); @@ -268,8 +310,6 @@ cpufreq_unregister_driver(&p4clockmod_driver); } - -MODULE_PARM(stock_freq, "i"); MODULE_AUTHOR ("Zwane Mwaikambo "); MODULE_DESCRIPTION ("cpufreq driver for Pentium(TM) 4/Xeon(TM)"); diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c Thu Jan 8 23:00:23 2004 @@ -337,7 +337,8 @@ } } printk (KERN_INFO PFX "No PST tables match this cpuid (0x%x)\n", etuple); - printk ("This is indicative of a broken BIOS. Email davej@redhat.com\n"); + printk (KERN_INFO PFX "This is indicative of a broken BIOS.\n"); + printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml\n"); return -EINVAL; } p++; @@ -386,7 +387,11 @@ minimum_speed, maximum_speed); policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = latency; + + /* latency is in 10 ns (look for SGTC above) for each VID + * and FID transition, so multiply that value with 20 */ + policy->cpuinfo.transition_latency = latency * 20; + policy->cur = maximum_speed; return cpufreq_frequency_table_cpuinfo(policy, powernow_table); diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c Thu Jan 8 23:00:24 2004 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c Thu Jan 8 23:00:24 2004 @@ -687,11 +687,13 @@ if (ppst[j].vid < rvo) { /* vid+rvo >= 0 */ printk(KERN_ERR BFX "0 vid exceeded with pstate %d\n", j); + kfree(ppst); return -ENODEV; } if (ppst[j].vid < maxvid+rvo) { /* vid+rvo >= maxvid */ printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j); + kfree(ppst); return -ENODEV; } } @@ -706,7 +708,7 @@ for (j = 0; j < numps; j++) if ((ppst[j].fid==currfid) && (ppst[j].vid==currvid)) - return (0); + return 0; printk(KERN_ERR BFX "currfid/vid do not match PST, ignoring\n"); return 0; @@ -935,10 +937,7 @@ return -ENODEV; } -#warning pol->policy is in undefined state here - res = find_match(&targ, &min, &max, - pol->policy == CPUFREQ_POLICY_POWERSAVE ? - SEARCH_DOWN : SEARCH_UP, 0, 0); + res = find_match(&targ, &min, &max, SEARCH_DOWN, 0, 0); if (!res) { pol->min = min * 1000; pol->max = max * 1000; @@ -957,9 +956,10 @@ pol->governor = CPUFREQ_DEFAULT_GOVERNOR; - /* Take a crude guess here. */ - pol->cpuinfo.transition_latency = ((rvo + 8) * vstable * VST_UNITS_20US) - + (3 * (1 << irt) * 10); + /* Take a crude guess here. + * That guess was in microseconds, so multply with 1000 */ + pol->cpuinfo.transition_latency = (((rvo + 8) * vstable * VST_UNITS_20US) + + (3 * (1 << irt) * 10)) * 1000; if (query_current_values_with_pending_wait()) return -EIO; diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c Thu Jan 8 23:00:23 2004 @@ -73,6 +73,16 @@ { .frequency = CPUFREQ_TABLE_END } }; +/* Ultra Low Voltage Intel Pentium M processor 1000MHz */ +static struct cpufreq_frequency_table op_1000[] = +{ + OP(600, 844), + OP(800, 972), + OP(900, 988), + OP(1000, 1004), + { .frequency = CPUFREQ_TABLE_END } +}; + /* Low Voltage Intel Pentium M processor 1.10GHz */ static struct cpufreq_frequency_table op_1100[] = { @@ -165,6 +175,7 @@ static const struct cpu_model models[] = { _CPU( 900, " 900"), + CPU(1000), CPU(1100), CPU(1200), CPU(1300), diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c Thu Jan 8 23:00:24 2004 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c Thu Jan 8 23:00:24 2004 @@ -106,14 +106,45 @@ static unsigned int pentium4_get_frequency(void) { - u32 msr_lo, msr_hi; + struct cpuinfo_x86 *c = &boot_cpu_data; + u32 msr_lo, msr_hi, mult; + unsigned int fsb = 0; rdmsr(0x2c, msr_lo, msr_hi); dprintk(KERN_DEBUG "speedstep-lib: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); - msr_lo >>= 24; - return (msr_lo * 100000); + /* decode the FSB: see IA-32 Intel (C) Architecture Software + * Developer's Manual, Volume 3: System Prgramming Guide, + * revision #12 in Table B-1: MSRs in the Pentium 4 and + * Intel Xeon Processors, on page B-4 and B-5. + */ + if (c->x86_model < 2) + fsb = 100 * 1000; + else { + u8 fsb_code = (msr_lo >> 16) & 0x7; + switch (fsb_code) { + case 0: + fsb = 100 * 1000; + break; + case 1: + fsb = 13333 * 10; + break; + case 2: + fsb = 200 * 1000; + break; + } + } + + if (!fsb) + printk(KERN_DEBUG "speedstep-lib: couldn't detect FSB speed. Please send an e-mail to \n"); + + /* Multiplier. */ + mult = msr_lo >> 24; + + dprintk(KERN_DEBUG "speedstep-lib: P4 - FSB %u kHz; Multiplier %u\n", fsb, mult); + + return (fsb * mult); } diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h Thu Jan 8 23:00:23 2004 @@ -15,7 +15,7 @@ #define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001 /* Coppermine core */ #define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002 /* Coppermine core */ #define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */ -#define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M with 100 MHz FSB */ +#define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M */ /* speedstep states -- only two of them */ diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c Thu Jan 8 23:00:23 2004 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "speedstep-lib.h" @@ -51,10 +52,14 @@ #define SET_SPEEDSTEP_STATE 2 #define GET_SPEEDSTEP_FREQS 4 +/* how often shall the SMI call be tried if it failed, e.g. because + * of DMA activity going on? */ +#define SMI_TRIES 5 + /* DEBUG * Define it if you want verbose debug output, e.g. for bug reporting */ -#define SPEEDSTEP_DEBUG +//#define SPEEDSTEP_DEBUG #ifdef SPEEDSTEP_DEBUG #define dprintk(msg...) printk(msg) @@ -85,6 +90,9 @@ /** * speedstep_smi_get_freqs - get SpeedStep preferred & current freq. + * Only available on later SpeedStep-enabled systems, returns false results or + * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing + * shows that the latter occurs if !(ist_info.event & 0xFFFF). * */ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high) @@ -93,6 +101,9 @@ u32 state=0; u32 function = GET_SPEEDSTEP_FREQS; + if (!(ist_info.event & 0xFFFF)) + return -ENODEV; + command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); __asm__ __volatile__("movl $0, %%edi\n" @@ -134,10 +145,11 @@ */ static void speedstep_set_state (unsigned int state, unsigned int notify) { - unsigned int old_state, result, command, new_state; + unsigned int old_state, result = 0, command, new_state; unsigned long flags; struct cpufreq_freqs freqs; unsigned int function=SET_SPEEDSTEP_STATE; + unsigned int retry = 0; if (state > 0x1) return; @@ -157,20 +169,28 @@ local_irq_save(flags); command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); - __asm__ __volatile__( - "movl $0, %%edi\n" - "out %%al, (%%dx)\n" - : "=b" (new_state), "=D" (result) - : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0) - ); + + do { + if (retry) { + dprintk(KERN_INFO "cpufreq: retry %u, previous result %u\n", retry, result); + mdelay(retry * 50); + } + retry++; + __asm__ __volatile__( + "movl $0, %%edi\n" + "out %%al, (%%dx)\n" + : "=b" (new_state), "=D" (result) + : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0) + ); + } while ((new_state != state) && (retry <= SMI_TRIES)); /* enable IRQs */ local_irq_restore(flags); if (new_state == state) { - dprintk(KERN_INFO "cpufreq: change to %u MHz succeded\n", (freqs.new / 1000)); + dprintk(KERN_INFO "cpufreq: change to %u MHz succeeded after %u tries with result %u\n", (freqs.new / 1000), retry, result); } else { - printk(KERN_ERR "cpufreq: change failed\n"); + printk(KERN_ERR "cpufreq: change failed with new_state %u and result %u\n", new_state, result); } if (notify) @@ -225,9 +245,10 @@ return -ENODEV; result = speedstep_smi_ownership(); - - if (result) + if (result) { dprintk(KERN_INFO "cpufreq: fails an aquiring ownership of a SMI interface.\n"); + return -EINVAL; + } /* detect low and high frequency */ result = speedstep_smi_get_freqs(&speedstep_freqs[SPEEDSTEP_LOW].frequency, @@ -286,6 +307,7 @@ .target = speedstep_target, .init = speedstep_cpu_init, .resume = speedstep_resume, + .owner = THIS_MODULE, }; /** diff -Nru a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/efi.c Thu Jan 8 23:00:24 2004 @@ -0,0 +1,645 @@ +/* + * Extensible Firmware Interface + * + * Based on Extensible Firmware Interface Specification version 1.0 + * + * Copyright (C) 1999 VA Linux Systems + * Copyright (C) 1999 Walt Drummond + * Copyright (C) 1999-2002 Hewlett-Packard Co. + * David Mosberger-Tang + * Stephane Eranian + * + * All EFI Runtime Services are not implemented yet as EFI only + * supports physical mode addressing on SoftSDV. This is to be fixed + * in a future version. --drummond 1999-07-20 + * + * Implemented EFI runtime services and virtual mode calls. --davidm + * + * Goutham Rao: + * Skip non-WB memory and ignore empty memory ranges. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EFI_DEBUG 0 +#define PFX "EFI: " + +extern efi_status_t asmlinkage efi_call_phys(void *, ...); + +struct efi efi; +struct efi efi_phys __initdata; +struct efi_memory_map memmap __initdata; + +/* + * We require an early boot_ioremap mapping mechanism initially + */ +extern void * boot_ioremap(unsigned long, unsigned long); + +/* + * efi_dir is allocated here, but the directory isn't created + * here, as proc_mkdir() doesn't work this early in the bootup + * process. Therefore, each module, like efivars, must test for + * if (!efi_dir) efi_dir = proc_mkdir("efi", NULL); + * prior to creating their own entries under /proc/efi. + */ +#ifdef CONFIG_PROC_FS +struct proc_dir_entry *efi_dir; +#endif + + +/* + * To make EFI call EFI runtime service in physical addressing mode we need + * prelog/epilog before/after the invocation to disable interrupt, to + * claim EFI runtime service handler exclusively and to duplicate a memory in + * low memory space say 0 - 3G. + */ + +static unsigned long efi_rt_eflags; +static spinlock_t efi_rt_lock = SPIN_LOCK_UNLOCKED; +static pgd_t efi_bak_pg_dir_pointer[2]; + +static void efi_call_phys_prelog(void) +{ + unsigned long cr4; + unsigned long temp; + + spin_lock(&efi_rt_lock); + local_irq_save(efi_rt_eflags); + + /* + * If I don't have PSE, I should just duplicate two entries in page + * directory. If I have PSE, I just need to duplicate one entry in + * page directory. + */ + __asm__ __volatile__("movl %%cr4, %0":"=r"(cr4)); + + if (cr4 & X86_CR4_PSE) { + efi_bak_pg_dir_pointer[0].pgd = + swapper_pg_dir[pgd_index(0)].pgd; + swapper_pg_dir[0].pgd = + swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; + } else { + efi_bak_pg_dir_pointer[0].pgd = + swapper_pg_dir[pgd_index(0)].pgd; + efi_bak_pg_dir_pointer[1].pgd = + swapper_pg_dir[pgd_index(0x400000)].pgd; + swapper_pg_dir[pgd_index(0)].pgd = + swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; + temp = PAGE_OFFSET + 0x400000; + swapper_pg_dir[pgd_index(0x400000)].pgd = + swapper_pg_dir[pgd_index(temp)].pgd; + } + + /* + * After the lock is released, the original page table is restored. + */ + local_flush_tlb(); + + cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address); + __asm__ __volatile__("lgdt %0":"=m" + (*(struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]))); +} + +static void efi_call_phys_epilog(void) +{ + unsigned long cr4; + + cpu_gdt_descr[0].address = + (unsigned long) __va(cpu_gdt_descr[0].address); + __asm__ __volatile__("lgdt %0":"=m"(cpu_gdt_descr)); + __asm__ __volatile__("movl %%cr4, %0":"=r"(cr4)); + + if (cr4 & X86_CR4_PSE) { + swapper_pg_dir[pgd_index(0)].pgd = + efi_bak_pg_dir_pointer[0].pgd; + } else { + swapper_pg_dir[pgd_index(0)].pgd = + efi_bak_pg_dir_pointer[0].pgd; + swapper_pg_dir[pgd_index(0x400000)].pgd = + efi_bak_pg_dir_pointer[1].pgd; + } + + /* + * After the lock is released, the original page table is restored. + */ + local_flush_tlb(); + + local_irq_restore(efi_rt_eflags); + spin_unlock(&efi_rt_lock); +} + +static efi_status_t +phys_efi_set_virtual_address_map(unsigned long memory_map_size, + unsigned long descriptor_size, + u32 descriptor_version, + efi_memory_desc_t *virtual_map) +{ + efi_status_t status; + + efi_call_phys_prelog(); + status = efi_call_phys(efi_phys.set_virtual_address_map, + memory_map_size, descriptor_size, + descriptor_version, virtual_map); + efi_call_phys_epilog(); + return status; +} + +efi_status_t +phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) +{ + efi_status_t status; + + efi_call_phys_prelog(); + status = efi_call_phys(efi_phys.get_time, tm, tc); + efi_call_phys_epilog(); + return status; +} + +int inline efi_set_rtc_mmss(unsigned long nowtime) +{ + int real_seconds, real_minutes; + efi_status_t status; + efi_time_t eft; + efi_time_cap_t cap; + + spin_lock(&efi_rt_lock); + status = efi.get_time(&eft, &cap); + spin_unlock(&efi_rt_lock); + if (status != EFI_SUCCESS) + panic("Ooops, efitime: can't read time!\n"); + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + + if (((abs(real_minutes - eft.minute) + 15)/30) & 1) + real_minutes += 30; + real_minutes %= 60; + + eft.minute = real_minutes; + eft.second = real_seconds; + + if (status != EFI_SUCCESS) { + printk("Ooops: efitime: can't read time!\n"); + return -1; + } + return 0; +} +/* + * This should only be used during kernel init and before runtime + * services have been remapped, therefore, we'll need to call in physical + * mode. Note, this call isn't used later, so mark it __init. + */ +unsigned long inline __init efi_get_time(void) +{ + efi_status_t status; + efi_time_t eft; + efi_time_cap_t cap; + + status = phys_efi_get_time(&eft, &cap); + if (status != EFI_SUCCESS) + printk("Oops: efitime: can't read time status: 0x%lx\n",status); + + return mktime(eft.year, eft.month, eft.day, eft.hour, + eft.minute, eft.second); +} + +int is_available_memory(efi_memory_desc_t * md) +{ + if (!(md->attribute & EFI_MEMORY_WB)) + return 0; + + switch (md->type) { + case EFI_LOADER_CODE: + case EFI_LOADER_DATA: + case EFI_BOOT_SERVICES_CODE: + case EFI_BOOT_SERVICES_DATA: + case EFI_CONVENTIONAL_MEMORY: + return 1; + } + return 0; +} + +/* + * We need to map the EFI memory map again after paging_init(). + */ +void __init efi_map_memmap(void) +{ + memmap.map = NULL; + + memmap.map = (efi_memory_desc_t *) + bt_ioremap((unsigned long) memmap.phys_map, + (memmap.nr_map * sizeof(efi_memory_desc_t))); + + if (memmap.map == NULL) + printk(KERN_ERR PFX "Could not remap the EFI memmap!\n"); +} + +void __init print_efi_memmap(void) +{ + efi_memory_desc_t *md; + int i; + + for (i = 0; i < memmap.nr_map; i++) { + md = &memmap.map[i]; + printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, " + "range=[0x%016llx-0x%016llx) (%lluMB)\n", + i, md->type, md->attribute, md->phys_addr, + md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), + (md->num_pages >> (20 - EFI_PAGE_SHIFT))); + } +} + +/* + * Walks the EFI memory map and calls CALLBACK once for each EFI + * memory descriptor that has memory that is available for kernel use. + */ +void efi_memmap_walk(efi_freemem_callback_t callback, void *arg) +{ + int prev_valid = 0; + struct range { + unsigned long start; + unsigned long end; + } prev, curr; + efi_memory_desc_t *md; + unsigned long start, end; + int i; + + for (i = 0; i < memmap.nr_map; i++) { + md = &memmap.map[i]; + + if ((md->num_pages == 0) || (!is_available_memory(md))) + continue; + + curr.start = md->phys_addr; + curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT); + + if (!prev_valid) { + prev = curr; + prev_valid = 1; + } else { + if (curr.start < prev.start) + printk(KERN_INFO PFX "Unordered memory map\n"); + if (prev.end == curr.start) + prev.end = curr.end; + else { + start = + (unsigned long) (PAGE_ALIGN(prev.start)); + end = (unsigned long) (prev.end & PAGE_MASK); + if ((end > start) + && (*callback) (start, end, arg) < 0) + return; + prev = curr; + } + } + } + if (prev_valid) { + start = (unsigned long) PAGE_ALIGN(prev.start); + end = (unsigned long) (prev.end & PAGE_MASK); + if (end > start) + (*callback) (start, end, arg); + } +} + +void __init efi_init(void) +{ + efi_config_table_t *config_tables; + efi_runtime_services_t *runtime; + efi_char16_t *c16; + char vendor[100] = "unknown"; + unsigned long num_config_tables; + int i = 0; + + memset(&efi, 0, sizeof(efi) ); + memset(&efi_phys, 0, sizeof(efi_phys)); + + efi_phys.systab = EFI_SYSTAB; + memmap.phys_map = EFI_MEMMAP; + memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE; + memmap.desc_version = EFI_MEMDESC_VERSION; + + efi.systab = (efi_system_table_t *) + boot_ioremap((unsigned long) efi_phys.systab, + sizeof(efi_system_table_t)); + /* + * Verify the EFI Table + */ + if (efi.systab == NULL) + printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n"); + if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) + printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n"); + if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0) + printk(KERN_ERR PFX + "Warning: EFI system table major version mismatch: " + "got %d.%02d, expected %d.%02d\n", + efi.systab->hdr.revision >> 16, + efi.systab->hdr.revision & 0xffff, + EFI_SYSTEM_TABLE_REVISION >> 16, + EFI_SYSTEM_TABLE_REVISION & 0xffff); + /* + * Grab some details from the system table + */ + num_config_tables = efi.systab->nr_tables; + config_tables = (efi_config_table_t *)efi.systab->tables; + runtime = efi.systab->runtime; + + /* + * Show what we know for posterity + */ + c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2); + if (c16) { + for (i = 0; i < sizeof(vendor) && *c16; ++i) + vendor[i] = *c16++; + vendor[i] = '\0'; + } else + printk(KERN_ERR PFX "Could not map the firmware vendor!\n"); + + printk(KERN_INFO PFX "EFI v%u.%.02u by %s \n", + efi.systab->hdr.revision >> 16, + efi.systab->hdr.revision & 0xffff, vendor); + + /* + * Let's see what config tables the firmware passed to us. + */ + config_tables = (efi_config_table_t *) + boot_ioremap((unsigned long) config_tables, + num_config_tables * sizeof(efi_config_table_t)); + + if (config_tables == NULL) + printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n"); + + for (i = 0; i < num_config_tables; i++) { + if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { + efi.mps = (void *)config_tables[i].table; + printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table); + } else + if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { + efi.acpi20 = __va(config_tables[i].table); + printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table); + } else + if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { + efi.acpi = __va(config_tables[i].table); + printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table); + } else + if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { + efi.smbios = (void *) config_tables[i].table; + printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table); + } else + if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { + efi.hcdp = (void *)config_tables[i].table; + printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table); + } else + if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) { + efi.uga = (void *)config_tables[i].table; + printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table); + } + } + printk("\n"); + + /* + * Check out the runtime services table. We need to map + * the runtime services table so that we can grab the physical + * address of several of the EFI runtime functions, needed to + * set the firmware into virtual mode. + */ + + runtime = (efi_runtime_services_t *) boot_ioremap((unsigned long) + runtime, + sizeof(efi_runtime_services_t)); + if (runtime != NULL) { + /* + * We will only need *early* access to the following + * two EFI runtime services before set_virtual_address_map + * is invoked. + */ + efi_phys.get_time = (efi_get_time_t *) runtime->get_time; + efi_phys.set_virtual_address_map = + (efi_set_virtual_address_map_t *) + runtime->set_virtual_address_map; + } else + printk(KERN_ERR PFX "Could not map the runtime service table!\n"); + + /* Map the EFI memory map for use until paging_init() */ + + memmap.map = (efi_memory_desc_t *) + boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE); + + if (memmap.map == NULL) + printk(KERN_ERR PFX "Could not map the EFI memory map!\n"); + + if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) { + printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc doesn't " + "match the one from EFI!\n"); + } +#if EFI_DEBUG + print_efi_memmap(); +#endif +} + +/* + * This function will switch the EFI runtime services to virtual mode. + * Essentially, look through the EFI memmap and map every region that + * has the runtime attribute bit set in its memory descriptor and update + * that memory descriptor with the virtual address obtained from ioremap(). + * This enables the runtime services to be called without having to + * thunk back into physical mode for every invocation. + */ + +void __init efi_enter_virtual_mode(void) +{ + efi_memory_desc_t *md; + efi_status_t status; + int i; + + efi.systab = NULL; + + for (i = 0; i < memmap.nr_map; i++) { + md = &memmap.map[i]; + + if (md->attribute & EFI_MEMORY_RUNTIME) { + md->virt_addr = + (unsigned long)ioremap(md->phys_addr, + md->num_pages << EFI_PAGE_SHIFT); + if (!(unsigned long)md->virt_addr) { + printk(KERN_ERR PFX "ioremap of 0x%lX failed\n", + (unsigned long)md->phys_addr); + } + + if (((unsigned long)md->phys_addr <= + (unsigned long)efi_phys.systab) && + ((unsigned long)efi_phys.systab < + md->phys_addr + + ((unsigned long)md->num_pages << + EFI_PAGE_SHIFT))) { + unsigned long addr; + + addr = md->virt_addr - md->phys_addr + + (unsigned long)efi_phys.systab; + efi.systab = (efi_system_table_t *)addr; + } + } + } + + if (!efi.systab) + BUG(); + + status = phys_efi_set_virtual_address_map( + sizeof(efi_memory_desc_t) * memmap.nr_map, + sizeof(efi_memory_desc_t), + memmap.desc_version, + memmap.phys_map); + + if (status != EFI_SUCCESS) { + printk (KERN_ALERT "You are screwed! " + "Unable to switch EFI into virtual mode " + "(status=%lx)\n", status); + panic("EFI call to SetVirtualAddressMap() failed!"); + } + + /* + * Now that EFI is in virtual mode, update the function + * pointers in the runtime service table to the new virtual addresses. + */ + + efi.get_time = (efi_get_time_t *) efi.systab->runtime->get_time; + efi.set_time = (efi_set_time_t *) efi.systab->runtime->set_time; + efi.get_wakeup_time = (efi_get_wakeup_time_t *) + efi.systab->runtime->get_wakeup_time; + efi.set_wakeup_time = (efi_set_wakeup_time_t *) + efi.systab->runtime->set_wakeup_time; + efi.get_variable = (efi_get_variable_t *) + efi.systab->runtime->get_variable; + efi.get_next_variable = (efi_get_next_variable_t *) + efi.systab->runtime->get_next_variable; + efi.set_variable = (efi_set_variable_t *) + efi.systab->runtime->set_variable; + efi.get_next_high_mono_count = (efi_get_next_high_mono_count_t *) + efi.systab->runtime->get_next_high_mono_count; + efi.reset_system = (efi_reset_system_t *) + efi.systab->runtime->reset_system; +} + +void __init +efi_initialize_iomem_resources(struct resource *code_resource, + struct resource *data_resource) +{ + struct resource *res; + efi_memory_desc_t *md; + int i; + + for (i = 0; i < memmap.nr_map; i++) { + md = &memmap.map[i]; + + if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > + 0x100000000ULL) + continue; + res = alloc_bootmem_low(sizeof(struct resource)); + switch (md->type) { + case EFI_RESERVED_TYPE: + res->name = "Reserved Memory"; + break; + case EFI_LOADER_CODE: + res->name = "Loader Code"; + break; + case EFI_LOADER_DATA: + res->name = "Loader Data"; + break; + case EFI_BOOT_SERVICES_DATA: + res->name = "BootServices Data"; + break; + case EFI_BOOT_SERVICES_CODE: + res->name = "BootServices Code"; + break; + case EFI_RUNTIME_SERVICES_CODE: + res->name = "Runtime Service Code"; + break; + case EFI_RUNTIME_SERVICES_DATA: + res->name = "Runtime Service Data"; + break; + case EFI_CONVENTIONAL_MEMORY: + res->name = "Conventional Memory"; + break; + case EFI_UNUSABLE_MEMORY: + res->name = "Unusable Memory"; + break; + case EFI_ACPI_RECLAIM_MEMORY: + res->name = "ACPI Reclaim"; + break; + case EFI_ACPI_MEMORY_NVS: + res->name = "ACPI NVS"; + break; + case EFI_MEMORY_MAPPED_IO: + res->name = "Memory Mapped IO"; + break; + case EFI_MEMORY_MAPPED_IO_PORT_SPACE: + res->name = "Memory Mapped IO Port Space"; + break; + default: + res->name = "Reserved"; + break; + } + res->start = md->phys_addr; + res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1); + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (request_resource(&iomem_resource, res) < 0) + printk(KERN_ERR PFX "Failed to allocate res %s : 0x%lx-0x%lx\n", + res->name, res->start, res->end); + /* + * We don't know which region contains kernel data so we try + * it repeatedly and let the resource manager test it. + */ + if (md->type == EFI_CONVENTIONAL_MEMORY) { + request_resource(res, code_resource); + request_resource(res, data_resource); + } + } +} + +/* + * Convenience functions to obtain memory types and attributes + */ + +u32 efi_mem_type(unsigned long phys_addr) +{ + efi_memory_desc_t *md; + int i; + + for (i = 0; i < memmap.nr_map; i++) { + md = &memmap.map[i]; + if ((md->phys_addr <= phys_addr) && (phys_addr < + (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) + return md->type; + } + return 0; +} + +u64 efi_mem_attributes(unsigned long phys_addr) +{ + efi_memory_desc_t *md; + int i; + + for (i = 0; i < memmap.nr_map; i++) { + md = &memmap.map[i]; + if ((md->phys_addr <= phys_addr) && (phys_addr < + (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) + return md->attribute; + } + return 0; +} diff -Nru a/arch/i386/kernel/efi_stub.S b/arch/i386/kernel/efi_stub.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/efi_stub.S Thu Jan 8 23:00:24 2004 @@ -0,0 +1,124 @@ +/* + * EFI call stub for IA32. + * + * This stub allows us to make EFI calls in physical mode with interrupts + * turned off. + */ + +#include +#include +#include +#include + +/* + * efi_call_phys(void *, ...) is a function with variable parameters. + * All the callers of this function assure that all the parameters are 4-bytes. + */ + +/* + * In gcc calling convention, EBX, ESP, EBP, ESI and EDI are all callee save. + * So we'd better save all of them at the beginning of this function and restore + * at the end no matter how many we use, because we can not assure EFI runtime + * service functions will comply with gcc calling convention, too. + */ + +.text +ENTRY(efi_call_phys) + /* + * 0. The function can only be called in Linux kernel. So CS has been + * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found + * the values of these registers are the same. And, the corresponding + * GDT entries are identical. So I will do nothing about segment reg + * and GDT, but change GDT base register in prelog and epilog. + */ + + /* + * 1. Now I am running with EIP = + PAGE_OFFSET. + * But to make it smoothly switch from virtual mode to flat mode. + * The mapping of lower virtual memory has been created in prelog and + * epilog. + */ + movl $1f, %edx + subl $__PAGE_OFFSET, %edx + jmp *%edx +1: + + /* + * 2. Now on the top of stack is the return + * address in the caller of efi_call_phys(), then parameter 1, + * parameter 2, ..., param n. To make things easy, we save the return + * address of efi_call_phys in a global variable. + */ + popl %edx + movl %edx, saved_return_addr + /* get the function pointer into ECX*/ + popl %ecx + movl %ecx, efi_rt_function_ptr + movl $2f, %edx + subl $__PAGE_OFFSET, %edx + pushl %edx + + /* + * 3. Clear PG bit in %CR0. + */ + movl %cr0, %edx + andl $0x7fffffff, %edx + movl %edx, %cr0 + jmp 1f +1: + + /* + * 4. Adjust stack pointer. + */ + subl $__PAGE_OFFSET, %esp + + /* + * 5. Call the physical function. + */ + jmp *%ecx + +2: + /* + * 6. After EFI runtime service returns, control will return to + * following instruction. We'd better readjust stack pointer first. + */ + addl $__PAGE_OFFSET, %esp + + /* + * 7. Restore PG bit + */ + movl %cr0, %edx + orl $0x80000000, %edx + movl %edx, %cr0 + jmp 1f +1: + /* + * 8. Now restore the virtual mode from flat mode by + * adding EIP with PAGE_OFFSET. + */ + movl $1f, %edx + jmp *%edx +1: + + /* + * 9. Balance the stack. And because EAX contain the return value, + * we'd better not clobber it. + */ + leal efi_rt_function_ptr, %edx + movl (%edx), %ecx + pushl %ecx + + /* + * 10. Push the saved return address onto the stack and return. + */ + leal saved_return_addr, %edx + movl (%edx), %ecx + pushl %ecx + ret +.previous + +.data +saved_return_addr: + .long 0 +efi_rt_function_ptr: + .long 0 diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c --- a/arch/i386/kernel/i8259.c Thu Jan 8 23:00:24 2004 +++ b/arch/i386/kernel/i8259.c Thu Jan 8 23:00:24 2004 @@ -419,8 +419,10 @@ * us. (some of these will be overridden and become * 'special' SMP interrupts) */ - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) { int vector = FIRST_EXTERNAL_VECTOR + i; + if (i >= NR_IRQS) + break; if (vector != SYSCALL_VECTOR) set_intr_gate(vector, interrupt[i]); } diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/io_apic.c Thu Jan 8 23:00:23 2004 @@ -76,6 +76,14 @@ int apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +#ifdef CONFIG_PCI_USE_VECTOR +int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; +#define vector_to_irq(vector) \ + (platform_legacy_irq(vector) ? vector : vector_irq[vector]) +#else +#define vector_to_irq(vector) (vector) +#endif + /* * The common case is 1:1 IRQ<->pin mappings. Sometimes there are * shared ISA-space IRQs, so we have to support them. We are super @@ -249,7 +257,7 @@ clear_IO_APIC_pin(apic, pin); } -static void set_ioapic_affinity(unsigned int irq, cpumask_t cpumask) +static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) { unsigned long flags; int pin; @@ -288,7 +296,7 @@ extern cpumask_t irq_affinity[NR_IRQS]; -static cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS]; +cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS]; #define IRQBALANCE_CHECK_ARCH -999 static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; @@ -670,13 +678,11 @@ __setup("noirqbalance", irqbalance_disable); -static void set_ioapic_affinity(unsigned int irq, cpumask_t mask); - static inline void move_irq(int irq) { /* note - we hold the desc->lock */ if (unlikely(!cpus_empty(pending_irq_balance_cpumask[irq]))) { - set_ioapic_affinity(irq, pending_irq_balance_cpumask[irq]); + set_ioapic_affinity_irq(irq, pending_irq_balance_cpumask[irq]); cpus_clear(pending_irq_balance_cpumask[irq]); } } @@ -853,7 +859,7 @@ if (irq_entry == -1) continue; irq = pin_2_irq(irq_entry, ioapic, pin); - set_ioapic_affinity(irq, mask); + set_ioapic_affinity_irq(irq, mask); } } @@ -1141,7 +1147,8 @@ /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; -static int __init assign_irq_vector(int irq) +#ifndef CONFIG_PCI_USE_VECTOR +int __init assign_irq_vector(int irq) { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; BUG_ON(irq >= NR_IRQ_VECTORS); @@ -1158,11 +1165,36 @@ } IO_APIC_VECTOR(irq) = current_vector; + return current_vector; } +#endif -static struct hw_interrupt_type ioapic_level_irq_type; -static struct hw_interrupt_type ioapic_edge_irq_type; +static struct hw_interrupt_type ioapic_level_type; +static struct hw_interrupt_type ioapic_edge_type; + +#define IOAPIC_AUTO -1 +#define IOAPIC_EDGE 0 +#define IOAPIC_LEVEL 1 + +static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) +{ + if (use_pci_vector() && !platform_legacy_irq(irq)) { + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[vector].handler = &ioapic_level_type; + else + irq_desc[vector].handler = &ioapic_edge_type; + set_intr_gate(vector, interrupt[vector]); + } else { + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[irq].handler = &ioapic_level_type; + else + irq_desc[irq].handler = &ioapic_edge_type; + set_intr_gate(vector, interrupt[irq]); + } +} void __init setup_IO_APIC_irqs(void) { @@ -1220,13 +1252,7 @@ if (IO_APIC_IRQ(irq)) { vector = assign_irq_vector(irq); entry.vector = vector; - - if (IO_APIC_irq_trigger(irq)) - irq_desc[irq].handler = &ioapic_level_irq_type; - else - irq_desc[irq].handler = &ioapic_edge_irq_type; - - set_intr_gate(vector, interrupt[irq]); + ioapic_register_intr(irq, vector, IOAPIC_AUTO); if (!apic && (irq < 16)) disable_8259A_irq(irq); @@ -1273,7 +1299,7 @@ * The timer IRQ doesn't have to know that behind the * scene we have a 8259A-master in AEOI mode ... */ - irq_desc[0].handler = &ioapic_edge_irq_type; + irq_desc[0].handler = &ioapic_edge_type; /* * Add it to the IO-APIC irq-routing table: @@ -1763,9 +1789,6 @@ * that was delayed but this is now handled in the device * independent code. */ -#define enable_edge_ioapic_irq unmask_IO_APIC_irq - -static void disable_edge_ioapic_irq (unsigned int irq) { /* nothing */ } /* * Starting up a edge-triggered IO-APIC interrupt is @@ -1776,7 +1799,6 @@ * This is not complete - we should be able to fake * an edge even if it isn't on the 8259A... */ - static unsigned int startup_edge_ioapic_irq(unsigned int irq) { int was_pending = 0; @@ -1794,8 +1816,6 @@ return was_pending; } -#define shutdown_edge_ioapic_irq disable_edge_ioapic_irq - /* * Once we have recorded IRQ_PENDING already, we can mask the * interrupt for real. This prevents IRQ storms from unhandled @@ -1810,9 +1830,6 @@ ack_APIC_irq(); } -static void end_edge_ioapic_irq (unsigned int i) { /* nothing */ } - - /* * Level triggered interrupts can just be masked, * and shutting down and starting up the interrupt @@ -1834,10 +1851,6 @@ return 0; /* don't check for pending */ } -#define shutdown_level_ioapic_irq mask_IO_APIC_irq -#define enable_level_ioapic_irq unmask_IO_APIC_irq -#define disable_level_ioapic_irq mask_IO_APIC_irq - static void end_level_ioapic_irq (unsigned int irq) { unsigned long v; @@ -1864,6 +1877,7 @@ * The idea is from Manfred Spraul. --macro */ i = IO_APIC_VECTOR(irq); + v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); ack_APIC_irq(); @@ -1898,7 +1912,57 @@ } } -static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ } +#ifdef CONFIG_PCI_USE_VECTOR +static unsigned int startup_edge_ioapic_vector(unsigned int vector) +{ + int irq = vector_to_irq(vector); + + return startup_edge_ioapic_irq(irq); +} + +static void ack_edge_ioapic_vector(unsigned int vector) +{ + int irq = vector_to_irq(vector); + + ack_edge_ioapic_irq(irq); +} + +static unsigned int startup_level_ioapic_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + return startup_level_ioapic_irq (irq); +} + +static void end_level_ioapic_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + end_level_ioapic_irq(irq); +} + +static void mask_IO_APIC_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + mask_IO_APIC_irq(irq); +} + +static void unmask_IO_APIC_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + unmask_IO_APIC_irq(irq); +} + +static void set_ioapic_affinity_vector (unsigned int vector, + cpumask_t cpu_mask) +{ + int irq = vector_to_irq(vector); + + set_ioapic_affinity_irq(irq, cpu_mask); +} +#endif /* * Level and edge triggered IO-APIC interrupts need different handling, @@ -1908,26 +1972,25 @@ * edge-triggered handler, without risking IRQ storms and other ugly * races. */ - -static struct hw_interrupt_type ioapic_edge_irq_type = { +static struct hw_interrupt_type ioapic_edge_type = { .typename = "IO-APIC-edge", - .startup = startup_edge_ioapic_irq, - .shutdown = shutdown_edge_ioapic_irq, - .enable = enable_edge_ioapic_irq, - .disable = disable_edge_ioapic_irq, - .ack = ack_edge_ioapic_irq, - .end = end_edge_ioapic_irq, + .startup = startup_edge_ioapic, + .shutdown = shutdown_edge_ioapic, + .enable = enable_edge_ioapic, + .disable = disable_edge_ioapic, + .ack = ack_edge_ioapic, + .end = end_edge_ioapic, .set_affinity = set_ioapic_affinity, }; -static struct hw_interrupt_type ioapic_level_irq_type = { +static struct hw_interrupt_type ioapic_level_type = { .typename = "IO-APIC-level", - .startup = startup_level_ioapic_irq, - .shutdown = shutdown_level_ioapic_irq, - .enable = enable_level_ioapic_irq, - .disable = disable_level_ioapic_irq, - .ack = mask_and_ack_level_ioapic_irq, - .end = end_level_ioapic_irq, + .startup = startup_level_ioapic, + .shutdown = shutdown_level_ioapic, + .enable = enable_level_ioapic, + .disable = disable_level_ioapic, + .ack = mask_and_ack_level_ioapic, + .end = end_level_ioapic, .set_affinity = set_ioapic_affinity, }; @@ -1947,7 +2010,13 @@ * 0x80, because int 0x80 is hm, kind of importantish. ;) */ for (irq = 0; irq < NR_IRQS ; irq++) { - if (IO_APIC_IRQ(irq) && !IO_APIC_VECTOR(irq)) { + int tmp = irq; + if (use_pci_vector()) { + if (!platform_legacy_irq(tmp)) + if ((tmp = vector_to_irq(tmp)) == -1) + continue; + } + if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { /* * Hmm.. We don't have an entry for this, * so default to an old-fashioned 8259 @@ -2379,10 +2448,12 @@ "IRQ %d Mode:%i Active:%i)\n", ioapic, mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low); + if (use_pci_vector() && !platform_legacy_irq(irq)) + irq = IO_APIC_VECTOR(irq); if (edge_level) { - irq_desc[irq].handler = &ioapic_level_irq_type; + irq_desc[irq].handler = &ioapic_level_type; } else { - irq_desc[irq].handler = &ioapic_edge_irq_type; + irq_desc[irq].handler = &ioapic_edge_type; } set_intr_gate(entry.vector, interrupt[irq]); diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c --- a/arch/i386/kernel/irq.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/irq.c Thu Jan 8 23:00:23 2004 @@ -138,17 +138,19 @@ int show_interrupts(struct seq_file *p, void *v) { - int i, j; + int i = *(loff_t *) v, j; struct irqaction * action; unsigned long flags; - seq_printf(p, " "); - for (j=0; j= NR_IRQS) + return 0; + action = irq_desc[irq].action; + if (action) { + if (irqflags & action->flags & SA_SHIRQ) + action = NULL; + } + return !action; +} + /** * request_irq - allocate an interrupt line * @irq: Interrupt line to allocate @@ -898,48 +918,6 @@ static struct proc_dir_entry * root_irq_dir; static struct proc_dir_entry * irq_dir [NR_IRQS]; -#define HEX_DIGITS (2*sizeof(cpumask_t)) - -static unsigned int parse_hex_value(const char __user *buffer, - unsigned long count, cpumask_t *ret) -{ - unsigned char hexnum[HEX_DIGITS]; - cpumask_t value = CPU_MASK_NONE; - int i; - - if (!count) - return -EINVAL; - if (count > HEX_DIGITS) - count = HEX_DIGITS; - if (copy_from_user(hexnum, buffer, count)) - return -EFAULT; - - /* - * Parse the first HEX_DIGITS characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. - */ - - for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; - int k; - - switch (c) { - case '0' ... '9': c -= '0'; break; - case 'a' ... 'f': c -= 'a'-10; break; - case 'A' ... 'F': c -= 'A'-10; break; - default: - goto out; - } - cpus_shift_left(value, value, 4); - for (k = 0; k < 4; ++k) - if (test_bit(k, (unsigned long *)&c)) - cpu_set(k, value); - } -out: - *ret = value; - return 0; -} - #ifdef CONFIG_SMP static struct proc_dir_entry *smp_affinity_entry[NR_IRQS]; @@ -949,20 +927,10 @@ static int irq_affinity_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - int k, len; - cpumask_t tmp = irq_affinity[(long)data]; - - if (count < HEX_DIGITS+1) + int len = cpumask_snprintf(page, count, irq_affinity[(long)data]); + if (count - len < 2) return -EINVAL; - - len = 0; - for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { - int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp)); - len += j; - page += j; - cpus_shift_right(tmp, tmp, 16); - } - len += sprintf(page, "\n"); + len += sprintf(page + len, "\n"); return len; } @@ -975,7 +943,7 @@ if (!irq_desc[irq].handler->set_affinity) return -EIO; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); if (err) return err; @@ -1000,10 +968,11 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long *mask = (unsigned long *) data; - if (count < HEX_DIGITS+1) + int len = cpumask_snprintf(page, count, *(cpumask_t *)data); + if (count - len < 2) return -EINVAL; - return sprintf (page, "%08lx\n", *mask); + len += sprintf(page + len, "\n"); + return len; } static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer, @@ -1013,7 +982,7 @@ unsigned long full_count = count, err; cpumask_t new_value; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); if (err) return err; diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c --- a/arch/i386/kernel/mpparse.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/mpparse.c Thu Jan 8 23:00:23 2004 @@ -1147,15 +1147,19 @@ if ((1<irq = irq; + if (use_pci_vector() && !platform_legacy_irq(irq)) + irq = IO_APIC_VECTOR(irq); + entry->irq = irq; continue; } mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq = irq; - + if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low)) { + if (use_pci_vector() && !platform_legacy_irq(irq)) + irq = IO_APIC_VECTOR(irq); + entry->irq = irq; + } printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", entry->id.segment, entry->id.bus, entry->id.device, ('A' + entry->pin), diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c --- a/arch/i386/kernel/process.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/process.c Thu Jan 8 23:00:23 2004 @@ -507,7 +507,7 @@ /* * Reload esp0, LDT and the page table pointer: */ - load_esp0(tss, next->esp0); + load_esp0(tss, next); /* * Load the per-thread Thread-Local Storage descriptor. diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c --- a/arch/i386/kernel/reboot.c Thu Jan 8 23:00:23 2004 +++ b/arch/i386/kernel/reboot.c Thu Jan 8 23:00:23 2004 @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include "mach_reboot.h" @@ -263,7 +264,12 @@ disable_IO_APIC(); #endif - if(!reboot_thru_bios) { + if (!reboot_thru_bios) { + if (efi_enabled) { + efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, 0); + __asm__ __volatile__("lidt %0": :"m" (no_idt)); + __asm__ __volatile__("int3"); + } /* rebooting needs to touch the page at absolute addr 0 */ *((unsigned short *)__va(0x472)) = reboot_mode; for (;;) { @@ -273,6 +279,8 @@ __asm__ __volatile__("int3"); } } + if (efi_enabled) + efi.reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, 0); machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); } @@ -287,6 +295,8 @@ void machine_power_off(void) { + if (efi_enabled) + efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, 0); if (pm_power_off) pm_power_off(); } diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c Thu Jan 8 23:00:24 2004 +++ b/arch/i386/kernel/setup.c Thu Jan 8 23:00:24 2004 @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include